]> git.the-white-hart.net Git - vhdl/commitdiff
Add pipeline stream sources and more tests
authorrs <>
Fri, 12 Dec 2025 03:12:44 +0000 (21:12 -0600)
committerrs <>
Fri, 12 Dec 2025 03:12:44 +0000 (21:12 -0600)
libraries/dsp/lfsr.vhd [new file with mode: 0644]
libraries/dsp/src_counter.vhd [new file with mode: 0644]
libraries/dsp/src_fracstep.vhd [new file with mode: 0644]
libraries/dsp/src_noise.vhd [new file with mode: 0644]
libraries/dsp/tests/test_delay2.vhd [new file with mode: 0644]
libraries/dsp/tests/test_pcm16_2ch_gain.vhd [new file with mode: 0644]
libraries/dsp/tests/test_src_noise.vhd [new file with mode: 0644]

diff --git a/libraries/dsp/lfsr.vhd b/libraries/dsp/lfsr.vhd
new file mode 100644 (file)
index 0000000..98f60e3
--- /dev/null
@@ -0,0 +1,47 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+
+entity lfsr is
+       generic (
+               INIT: std_logic_vector(15 downto 0)
+       );
+       port (
+               clk_i: in  std_logic;
+               en_i:  in  std_logic;
+               dat_o: out std_logic
+       );
+end lfsr;
+
+architecture behavioral of lfsr is
+
+       signal tap_10:   std_logic;
+       signal tap_15:   std_logic;
+       signal feedback: std_logic;
+
+begin
+
+       -- This is the example from Xilinx WP271
+       -- It's not the best, but it's simple enough to do with one SRL
+       e_srl: srlc16e
+               generic map (INIT => to_bitvector(INIT))
+               port map (
+                       D   => feedback,
+                       CE  => en_i,
+                       CLK => clk_i,
+                       A0  => '0',
+                       A1  => '1',
+                       A2  => '0',
+                       A3  => '1',
+                       Q   => tap_10,
+                       Q15 => tap_15
+               );
+
+       feedback <= tap_10 xor tap_15;
+       dat_o <= tap_15;
+
+end behavioral;
+
diff --git a/libraries/dsp/src_counter.vhd b/libraries/dsp/src_counter.vhd
new file mode 100644 (file)
index 0000000..347373a
--- /dev/null
@@ -0,0 +1,41 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity src_counter is
+       generic (
+               WIDTH: positive := 16
+       );
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+
+               stb_o: out std_logic;
+               rdy_i: in  std_logic;
+               dat_o: out std_logic_vector(WIDTH-1 downto 0)
+       );
+end src_counter;
+
+
+architecture behavioral of src_counter is
+
+       signal count_reg: unsigned(WIDTH-1 downto 0);
+
+begin
+
+       process(rst_i, clk_i, count_reg)
+       begin
+               if rising_edge(clk_i) then
+                       if rst_i = '1' then
+                               count_reg <= (others => '0');
+                       elsif rdy_i = '1' then
+                               count_reg <= count_reg + 1;
+                       end if;
+               end if;
+       end process;
+
+       stb_o <= '1';
+       dat_o <= std_logic_vector(count_reg);
+
+end behavioral;
diff --git a/libraries/dsp/src_fracstep.vhd b/libraries/dsp/src_fracstep.vhd
new file mode 100644 (file)
index 0000000..69e3f92
--- /dev/null
@@ -0,0 +1,45 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity src_fracstep is
+       generic (
+               WIDTH_OUT:  positive := 16;
+               WIDTH_INC:  natural  := 16;
+               WIDTH_FRAC: natural  := 8
+       );
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+
+               inc_i: in  std_logic_vector(WIDTH_INC-1 downto 0);
+
+               stb_o: out std_logic;
+               rdy_i: in  std_logic;
+               dat_o: out std_logic_vector(WIDTH_OUT-1 downto 0)
+       );
+end src_fracstep;
+
+
+architecture behavioral of src_fracstep is
+
+       signal count_reg: unsigned(WIDTH_OUT+WIDTH_FRAC-1 downto 0);
+
+begin
+
+       process (rst_i, clk_i, inc_i)
+       begin
+               if rising_edge(clk_i) then
+                       if rst_i = '1' then
+                               count_reg <= (others => '0');
+                       elsif rdy_i = '1' then
+                               count_reg <= count_reg + unsigned(inc_i);
+                       end if;
+               end if;
+       end process;
+
+       stb_o <= '1';
+       dat_o <= std_logic_vector(count_reg(WIDTH_OUT+WIDTH_FRAC-1 downto WIDTH_FRAC));
+
+end behavioral;
diff --git a/libraries/dsp/src_noise.vhd b/libraries/dsp/src_noise.vhd
new file mode 100644 (file)
index 0000000..9b341d2
--- /dev/null
@@ -0,0 +1,44 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+
+
+entity src_noise is
+       generic (
+               WIDTH: positive := 16
+       );
+       port (
+               clk_i: in  std_logic;
+
+               stb_o: out std_logic;
+               rdy_i: in  std_logic;
+               dat_o: out std_logic_vector(WIDTH-1 downto 0)
+       );
+end src_noise;
+
+
+architecture behavioral of src_noise is
+
+       constant X: std_logic_vector(15 downto 0) := x"0001";
+
+begin
+
+       g_bits: for i in WIDTH-1 downto 0 generate
+               e_lfsr: entity work.lfsr
+                       generic map (
+                               -- First part guarantees at least one bit set
+                               -- Second part is an attempt at pseudorandomness
+                               INIT => std_logic_vector(rotate_left(unsigned(X), i)) or std_logic_vector(to_unsigned(i*13, 16) xor x"a5c3")
+                       )
+                       port map (
+                               clk_i => clk_i,
+                               en_i  => rdy_i,
+                               dat_o => dat_o(i)
+                       );
+       end generate;
+
+       stb_o <= '1';
+
+end behavioral;
diff --git a/libraries/dsp/tests/test_delay2.vhd b/libraries/dsp/tests/test_delay2.vhd
new file mode 100644 (file)
index 0000000..a3af16e
--- /dev/null
@@ -0,0 +1,115 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_delay2 is
+end test_delay2;
+
+
+architecture behavior of test_delay2 is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal rst_i:       std_logic;
+       signal clk_i:       std_logic;
+
+       signal src_stb:     std_logic;
+       signal src_rdy:     std_logic;
+       signal src_dat:     std_logic_vector(7 downto 0);
+
+       signal split_a_stb: std_logic;
+       signal split_a_rdy: std_logic;
+       signal split_b_stb: std_logic;
+       signal split_b_rdy: std_logic;
+       signal split_dat:   std_logic_vector(7 downto 0);
+
+       signal delay_en:    std_logic;
+       signal delay_dat:   std_logic_vector(7 downto 0);
+       signal norm_dat:    std_logic_vector(7 downto 0);
+
+begin
+
+       p_test: process
+       begin
+               -- Reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD*17;
+               rst_i <= '0';
+
+               -- Done
+               wait;
+       end process;
+
+       e_src: entity work.src_counter
+               generic map (WIDTH => 8)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       stb_o => src_stb,
+                       rdy_i => src_rdy,
+                       dat_o => src_dat
+               );
+
+       e_split: entity work.pipectrl_split
+               generic map (WIDTH => 8)
+               port map (
+                       rst_i   => rst_i,
+                       clk_i   => clk_i,
+                       stb_i   => src_stb,
+                       rdy_o   => src_rdy,
+                       dat_i   => src_dat,
+                       a_stb_o => split_a_stb,
+                       a_rdy_i => split_a_rdy,
+                       b_stb_o => split_b_stb,
+                       b_rdy_i => split_b_rdy,
+                       dat_o   => split_dat
+               );
+
+       e_norm: entity work.pipectrl
+               generic map (WIDTH => 8)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       stb_i => split_a_stb,
+                       rdy_o => split_a_rdy,
+                       dat_i => split_dat,
+                       stb_o => open,
+                       rdy_i => '1',
+                       dat_o => norm_dat
+               );
+
+       e_delay_ctrl: entity work.pipectrl
+               generic map (WIDTH => 8)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_o  => delay_en,
+                       stb_i => split_b_stb,
+                       rdy_o => split_b_rdy,
+                       dat_i => split_dat,
+                       stb_o => open,
+                       rdy_i => '1',
+                       dat_o => norm_dat
+               );
+
+       e_delay: entity work.delay_srl
+               generic map (WIDTH => 8, DELAY => 2)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       en_i  => delay_en,
+                       dat_i => split_dat,
+                       dat_o => delay_dat
+               );
+
+       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_pcm16_2ch_gain.vhd b/libraries/dsp/tests/test_pcm16_2ch_gain.vhd
new file mode 100644 (file)
index 0000000..23f67e8
--- /dev/null
@@ -0,0 +1,98 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_pcm16_2ch_gain is
+end test_pcm16_2ch_gain;
+
+
+architecture behavior of test_pcm16_2ch_gain is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal gain_l: std_logic_vector(17 downto 0);
+       signal gain_r: std_logic_vector(17 downto 0);
+
+       signal rst_i: std_logic;
+       signal clk_i: std_logic;
+       signal dat_i: std_logic_vector(31 downto 0);
+       signal dat_o: std_logic_vector(31 downto 0);
+
+begin
+
+       p_test: process
+       begin
+               -- Initial values
+
+               -- Reset
+               rst_i <= '1';
+               wait for CLK_I_PERIOD;
+               rst_i <= '0';
+
+               -- Test
+               gain_l <= "000000001" & "000000000";
+               gain_r <= "000000001" & "000000000";
+               dat_i <= x"0001" & x"0002";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0003" & x"0004";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0005" & x"0006";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0007" & x"0008";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"ffff" & x"fffe";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"fffd" & x"fffc";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"fffb" & x"fffa";
+               wait for CLK_I_PERIOD;
+
+               gain_l <= "000000000" & "100000000";
+               gain_r <= "000000000" & "100000000";
+               dat_i <= x"0001" & x"0002";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0003" & x"0004";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0005" & x"0006";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"0007" & x"0008";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"ffff" & x"fffe";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"fffd" & x"fffc";
+               wait for CLK_I_PERIOD;
+               dat_i <= x"fffb" & x"fffa";
+               wait for CLK_I_PERIOD;
+
+               -- Done
+               wait;
+       end process;
+
+       e_uut: entity work.pcm16_2ch_gain
+               port map (
+                       rst_i  => rst_i,
+                       clk_i  => clk_i,
+
+                       gain_l => gain_l,
+                       gain_r => gain_r,
+
+                       stb_i  => '1',
+                       rdy_o  => open,
+                       dat_i  => dat_i,
+
+                       stb_o  => open,
+                       rdy_i  => '1',
+                       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_src_noise.vhd b/libraries/dsp/tests/test_src_noise.vhd
new file mode 100644 (file)
index 0000000..5227242
--- /dev/null
@@ -0,0 +1,37 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_src_noise is
+end test_src_noise;
+
+
+architecture behavior of test_src_noise is
+
+       constant CLK_I_PERIOD: time := 20 ns;
+
+       signal clk_i: std_logic;
+       signal dat_o: std_logic_vector(15 downto 0);
+
+begin
+
+       e_uut: entity work.src_noise
+               generic map (WIDTH => 16)
+               port map (
+                       clk_i => clk_i,
+                       stb_o => open,
+                       rdy_i => '1',
+                       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;