]> git.the-white-hart.net Git - vhdl/commitdiff
Add sample delay entities
authorrs <>
Thu, 11 Dec 2025 08:46:46 +0000 (02:46 -0600)
committerrs <>
Thu, 11 Dec 2025 08:46:46 +0000 (02:46 -0600)
libraries/dsp/delay_bram.vhd [new file with mode: 0644]
libraries/dsp/delay_srl.vhd [new file with mode: 0644]
libraries/dsp/tests/test_delay_bram.vhd [new file with mode: 0644]
libraries/dsp/tests/test_delay_srl.vhd [new file with mode: 0644]

diff --git a/libraries/dsp/delay_bram.vhd b/libraries/dsp/delay_bram.vhd
new file mode 100644 (file)
index 0000000..e58157b
--- /dev/null
@@ -0,0 +1,82 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+
+entity delay_bram is
+       generic (
+               WIDTH: positive := 16;
+               DELAY: positive := 2048
+       );
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+
+               en_i:  in  std_logic;
+
+               dat_i: in  std_logic_vector(WIDTH-1 downto 0);
+               dat_o: out std_logic_vector(WIDTH-1 downto 0)
+       );
+end delay_bram;
+
+
+architecture behavioral of delay_bram is
+
+       constant COUNT_WIDTH: integer := 10;  --integer(ceil(log2(real(DELAY))));
+
+       signal ptr_head_reg:  unsigned(COUNT_WIDTH-1 downto 0);
+       signal ptr_tail_reg:  unsigned(COUNT_WIDTH   downto 0);
+
+begin
+
+       process (rst_i, clk_i, en_i, ptr_head_reg, ptr_tail_reg)
+               variable tail_sign: std_logic;
+       begin
+               if rising_edge(clk_i) then
+                       if rst_i = '1' then
+                               ptr_tail_reg <= unsigned(to_signed(-DELAY, COUNT_WIDTH+1));
+                               ptr_head_reg <= (others => '0');
+                       elsif en_i = '1' then
+                               tail_sign := ptr_tail_reg(COUNT_WIDTH);
+                               ptr_tail_reg <= ptr_tail_reg + 1;
+                               if tail_sign = '0' then
+                                       ptr_tail_reg(COUNT_WIDTH) <= '0';
+                               end if;
+
+                               ptr_head_reg <= ptr_head_reg + 1;
+                       end if;
+               end if;
+       end process;
+
+       e_fifo: ramb16_s18_s18
+               port map (
+                       -- Head port (insertion)
+                       WEA   => '1',
+                       ENA   => en_i,
+                       SSRA  => '0',
+                       CLKA  => clk_i,
+                       ADDRA => std_logic_vector(ptr_head_reg),
+                       DIA   => dat_i(15 downto 0),
+                       DIPA  => (others => '0'),
+
+                       DOA   => open,
+                       DOPA  => open,
+
+                       -- Tail port (removal)
+                       WEB   => '0',
+                       ENB   => en_i,
+                       SSRB  => ptr_tail_reg(COUNT_WIDTH),
+                       CLKB  => clk_i,
+                       ADDRB => std_logic_vector(ptr_tail_reg(9 downto 0)),
+                       DIB   => (others => '0'),
+                       DIPB  => (others => '0'),
+
+                       DOB   => dat_o(15 downto 0),
+                       DOPB  => open
+               );
+
+end behavioral;
diff --git a/libraries/dsp/delay_srl.vhd b/libraries/dsp/delay_srl.vhd
new file mode 100644 (file)
index 0000000..bbb6beb
--- /dev/null
@@ -0,0 +1,86 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+
+entity delay_srl is
+       generic (
+               WIDTH: positive := 16;
+               DELAY: natural  := 16
+       );
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+
+               en_i:  in  std_logic;
+               dat_i: in  std_logic_vector(WIDTH-1 downto 0);
+               dat_o: out std_logic_vector(WIDTH-1 downto 0)
+       );
+end delay_srl;
+
+
+architecture behavioral of delay_srl is
+
+       constant NUM_FULL_SRLS:    natural := DELAY / 16;
+       constant NUM_EXTRA_STAGES: natural := DELAY mod 16;
+
+       signal extra_tap: std_logic_vector(3 downto 0) := std_logic_vector(to_signed(NUM_EXTRA_STAGES-1, 4));
+
+       type word_array_t is array(natural range <>) of std_logic_vector(WIDTH-1 downto 0);
+
+       signal shift:     std_logic;
+
+       signal srl_in:    word_array_t(NUM_FULL_SRLS downto 1);
+       signal srl_out:   word_array_t(NUM_FULL_SRLS downto 0);
+       signal extra_in:  std_logic_vector(WIDTH-1 downto 0);
+       signal extra_out: std_logic_vector(WIDTH-1 downto 0);
+
+begin
+
+       shift <= en_i or rst_i;
+
+       srl_out(0) <= dat_i;
+
+       g_full: for i in 1 to NUM_FULL_SRLS generate
+               srl_in(i) <= (others => '0') when rst_i = '1' else srl_out(i-1);
+               g_bits: for j in WIDTH-1 downto 0 generate
+                       e_srl: srlc16e
+                               port map (
+                                       D   => srl_in(i)(j),
+                                       CE  => shift,
+                                       CLK => clk_i,
+                                       A0  => '0',
+                                       A1  => '0',
+                                       A2  => '0',
+                                       A3  => '0',
+                                       Q   => open,
+                                       Q15 => srl_out(i)(j)
+                               );
+               end generate;
+       end generate;
+
+       g_end_n: if NUM_EXTRA_STAGES > 0 generate
+               extra_in <= (others => '0') when rst_i = '1' else srl_out(NUM_FULL_SRLS);
+               g_bits: for j in WIDTH-1 downto 0 generate
+                       e_last: srl16e
+                               port map (
+                                       D   => extra_in(j),
+                                       CE  => shift,
+                                       CLK => clk_i,
+                                       A0  => extra_tap(0),
+                                       A1  => extra_tap(1),
+                                       A2  => extra_tap(2),
+                                       A3  => extra_tap(3),
+                                       Q   => extra_out(j)
+                               );
+               end generate;
+               dat_o <= extra_out;
+       end generate;
+       g_end_0: if NUM_EXTRA_STAGES = 0 generate
+               dat_o <= srl_out(NUM_FULL_SRLS);
+       end generate;
+
+end behavioral;
diff --git a/libraries/dsp/tests/test_delay_bram.vhd b/libraries/dsp/tests/test_delay_bram.vhd
new file mode 100644 (file)
index 0000000..f947d94
--- /dev/null
@@ -0,0 +1,79 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_delay_bram is
+end test_delay_bram;
+
+
+architecture behavior of test_delay_bram is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal rst_i: std_logic;
+       signal clk_i: std_logic;
+
+       signal en:    std_logic;
+
+       signal dat_i: std_logic_vector(15 downto 0);
+       signal dat_o: std_logic_vector(15 downto 0);
+
+begin
+
+       p_test: process
+       begin
+               -- Initial values
+               en <= '0';
+
+               -- Reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD;
+               rst_i <= '0';
+
+               -- Test
+               en  <= '1';
+               dat_i <= x"0001";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0002";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0003";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0004";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0005";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0006";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0007";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0008";
+               wait for CLK_I_PERIOD;
+
+               -- Done
+               wait;
+       end process;
+
+       e_uut: entity work.delay_bram
+               generic map (
+                       WIDTH => 16,
+                       DELAY => 4
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o
+               );
+
+       p_clk: process
+       begin
+               clk_i <= '0';
+               wait for CLK_I_PERIOD/2;
+               clk_i <= '1';
+               wait for CLK_I_PERIOD/2;
+       end process;
+
+end;
diff --git a/libraries/dsp/tests/test_delay_srl.vhd b/libraries/dsp/tests/test_delay_srl.vhd
new file mode 100644 (file)
index 0000000..3501d0b
--- /dev/null
@@ -0,0 +1,151 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_delay_srl is
+end test_delay_srl;
+
+
+architecture behavior of test_delay_srl is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal rst_i:    std_logic;
+       signal clk_i:    std_logic;
+
+       signal en:       std_logic;
+
+       signal dat_i:    std_logic_vector(7 downto 0);
+       signal dat_o_15: std_logic_vector(7 downto 0);
+       signal dat_o_16: std_logic_vector(7 downto 0);
+       signal dat_o_17: std_logic_vector(7 downto 0);
+       signal dat_o_31: std_logic_vector(7 downto 0);
+       signal dat_o_32: std_logic_vector(7 downto 0);
+       signal dat_o_33: std_logic_vector(7 downto 0);
+
+begin
+
+       p_test: process
+       begin
+               -- Initial values
+               en <= '0';
+
+               -- Reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD*17;
+               rst_i <= '0';
+
+               -- Test
+               en    <= '1';
+               dat_i <= x"01";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"02";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"03";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"04";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"a5";
+               wait for CLK_I_PERIOD;
+
+               wait for CLK_I_PERIOD*33;
+               en <= '0';
+
+               -- Test reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD*17;
+               rst_i <= '0';
+
+               -- Done
+               wait;
+       end process;
+
+       e_uut_15: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 15
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_15
+               );
+
+       e_uut_16: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 16
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_16
+               );
+
+       e_uut_17: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 17
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_17
+               );
+
+       e_uut_31: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 31
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_31
+               );
+
+       e_uut_32: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 32
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_32
+               );
+
+       e_uut_33: entity work.delay_srl
+               generic map (
+                       WIDTH => 8,
+                       DELAY => 33
+               )
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => en,
+                       dat_i => dat_i,
+                       dat_o => dat_o_33
+               );
+
+       p_clk: process
+       begin
+               clk_i <= '0';
+               wait for CLK_I_PERIOD/2;
+               clk_i <= '1';
+               wait for CLK_I_PERIOD/2;
+       end process;
+
+end;