-- 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;
|