library IEEE; use IEEE.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; LIBRARY lpm; USE lpm.lpm_components.all; entity ni2fifo is port ( reset_n : in std_logic; -- asynchronous reset sreset : in std_logic; -- synchronous reset des_clk : in std_logic; -- data clock des_en : in std_logic; -- data valid des_er : in std_logic; -- data error des_data : in std_logic_vector(15 downto 0); -- data -- to pci interface (decoder) naddr : out std_logic_vector(31 downto 0); pci_rd_req : in std_logic; pci_raddr : in std_logic_vector(16 downto 0); pci_rdy : out std_logic; not_empty : out std_logic; ds_en_reg : out std_logic; sram_rdata : out std_logic_vector(31 downto 0); -- to SRAM ce_n : out std_logic; we_n : out std_logic; re_n : out std_logic; sram_q : in std_logic_vector(15 downto 0); clk_sram : out std_logic; addr : out std_logic_vector(17 downto 0); wdata : out std_logic_vector(15 downto 0) ); end ni2fifo; architecture a of ni2fifo is component nififo8m generic (Na : Integer := 11; Nd : Integer := 8); PORT ( data : IN STD_LOGIC_VECTOR (Nd-1 DOWNTO 0); wrreq : IN STD_LOGIC ; rdreq : IN STD_LOGIC ; clk : IN STD_LOGIC ; aclr : IN STD_LOGIC := '0'; q : OUT STD_LOGIC_VECTOR (Nd-1 DOWNTO 0); rdempty : OUT STD_LOGIC ); end component; type sm_type is (idle, fifo_rd1, fifo_rd2, sram_A, sram_Ae, sram_A1, sram_A1e, sram_D, sram_De, sram_D1, sram_D1e, sram_fin); signal sm : sm_type; signal q_l : std_logic_vector( 7 downto 0); signal q_h : std_logic_vector( 7 downto 0); signal clk_sram_i : std_logic; signal sreset120 : std_logic; signal rdreq_fifo : std_logic; signal rdempty : std_logic; signal rdempty_s : std_logic; signal pci_rd_req_s : std_logic; signal wcounter : std_logic_vector(17 downto 0); signal rcounter : std_logic_vector( 5 downto 0); signal cdata : std_logic_vector(15 downto 0); signal sram_qL : std_logic_vector(15 downto 0); signal sram_qH : std_logic_vector(15 downto 0); signal des_en_r : std_logic; signal des_er_r : std_logic; signal des_valid_data : std_logic; signal des_dv1_err1 : std_logic; signal des_dv0_err1 : std_logic; signal des_data_r : std_logic_vector(15 downto 0); signal des_data_rr : std_logic_vector(15 downto 0); signal des_dv1_err1_cnt : std_logic_vector(31 downto 0); signal des_dv0_err1_cnt : std_logic_vector(31 downto 0); signal des_valid_data_cnt : std_logic_vector(31 downto 0); signal en_valid_cnt : std_logic; signal clk : std_logic; -- 120 MHz clock begin clk <= des_clk; process(des_clk) begin if des_clk'event and des_clk='1' then des_en_r <= des_en; des_er_r <= des_er; des_data_r <= des_data; ds_en_reg <= des_en_r; des_valid_data <= des_en_r and not des_er_r; des_dv1_err1 <= des_en_r and des_er_r; des_dv0_err1 <= not des_en_r and des_er_r; des_data_rr <= des_data_r; end if; end process; process(des_clk, sreset120) begin if sreset120='1' then des_dv1_err1_cnt <= (others => '0'); des_dv0_err1_cnt <= (others => '0'); des_valid_data_cnt <= (others => '0'); en_valid_cnt <= '0'; elsif des_clk'event and des_clk='1' then en_valid_cnt <= des_valid_data; if en_valid_cnt='1' and des_valid_data_cnt(des_valid_data_cnt'high)='0' then des_valid_data_cnt <= des_valid_data_cnt + 1; end if; if des_dv1_err1='1' and des_dv1_err1_cnt(des_dv1_err1_cnt'high)='0' then des_dv1_err1_cnt <= des_dv1_err1_cnt + 1; end if; if des_dv0_err1='1' and des_dv0_err1_cnt(des_dv0_err1_cnt'high)='0' then des_dv0_err1_cnt <= des_dv0_err1_cnt + 1; end if; end if; end process; fifo_l: nififo8m PORT map ( data => des_data_rr(7 downto 0), wrreq => des_valid_data, rdreq => rdreq_fifo, clk => clk, q => q_l, aclr => sreset120, rdempty => open ); fifo_h: nififo8m PORT map ( data => des_data_rr(15 downto 8), wrreq => des_valid_data, rdreq => rdreq_fifo, clk => clk, q => q_h, aclr => sreset120, rdempty => rdempty ); process(clk, reset_n) begin if reset_n = '0' then sm <= idle; pci_rdy <= '0'; ce_n <= '1'; we_n <= '1'; re_n <= '1'; clk_sram_i <= '1'; not_empty <= '0'; rdreq_fifo <= '0'; addr <= (others => '0'); elsif clk'event and clk='1' then ce_n <= '1'; we_n <= '1'; re_n <= '1'; clk_sram_i <= '1'; pci_rdy <= '0'; rdreq_fifo <= '0'; case sm is when idle => if rdempty='0' then sm <= fifo_rd1; elsif pci_rd_req_s='1' then sm <= sram_A; addr <= pci_raddr & '0'; end if; when fifo_rd1 => rdreq_fifo <= not rdempty; addr <= wcounter; if rdempty = '1' then sm <= idle; else sm <= fifo_rd2; we_n <= '0'; ce_n <= '0'; clk_sram_i <= '0'; end if; when fifo_rd2 => we_n <= '0'; ce_n <= '0'; -- addr <= wcounter; -- write address if rdreq_fifo='1' then sm <= fifo_rd1; else sm <= idle; end if; when sram_A => addr <= pci_raddr & '0'; clk_sram_i <= '0'; ce_n <= '0'; sm <= sram_Ae; when sram_Ae => ce_n <= '0'; sm <= sram_A1; when sram_A1 => addr <= pci_raddr & '1'; clk_sram_i <= '0'; ce_n <= '0'; re_n <= '0'; sm <= sram_A1e; when sram_A1e=> ce_n <= '0'; re_n <= '0'; sm <= sram_D; when sram_D => clk_sram_i <= '0'; ce_n <= '0'; re_n <= '0'; sm <= sram_De; when sram_De => ce_n <= '0'; re_n <= '0'; sm <= sram_D1; when sram_D1 => clk_sram_i <= '0'; ce_n <= '0'; re_n <= '0'; sm <= sram_D1e; pci_rdy <= '1'; when sram_D1e=> ce_n <= '0'; re_n <= '0'; sm <= sram_fin; pci_rdy <= '1'; when sram_fin => pci_rdy <= '1'; if pci_rd_req_s='0' then sm <= idle; end if; when others => sm <= idle; end case; if sm /= idle then not_empty <= '1'; elsif sreset='1' then not_empty <= '0'; end if; end if; end process; process(clk) begin if clk'event and clk='1' then -- synchronize the software reset from PCI sreset120 <= sreset; pci_rd_req_s <= pci_rd_req; -- write address counter for SRAM if sm=fifo_rd2 then wcounter <= wcounter + 1; end if; if sm=sram_D1e then rcounter <= rcounter + 1; end if; if sreset120='1' then wcounter <= (others => '0'); cdata <= (others => '1'); rcounter <= (others => '0'); end if; -- output signals to SRAM if sm=fifo_rd2 then cdata <= q_h & q_l; -- write data end if; if sm=sram_De then sram_qL <= sram_q; end if; if sm=sram_D1e then sram_qH <= sram_q; end if; end if; end process; -- with sm select -- sm_num <= "0000" when idle, -- "0001" when fifo_rd, -- "0010" when fifo_st, -- "0011" when sram_A, -- "0100" when sram_Ae, -- "0101" when sram_A1, -- "0110" when sram_A1e, -- "0111" when sram_D, -- "1000" when sram_De, -- "1001" when sram_D1, -- "1010" when sram_D1e, -- "1011" when sram_fin, -- "1111" when others; -- outputs -- wdata <= cdata; wdata <= q_h & q_l; clk_sram <= clk_sram_i; sram_rdata <= sram_qH & sram_qL; process(wcounter, rcounter, pci_raddr, des_dv1_err1_cnt, des_dv0_err1_cnt, des_valid_data_cnt) begin naddr <= (others => '0'); case pci_raddr(1 downto 0) is when "00" | "01" => -- when "00" => naddr(wcounter'range) <= wcounter; naddr(23 downto 18) <= rcounter; when "10" => naddr(des_valid_data_cnt'range) <= des_valid_data_cnt; -- when "10" => naddr(des_dv0_err1_cnt'range) <= des_dv0_err1_cnt; when "11" => naddr(des_dv1_err1_cnt'range) <= des_dv1_err1_cnt; when others => naddr <= (others => '-'); end case; end process; end;