You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

422 lines
9.2 KiB

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