-- Async reset synchronizer circuit inspired from -- Chris Cummings SNUG 2002 paper -- Synchronous Resets? Asynchronous Resets? -- I am so confused! -- How will I ever know which to use? library ieee ; use ieee.std_logic_1164.all; entity reset_sync is generic ( POLARITY : std_logic := '0' ); port ( clk_i : in std_logic; rst_i : in std_logic; rst_o : out std_logic ); end entity; architecture sim of reset_sync is signal s_rst_d : std_logic_vector(1 downto 0); begin process (clk_i, rst_i) is begin if (rst_i = POLARITY) then s_rst_d <= (others => POLARITY); elsif (rising_edge(clk_i)) then s_rst_d <= s_rst_d(0) & not POLARITY; end if; end process; rst_o <= s_rst_d(1); end architecture; -- Async reset synchronizer circuit inspired from -- Chris Cummings SNUG 2002 paper -- Synchronous Resets? Asynchronous Resets? -- I am so confused! -- How will I ever know which to use? library ieee ; use ieee.std_logic_1164.all; entity reset_sync_slv is generic ( POLARITY : std_logic := '0' ); port ( clk_i : in std_logic; rst_i : in std_logic_vector; rst_o : out std_logic_vector ); end entity; architecture sim of reset_sync_slv is begin GEN : for i in rst_i'range generate signal s_rst_d : std_logic_vector(1 downto 0); begin process (clk_i, rst_i(i)) is begin if (rst_i(i) = POLARITY) then s_rst_d <= (others => POLARITY); elsif (rising_edge(clk_i)) then s_rst_d <= s_rst_d(0) & not POLARITY; end if; end process; rst_o(i) <= s_rst_d(1); end generate; end architecture; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fifo is generic ( DEPTH : positive := 16; WIDTH : positive := 16 ); port ( rst_n_i : in std_logic; clk_i : in std_logic; -- write wen_i : in std_logic; din_i : in std_logic_vector(WIDTH-1 downto 0); full_o : out std_logic; werror_o : out std_logic; -- read ren_i : in std_logic; dout_o : out std_logic_vector(WIDTH-1 downto 0); empty_o : out std_logic; rerror_o : out std_logic ); end entity fifo; architecture rtl of fifo is subtype t_fifo_pnt is natural range 0 to DEPTH-1; signal s_write_pnt : t_fifo_pnt; signal s_read_pnt : t_fifo_pnt; type t_fifo_mem is array (t_fifo_pnt'low to t_fifo_pnt'high) of std_logic_vector(din_i'range); signal s_fifo_mem : t_fifo_mem; signal s_almost_full : boolean; signal s_almost_empty : boolean; function incr_pnt (data : t_fifo_pnt) return t_fifo_pnt is begin if (data = t_fifo_mem'high) then return 0; end if; return data + 1; end function incr_pnt; begin s_almost_full <= (s_write_pnt = s_read_pnt - 1) or (s_write_pnt = t_fifo_mem'high and s_read_pnt = t_fifo_mem'low); s_almost_empty <= (s_read_pnt = s_write_pnt - 1) or (s_read_pnt = t_fifo_mem'high and s_write_pnt = t_fifo_mem'low); WriteP : process (rst_n_i, clk_i) is begin if (not rst_n_i) then s_write_pnt <= 0; werror_o <= '0'; elsif (rising_edge(clk_i)) then werror_o <= Wen_i and Full_o; if (Wen_i = '1' and Full_o = '0') then s_fifo_mem(s_write_pnt) <= Din_i; s_write_pnt <= incr_pnt(s_write_pnt); end if; end if; end process WriteP; ReadP : process (rst_n_i, clk_i) is begin if (not rst_n_i) then s_read_pnt <= 0; rerror_o <= '0'; elsif (rising_edge(clk_i)) then rerror_o <= Ren_i and Empty_o; if (Ren_i = '1' and Empty_o = '0') then Dout_o <= s_fifo_mem(s_read_pnt); s_read_pnt <= incr_pnt(s_read_pnt); end if; end if; end process ReadP; FlagsP : process (rst_n_i, clk_i) is begin if (rst_n_i = '0') then Full_o <= '0'; Empty_o <= '1'; elsif (rising_edge(clk_i)) then if (Wen_i = '1') then if (Ren_i = '0' and s_almost_full) then Full_o <= '1'; end if; Empty_o <= '0'; end if; if (Ren_i = '1') then if (Wen_i = '0' and s_almost_empty) then Empty_o <= '1'; end if; Full_o <= '0'; end if; end if; end process FlagsP; end architecture; -- Synchronous AXI stream FIFO based on generic fifo -- component. Configurable depth and width. library ieee ; use ieee.std_logic_1164.all; library gatemate; use gatemate.components.all; entity axis_fifo is generic ( DEPTH : positive := 8; WIDTH : positive := 8 ); port ( -- global rst_n_i : in std_logic; clk_i : in std_logic; -- axis in tdata_i : in std_logic_vector(WIDTH-1 downto 0); tvalid_i : in std_logic; tready_o : out std_logic; -- axis aout tdata_o : out std_logic_vector(WIDTH-1 downto 0); tvalid_o : out std_logic; tready_i : in std_logic ); end entity; architecture rtl of axis_fifo is signal s_fifo_wen : std_logic; signal s_fifo_ren : std_logic; signal s_fifo_empty : std_logic; signal s_fifo_full : std_logic; signal s_fwft_empty : std_logic; signal s_ren : std_logic; begin fifo : entity work.fifo generic map ( DEPTH => DEPTH, WIDTH => WIDTH ) port map ( rst_n_i => rst_n_i, clk_i => clk_i, -- write wen_i => s_fifo_wen, din_i => tdata_i, full_o => s_fifo_full, werror_o => open, -- read ren_i => s_fifo_ren, dout_o => tdata_o, empty_o => s_fifo_empty, rerror_o => open ); -- FWFT logic process (clk_i, rst_n_i) is begin if (not rst_n_i) then s_fwft_empty <= '1'; elsif (rising_edge(clk_i)) then if (s_fifo_ren) then s_fwft_empty <= '0'; elsif (s_ren) then s_fwft_empty <= '1'; end if; end if; end process; s_fifo_ren <= not s_fifo_empty and (s_fwft_empty or s_ren); -- AXIS logic s_fifo_wen <= tvalid_i and not s_fifo_full; s_ren <= tready_i and not s_fwft_empty; tready_o <= not s_fifo_full; tvalid_o <= not s_fwft_empty; end architecture; -- Synchronous AXI stream FIFO based on GateMate CC_FIFO_40K -- primitive library ieee ; use ieee.std_logic_1164.all; library gatemate; use gatemate.components.all; entity axis_fifo_gm is generic ( WIDTH : positive := 8 ); port ( -- global rst_n_i : in std_logic; clk_i : in std_logic; -- axis in tdata_i : in std_logic_vector(WIDTH-1 downto 0); tvalid_i : in std_logic; tready_o : out std_logic; -- axis aout tdata_o : out std_logic_vector(WIDTH-1 downto 0); tvalid_o : out std_logic; tready_i : in std_logic ); end entity; architecture rtl of axis_fifo_gm is signal s_fifo_wen : std_logic; signal s_fifo_ren : std_logic; signal s_fifo_empty : std_logic; signal s_fifo_full : std_logic; signal s_fwft_empty : std_logic; signal s_ren : std_logic; signal s_fifo_a_en : std_logic; signal s_fifo_b_en : std_logic; signal s_fifo_b_we : std_logic; signal s_fifo_din : std_logic_vector(79 downto 0); signal s_fifo_dout : std_logic_vector(79 downto 0); begin -- CC_FIFO_40K instance (512x80) fifo : CC_FIFO_40K generic map ( LOC => "UNPLACED", ALMOST_FULL_OFFSET => (others => '0'), ALMOST_EMPTY_OFFSET => (others => '0'), A_WIDTH => WIDTH, -- 1..80 B_WIDTH => WIDTH, -- 1..80 RAM_MODE => "SDP", FIFO_MODE => "SYNC", A_CLK_INV => '0', B_CLK_INV => '0', A_EN_INV => '0', B_EN_INV => '0', A_WE_INV => '0', B_WE_INV => '0', A_DO_REG => '0', B_DO_REG => '0', A_ECC_EN => '0', B_ECC_EN => '0' ) port map( A_ECC_1B_ERR => open, B_ECC_1B_ERR => open, A_ECC_2B_ERR => open, B_ECC_2B_ERR => open, -- FIFO pop port A_DO => s_fifo_dout(39 downto 0), B_DO => s_fifo_dout(79 downto 40), A_CLK => clk_i, A_EN => s_fifo_a_en, -- FIFO push port A_DI => s_fifo_din(39 downto 0), B_DI => s_fifo_din(79 downto 40), A_BM => (others => '1'), B_BM => (others => '1'), B_CLK => clk_i, B_EN => s_fifo_b_en, B_WE => s_fifo_b_we, -- FIFO control F_RST_N => rst_n_i, F_ALMOST_FULL_OFFSET => (others => '0'), F_ALMOST_EMPTY_OFFSET => (others => '0'), -- FIFO status signals F_FULL => s_fifo_full, F_EMPTY => s_fifo_empty, F_ALMOST_FULL => open, F_ALMOST_EMPTY => open, F_RD_ERROR => open, F_WR_ERROR => open, F_RD_PTR => open, F_WR_PTR => open ); s_fifo_b_en <= s_fifo_wen; s_fifo_b_we <= s_fifo_wen; s_fifo_a_en <= s_fifo_ren; -- FWFT logic process (clk_i, rst_n_i) is begin if (not rst_n_i) then s_fwft_empty <= '1'; elsif (rising_edge(clk_i)) then if (s_fifo_ren) then s_fwft_empty <= '0'; elsif (s_ren) then s_fwft_empty <= '1'; end if; end if; end process; s_fifo_ren <= not s_fifo_empty and (s_fwft_empty or s_ren); -- AXIS logic s_fifo_wen <= tvalid_i and not s_fifo_full; s_ren <= tready_i and not s_fwft_empty; tready_o <= not s_fifo_full; s_fifo_din(tdata_i'range) <= tdata_i; tvalid_o <= not s_fwft_empty; tdata_o <= s_fifo_dout(tdata_o'range); end architecture;