|
@ -1,13 +1,14 @@ |
|
|
library ieee ; |
|
|
|
|
|
use ieee.std_logic_1164.all; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Async reset synchronizer circuit inspired from |
|
|
-- Async reset synchronizer circuit inspired from |
|
|
-- Chris Cummings SNUG 2002 paper |
|
|
-- Chris Cummings SNUG 2002 paper |
|
|
-- Synchronous Resets? Asynchronous Resets? |
|
|
-- Synchronous Resets? Asynchronous Resets? |
|
|
-- I am so confused! |
|
|
-- I am so confused! |
|
|
-- How will I ever know which to use? |
|
|
-- How will I ever know which to use? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
library ieee ; |
|
|
|
|
|
use ieee.std_logic_1164.all; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entity reset_sync is |
|
|
entity reset_sync is |
|
|
generic ( |
|
|
generic ( |
|
|
POLARITY : std_logic := '0' |
|
|
POLARITY : std_logic := '0' |
|
@ -38,3 +39,384 @@ begin |
|
|
rst_o <= s_rst_d(1); |
|
|
rst_o <= s_rst_d(1); |
|
|
|
|
|
|
|
|
end architecture; |
|
|
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; |