-- -- LL Packet FIFO -- -- Clock crossing fifo that buffers whole packets of data -- -- -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library utils; use utils.pkg_types.all; entity ll_pkt_fifo_txcx is port( -- input interface core_lls_i: in t_llsrc; core_lld_o : out std_logic; --core_src_rdy_i : in std_logic; --core_sof_i : in std_logic; --core_eof_i : in std_logic; --core_data_i : in std_logic_vector (15 downto 0); --core_dst_rdy_o : out std_logic; -- output interface net_lls_o : out t_llsrc; net_lld_i : in std_logic; --net_data_o : out std_logic_vector (15 downto 0); --net_sof_o : out std_logic; --net_eof_o : out std_logic; --net_dst_rdy_i : in std_logic; --net_src_rdy_o : out std_logic; -- fifo status --full_o : out std_logic; --near_full_o : out std_logic; --overflow_o : out std_logic; --underflow_o : out std_logic; --wr_data_count_o : out std_logic_vector (3 downto 0) := "0000"; clk80 : in std_logic; rst80 : in std_logic; clk125 : in std_logic; rst125 : in std_logic ); -- Declarations end ll_pkt_fifo_txcx; architecture rtl of ll_pkt_fifo_txcx is signal core_dst_rdy : std_logic; component cg_cxbrfifo_2kx18_ft port ( wr_clk : in std_logic; wr_rst : in std_logic; din : in std_logic_vector(17 downto 0); wr_en : in std_logic; full : out std_logic; --almost_full : out std_logic; prog_full : out std_logic; rd_clk : in std_logic; rd_rst : in std_logic; rd_en : in std_logic; dout : out std_logic_vector(17 downto 0); empty : out std_logic ); end component; signal fifo_rd : std_logic; signal fifo_full : std_logic; signal fifo_prog_full : std_logic; signal fifo_din : std_logic_vector(17 downto 0); signal fifo_wr : std_logic; signal fifo_dout : std_logic_vector(17 downto 0); --signal fifo_empty : std_logic; signal fifo_sof : std_logic; signal fifo_sof_q : std_logic := '0'; signal fifo_eof : std_logic; signal efifo_rd : std_logic; signal efifo_full : std_logic; signal efifo_wr : std_logic; signal efifo_dout : std_logic_vector(0 downto 0); signal efifo_empty : std_logic; component cg_cxdrfifo_1x16_ft port ( wr_clk : in std_logic; wr_rst : in std_logic; din : in std_logic_vector(0 downto 0); wr_en : in std_logic; full : out std_logic; rd_clk : in std_logic; rd_rst : in std_logic; rd_en : in std_logic; dout : out std_logic_vector(0 downto 0); empty : out std_logic ); end component; type states is (FIFOSOF, SrcRdy, SOF, WaitEOF, NextEOF, Delay, Idle ); signal state, nstate : states; begin core_dst_rdy <= not(fifo_prog_full or rst80); core_lld_o <= core_dst_rdy; fifo_wr <= core_lls_i.src_rdy and core_dst_rdy; fifo_din(15 downto 0) <= core_lls_i.data; fifo_din(16) <= core_lls_i.eof; fifo_din(17) <= core_lls_i.sof; fifo0 : cg_cxbrfifo_2kx18_ft port map ( wr_clk => clk80, wr_rst => rst80, din => fifo_din, wr_en => fifo_wr, full => fifo_full, --almost_full => open, prog_full => fifo_prog_full, rd_clk => clk125, rd_rst => rst125, rd_en => fifo_rd, dout => fifo_dout, empty => open ); net_lls_o.data <= fifo_dout(15 downto 0); fifo_eof <= fifo_dout(16); fifo_sof <= fifo_dout(17); --------------------------------------------------------------- prc_readsm_sync : process (clk125) begin if rising_edge(clk125) then if (rst125 = '1') then state <= Idle; else state <= nstate; end if; end if; end process; prc_readsm_async : process (efifo_dout, efifo_empty, fifo_eof, fifo_sof, net_lld_i, state) begin -- defaults nstate <= Idle; net_lls_o.src_rdy <= '0'; net_lls_o.sof <= '0'; net_lls_o.eof <= '0'; fifo_rd <= '0'; efifo_rd <= '0'; case state is when Idle => nstate <= Idle; if (efifo_dout = "1") and (efifo_empty = '0') then -- eof seen nstate <= FIFOSOF; end if; when FIFOSOF => nstate <= FIFOSOF; if (fifo_sof = '1') then net_lls_o.src_rdy <= '1'; if (net_lld_i = '1') then nstate <= SrcRdy; end if; else fifo_rd <= '1'; end if; when SrcRdy => net_lls_o.src_rdy <= '1'; nstate <= SOF; when SOF => nstate <= SOF; net_lls_o.src_rdy <= '1'; net_lls_o.sof <= '1'; if (net_lld_i = '1') then fifo_rd <= '1'; nstate <= WaitEOF; end if; when WaitEOF => nstate <= WaitEOF; net_lls_o.src_rdy <= '1'; net_lls_o.eof <= fifo_eof; if (net_lld_i = '1') then if (fifo_eof = '1') then nstate <= NextEOF; -- no more reads needed now else fifo_rd <= '1'; end if; end if; when NextEOF => efifo_rd <= '1'; nstate <= Delay; when Delay => -- need to wait for the delta_eof to update nstate <= Idle; end case; end process; ------------------------------------------------------------------- -- EOF FIFO ------------------------------------------------------------------- efifo_wr <= (core_lls_i.eof and core_lls_i.src_rdy and core_dst_rdy); efifo0 : cg_cxdrfifo_1x16_ft port map ( wr_clk => clk80, wr_rst => rst80, din => "1", wr_en => efifo_wr, full => efifo_full, rd_clk => clk125, rd_rst => rst125, rd_en => efifo_rd, dout => efifo_dout, empty => efifo_empty ); end architecture;