diff --git a/lib/filter/src/fir_semi_parallel.vhd b/lib/filter/src/fir_semi_parallel.vhd index 4bd0ecb..e175530 100644 --- a/lib/filter/src/fir_semi_parallel.vhd +++ b/lib/filter/src/fir_semi_parallel.vhd @@ -81,8 +81,8 @@ architecture Behavioral of fir_semi_parallel is signal count_array : count_array_t; signal count0 : count_t; - signal ce0 : std_logic; signal ce_array : unsigned(nstages downto 0); + signal en_array : unsigned(nstages downto 0); signal coef_addr : unsigned(coef_addr_nbits-1 downto 0); SIGNAL x : stage_array_t; @@ -90,9 +90,10 @@ architecture Behavioral of fir_semi_parallel is SIGNAL y : stage_array_t; SIGNAL accu : sfixed(shi(nbits_stages, nbits_stages_frac) downto slo(nbits_stages, nbits_stages_frac)); - signal en : std_logic; + SIGNAL act : std_logic := '0'; + SIGNAL start_r : std_logic := '0'; signal accu_load : std_logic; - signal accu_ld_pipe : unsigned(nstages+input_latency+coef_latency+pipe_latency downto 0); + signal accu_ld_pipe : unsigned(nstages+input_latency+coef_latency+pipe_latency-2 downto 0); signal din_r : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); signal coef_we : unsigned(nstages-1 downto 0); @@ -111,6 +112,7 @@ begin y(0) <= to_sfixed(0.0, y(0)); accu_load <= accu_ld_pipe(accu_ld_pipe'left); + start_r <= act and ce_array(ce_array'left) and not ce_array(ce_array'left-1); din_register: process(clk) @@ -128,8 +130,8 @@ accu_load_pipe: if rising_edge(clk) then if rst = '1' then accu_ld_pipe <= (others => '0'); - elsif en = '1' then - accu_ld_pipe <= accu_ld_pipe(accu_ld_pipe'left-1 downto 0) & ce0; + else + accu_ld_pipe <= accu_ld_pipe(accu_ld_pipe'left-1 downto 0) & start_r; end if; end if; end process; @@ -151,41 +153,43 @@ coef_we_gen: end if; end process; -counter: +rdy_logic: process(clk) - variable cnt : count_t; begin if rising_edge(clk) then - ce0 <= '0'; - count0 <= cnt; if rst = '1' then rdy <= '1'; - en <= '0'; - cnt := count_t'high; - elsif cnt /= count_t'high then - cnt := cnt + 1; - if cnt = count_t'high-1 then - rdy <= '1'; - end if; - else - en <= '0'; - if din_vld = '1' then - en <= '1'; - cnt := 0; - ce0 <= '1'; - rdy <= '0'; - end if; + act <= '0'; + elsif start = '1' then + rdy <= '0'; + act <= '1'; + elsif count0 = count_t'high-2 then + rdy <= '1'; + act <= '0'; end if; end if; end process; -cnt_pipe: +counter: process(clk) + variable cnt : count_t; + variable enable : std_logic; begin if rising_edge(clk) then - if en = '1' then - count_array <= count_array(count_array'left-1 downto 0) & count0; + if rst = '1' then + cnt := count_t'high; + elsif cnt /= count_t'high then + cnt := cnt + 1; + else + enable := '0'; + if start_r = '1' then + enable := '1'; + cnt := 0; + end if; end if; + count0 <= cnt; + count_array <= count_array(count_array'left-1 downto 0) & cnt; + en_array <= en_array(en_array'left-1 downto 0) & enable; end if; end process; @@ -195,8 +199,8 @@ ce_pipe: if rising_edge(clk) then if rst = '1' then ce_array <= (others => '0'); - elsif en = '1' then - ce_array <= ce_array(ce_array'left-1 downto 0) & ce0; + else + ce_array <= ce_array(ce_array'left-1 downto 0) & din_vld; end if; end if; end process; @@ -218,7 +222,7 @@ gen_coef_ram: clka => clk, clkb => clk, en_a => '1', - en_b => en, + en_b => en_array(i), we_a => coef_we(i), addr_a => addr_a, addr_b => addr_b, @@ -247,7 +251,7 @@ gen_stages: PORT MAP ( clk => clk, - ce => en, + ce => en_array(i), x_in => x(i+1), y_in => y(i), h_in => h_in, @@ -272,7 +276,6 @@ gen_delays: ( rst => rst, clk => clk, - ce => en, shift_en => ce_array(i), delay => count_array(i), din => x(i), @@ -284,10 +287,10 @@ acumulator: process(clk) begin if rising_edge(clk) then + dout_vld <= accu_load; if rst = '1' then dout_vld <= '0'; - elsif en = '1' then - dout_vld <= accu_load; + elsif en_array(en_array'left) = '1' then if accu_load = '1' then dout <= resize(accu, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac)); accu <= y(nstages); diff --git a/lib/filter/src/tb_fir_semi_parallel.vhd b/lib/filter/src/tb_fir_semi_parallel.vhd index bf6ee5d..d7f36ad 100644 --- a/lib/filter/src/tb_fir_semi_parallel.vhd +++ b/lib/filter/src/tb_fir_semi_parallel.vhd @@ -31,8 +31,8 @@ use work.PCK_FIO.all; ENTITY tb_fir_semi_parallel IS Generic ( - ntaps_per_stage : integer := 16; - nstages : integer := 4; + ntaps_per_stage : integer := 32; + nstages : integer := 2; nbits_in : integer := 32; nbits_in_frac : integer := 30; nbits_stages : integer := 32; @@ -48,6 +48,7 @@ ARCHITECTURE behavior OF tb_fir_semi_parallel IS --Constants constant PERIOD : time := 10 ns; constant nsamples : integer := 32; + constant M : integer := 2; --Inputs SIGNAL clk : std_logic := '0'; @@ -104,10 +105,10 @@ ARCHITECTURE behavior OF tb_fir_semi_parallel IS 0.0, 0.0, 0.0, + 1.0, + 0.0, 0.0, 0.0, - 0.9999, - -0.0000, 0.0, 0.0, 0.0, @@ -176,7 +177,8 @@ BEGIN tb : PROCESS file fi : file_t open read_mode is "wav_in.dat"; variable si : sample_t; - + variable remain : integer; + variable j : integer; BEGIN -- Wait 100 ns for global reset to finish @@ -193,43 +195,76 @@ BEGIN h_we <= '1'; end loop; wait until rising_edge(clk); - h_addr <= 0; - h_in <= to_sfixed(0.25, h_in); - h_we <= '1'; - wait until rising_edge(clk); +-- h_addr <= 0; +-- h_in <= to_sfixed(0.25, h_in); +-- h_we <= '1'; +-- wait until rising_edge(clk); h_we <= '0'; -- Write zeros - for i in 0 to ntaps_per_stage*nstages-1 loop + remain := ntaps_per_stage*nstages; + j := 0; + while remain /= 0 loop wait until rising_edge(clk) and rdy = '1'; - d_in <= to_sfixed(0.0, d_in); - din_vld <= '1'; + for i in 0 to M-1 loop + d_in <= to_sfixed(0.0, d_in); + din_vld <= '1'; + j := j + 1; + remain := remain - 1; + wait until rising_edge(clk); + end loop; + din_vld <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); start <= '1'; wait until rising_edge(clk); - din_vld <= '0'; start <= '0'; end loop; ------------------------------------------ -- Write data - for i in 0 to nsamples-1 loop + remain := nsamples; + j := 0; + while remain /= 0 loop wait until rising_edge(clk) and rdy = '1'; - d_in <= to_sfixed(x_input(i), d_in); - din_vld <= '1'; + for i in 0 to M-1 loop + d_in <= to_sfixed(x_input(j), d_in); + din_vld <= '1'; + j := j + 1; + remain := remain - 1; + wait until rising_edge(clk); + end loop; + din_vld <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); start <= '1'; wait until rising_edge(clk); - din_vld <= '0'; start <= '0'; end loop; -- Write zeros - for i in 0 to 99 loop + remain := 100; + j := 0; + while remain /= 0 loop wait until rising_edge(clk) and rdy = '1'; - d_in <= to_sfixed(0.0, d_in); - din_vld <= '1'; + for i in 0 to M-1 loop + d_in <= to_sfixed(0.0, d_in); + din_vld <= '1'; + j := j + 1; + remain := remain - 1; + wait until rising_edge(clk); + end loop; + din_vld <= '0'; +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); +-- wait until rising_edge(clk); start <= '1'; wait until rising_edge(clk); - din_vld <= '0'; start <= '0'; end loop;