diff --git a/modules/genrams/generic_shiftreg_fifo.vhd b/modules/genrams/generic_shiftreg_fifo.vhd index 1c19e4eb1a91f060f35a2dc9b664fb43e961a5c2..2c0620c013121c9189c196facc20992ef061f68e 100644 --- a/modules/genrams/generic_shiftreg_fifo.vhd +++ b/modules/genrams/generic_shiftreg_fifo.vhd @@ -72,13 +72,20 @@ end generic_shiftreg_fifo; architecture rtl of generic_shiftreg_fifo is - constant c_srl_length : integer := g_size; -- set to srl 'type' 16 or 32 bit length - - type t_srl_array is array (c_srl_length - 1 downto 0) of std_logic_vector (g_data_width - 1 downto 0); - - signal fifo_store : t_srl_array; - signal pointer : integer range 0 to c_srl_length - 1; + component gc_shiftreg + generic ( + g_size : integer); + port ( + clk_i : in std_logic; + en_i : in std_logic; + d_i : in std_logic; + q_o : out std_logic; + a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0)); + end component; + + signal pointer : integer range 0 to g_size-1; + signal srl_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0); signal pointer_zero : std_logic; signal pointer_full : std_logic; signal pointer_almost_full : std_logic; @@ -92,22 +99,21 @@ begin do_write <= '1' when (rd_i = '1' and we_i = '1') or (we_i = '1' and pointer_full = '0') else '0'; --- data store SRL's - p_data_srl : process(clk_i) - begin - if rising_edge(clk_i) then --- if rst_n_i = '0'then --- for i in 0 to c_srl_length-1 loop --- fifo_store(i) <= (others => '0'); --- end loop; -- i - if do_write = '1' then - fifo_store <= fifo_store(fifo_store'left - 1 downto 0) & d_i; - end if; - end if; - end process; - q_o <= fifo_store(pointer); + gen_sregs: for i in 0 to g_data_width-1 generate + U_SRLx: gc_shiftreg + generic map ( + g_size => g_size) + port map ( + clk_i => clk_i, + en_i => do_write, + d_i => d_i(i), + q_o => q_o(i), + a_i => srl_addr); + end generate gen_sregs; + srl_addr <= std_logic_vector(to_unsigned(pointer, srl_addr'length)); + p_empty_logic : process(clk_i) begin if rising_edge(clk_i) then @@ -149,8 +155,8 @@ begin -- Detect when pointer is zero and maximum pointer_zero <= '1' when pointer = 0 else '0'; - pointer_full <= '1' when pointer = c_srl_length - 1 else '0'; - pointer_almost_full <= '1' when pointer_full = '1' or pointer = c_srl_length - 2 else '0'; + pointer_full <= '1' when pointer = g_size - 1 else '0'; + pointer_almost_full <= '1' when pointer_full = '1' or pointer = g_size - 2 else '0'; -- assign internal signals to outputs diff --git a/modules/genrams/xilinx/Manifest.py b/modules/genrams/xilinx/Manifest.py index 9595065db5c3e3eb60ed4e1c8004ea1c9b5264b7..f4fc825e9ad1254dcf6879f0040daad1cea8393e 100644 --- a/modules/genrams/xilinx/Manifest.py +++ b/modules/genrams/xilinx/Manifest.py @@ -3,4 +3,6 @@ files = [ "generic_dpram_sameclock.vhd", "generic_dpram_dualclock.vhd", "generic_simple_dpram.vhd", -"generic_spram.vhd"]; +"generic_spram.vhd", +"gc_shiftreg.vhd"] + diff --git a/modules/genrams/xilinx/gc_shiftreg.vhd b/modules/genrams/xilinx/gc_shiftreg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..87a4eee971db2138a290a203a4a2f7c984dba396 --- /dev/null +++ b/modules/genrams/xilinx/gc_shiftreg.vhd @@ -0,0 +1,68 @@ +library ieee; + +use ieee.STD_LOGIC_1164.all; +use ieee.NUMERIC_STD.all; + +use work.genram_pkg.all; + +entity gc_shiftreg is + + generic ( + g_size : integer); + + port ( + clk_i : in std_logic; + en_i : in std_logic; + d_i : in std_logic; + q_o : out std_logic; + a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0)); + +end gc_shiftreg; + + +architecture wrapper of gc_shiftreg is + + component SRLC32E + port ( + Q : out std_ulogic; + A : in std_logic_vector (4 downto 0); + CE : in std_ulogic; + CLK : in std_ulogic; + D : in std_ulogic); + end component; + + signal a : std_logic_vector(4 downto 0); + signal sr : std_logic_vector(g_size-1 downto 0); + +begin -- wrapper + + assert (g_size <= 32) report "gc_shiftreg[xilinx]: forced SRL32 implementation can be done only for 32-bit or smaller shift registers" severity warning; + + a <= std_logic_vector(resize(unsigned(a_i), 5)); + + gen_srl32 : if(g_size <= 32) generate + U_SRLC32 : SRLC32E + port map ( + Q => q_o, + A => a, + CE => en_i, + CLK => clk_i, + D => d_i); + end generate gen_srl32; + + gen_inferred : if(g_size > 32) generate + + p_srl : process(clk_i) + begin + if rising_edge(clk_i) then + if en_i = '1' then + sr <= sr(sr'left - 1 downto 0) & d_i; + end if; + end if; + end process; + + q_o <= sr(TO_INTEGER(unsigned(a_i))); + end generate gen_inferred; + + +end wrapper;