---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:39:40 06/29/2006 -- Design Name: -- Module Name: flash - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.std_logic_misc.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; Library UNIMACRO; use UNIMACRO.vcomponents.all; entity flash is Port ( clk : in STD_LOGIC; sysclk : in STD_LOGIC; we : in STD_LOGIC; strobe : in STD_LOGIC; w_data : in STD_LOGIC_VECTOR (31 downto 0); addr : in STD_LOGIC_VECTOR (31 downto 0); flash_wdata : out STD_LOGIC_VECTOR (31 downto 0); flash_rdata : out STD_LOGIC_VECTOR (31 downto 0); flash_busy : out STD_LOGIC; MQ : in STD_LOGIC; MD : out STD_LOGIC; MCS : out STD_LOGIC_VECTOR (1 downto 0) ); end flash; architecture Behavioral of flash is constant cmd_addr : std_logic_vector(15 downto 0) := x"0001"; constant buffer_addr : std_logic_vector(15 downto 0) := x"1000"; signal dia : std_logic_vector(0 downto 0) := (others => '0'); signal doa : std_logic_vector(0 downto 0) := (others => '0'); signal addra : std_logic_vector(12 downto 0) := (others => '0'); signal addrap : std_logic_vector(13 downto 0) := (others => '0'); signal wbuf_ra : std_logic_vector(13 downto 0) := (others => '0'); signal wbuf_wa : std_logic_vector(8 downto 0) := (others => '0'); signal rbuf_wa : std_logic_vector(13 downto 0) := (others => '0'); signal rbuf_ra : std_logic_vector(8 downto 0) := (others => '0'); signal byte_cnt : std_logic_vector(8 downto 0) := (others => '0'); signal en_FLASHp : std_logic := '0'; signal en_FLASH : std_logic := '0'; signal en_FLASH_dl : std_logic_vector(1 downto 0) := "00"; signal en_FLASH_q : std_logic_vector(2 downto 0) := "000"; signal cmd : std_logic := '0'; signal rd : std_logic := '0'; signal wea : std_logic_vector(0 downto 0) := (others => '0'); signal web : std_logic_vector(3 downto 0) := (others => '0'); signal strobe_q : std_logic := '0'; signal clk_toggle : std_logic := '0'; signal clk_toggle_q : std_logic := '0'; begin process(sysclk) begin if(sysclk'event and sysclk = '1')then clk_toggle_q <= clk_toggle; if(clk_toggle_q /= clk_toggle and we = '1' and strobe = '1' and addr(15 downto 7) = buffer_addr(15 downto 7))then web <= x"f"; else web <= x"0"; end if; end if; end process; process(clk) begin if(clk'event and clk = '1')then clk_toggle <= not clk_toggle; if(en_FLASHp = '1')then en_FLASH <= '1'; elsif(addra(11 downto 3) = byte_cnt and addra(2 downto 0) = "111")then en_FLASH <= '0'; end if; if(en_FLASH = '0')then addra <= (others => '0'); cmd <= '1'; else addra(11 downto 0) <= addra(11 downto 0) + 1; if(addra(4 downto 0) = "11111")then cmd <= '0'; end if; end if; wea(0) <= en_FLASH_q(2) and en_FLASH_dl(1); en_FLASH_dl <= en_FLASH_dl(0) & en_FLASH; MCS <= en_FLASH_dl; MD <= doa(0); if(en_FLASH_dl(1) = '0')then addrap <= (others => '0'); elsif(wea(0) = '1')then addrap(11 downto 0) <= addrap(11 downto 0) + 1; end if; flash_busy <= en_flash or en_flash_dl(1); if(we = '1' and strobe = '1' and addr(15 downto 0) = buffer_addr)then if(w_data(31 downto 24) = x"0b")then rd <= '1'; else rd <= '0'; end if; end if; -- FLASH signals if(we = '1' and strobe = '1' and addr(15 downto 0) = cmd_addr)then byte_cnt <= w_data(8 downto 0); end if; if(we = '1' and strobe = '1' and addr(15 downto 0) = cmd_addr)then en_FLASHp <= '1'; elsif(en_FLASH = '1')then en_FLASHp <= '0'; end if; strobe_q <= strobe; end if; end process; i_wbuf : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "18Kb", -- Target BRAM, "9Kb" or "18Kb" DEVICE => "SPARTAN6", -- Target Device: "VIRTEX5", "VIRTEX6", "SPARTAN6" DOA_REG => 0, -- Optional port A output register (0 or 1) DOB_REG => 0, -- Optional port B output register (0 or 1) WRITE_WIDTH_A => 1, -- Valid values are 1-36 WRITE_WIDTH_B => 32, -- Valid values are 1-36 READ_WIDTH_A => 1, -- Valid values are 1-36 READ_WIDTH_B => 32) -- Valid values are 1-36 port map ( DOA => doa, -- Output port-A data DOB => flash_wdata, -- Output port-B data ADDRA => wbuf_ra, -- Input port-A address ADDRB => wbuf_wa, -- Input port-B address CLKA => clk, -- Input port-A clock CLKB => sysclk, -- Input port-B clock DIA => (others => '0'), -- Input port-A data DIB => w_data, -- Input port-B data ENA => '1', -- Input port-A enable ENB => '1', -- Input port-B enable REGCEA => '1', -- Input port-A output register enable REGCEB => '1', -- Input port-B output register enable RSTA => '0', -- Input port-A reset RSTB => '0', -- Input port-B reset WEA => "0", -- Input port-A write enable WEB => web -- Input port-B write enable ); --web <= x"f" when we = '1' and strobe = '1' and addr(15 downto 7) = buffer_addr(15 downto 7) else x"0"; wbuf_wa <= "00" & addr(6 downto 0); wbuf_ra(13 downto 5) <= '0' & addra(12 downto 5); wbuf_ra(4 downto 0) <= not addra(4 downto 3) & addra(2 downto 0) when cmd = '0' else not addra(4 downto 0); i_rbuf : BRAM_TDP_MACRO generic map ( BRAM_SIZE => "18Kb", -- Target BRAM, "9Kb" or "18Kb" DEVICE => "SPARTAN6", -- Target Device: "VIRTEX5", "VIRTEX6", "SPARTAN6" DOA_REG => 0, -- Optional port A output register (0 or 1) DOB_REG => 0, -- Optional port B output register (0 or 1) WRITE_WIDTH_A => 1, -- Valid values are 1-36 WRITE_WIDTH_B => 32, -- Valid values are 1-36 READ_WIDTH_A => 1, -- Valid values are 1-36 READ_WIDTH_B => 32) -- Valid values are 1-36 port map ( DOA => open, -- Output port-A data DOB => flash_rdata, -- Output port-B data ADDRA => rbuf_wa, -- Input port-A address ADDRB => rbuf_ra, -- Input port-B address CLKA => clk, -- Input port-A clock CLKB => sysclk, -- Input port-B clock DIA => dia, -- Input port-A data DIB => (others => '0'), -- Input port-B data ENA => '1', -- Input port-A enable ENB => '1', -- Input port-B enable REGCEA => '1', -- Input port-A output register enable REGCEB => '1', -- Input port-B output register enable RSTA => '0', -- Input port-A reset RSTB => '0', -- Input port-B reset WEA => wea, -- Input port-A write enable WEB => x"0" -- Input port-B write enable ); dia(0) <= MQ; rbuf_wa(13 downto 5) <= addrap(13 downto 5); rbuf_wa(4 downto 0) <= not addrap(4 downto 3) & addrap(2 downto 0) when rd = '1' else not addrap(4 downto 0); rbuf_ra <= "00" & addr(6 downto 0); -- need to add 8 more delays for fast read 10/27/2008 i_SRL16a : SRL16E port map ( Q => en_FLASH_q(0), A0 => '1', A1 => '1', A2 => rd, A3 => rd, CE => '1', CLK => clk, D => en_FLASH_dl(0) ); i_SRL16b : SRL16E port map ( Q => en_FLASH_q(1), A0 => '1', A1 => '1', A2 => rd, A3 => rd, CE => '1', CLK => clk, D => en_FLASH_q(0) ); i_SRL16c : SRL16E port map ( Q => en_FLASH_q(2), A0 => '0', A1 => '0', A2 => '0', A3 => rd, CE => '1', CLK => clk, D => en_FLASH_q(1) ); end Behavioral;