From d4e13eb27286b4e750176666bd5725bc5cc7dd2e Mon Sep 17 00:00:00 2001 From: Brian Woods Date: Wed, 12 Apr 2023 14:29:21 -0400 Subject: fir_filter: wip V2 Added a rough state machine to control the parts of the filter --- fir_filter/fir_filter.vhd | 80 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 7 deletions(-) diff --git a/fir_filter/fir_filter.vhd b/fir_filter/fir_filter.vhd index 429b09a..63a39b7 100644 --- a/fir_filter/fir_filter.vhd +++ b/fir_filter/fir_filter.vhd @@ -42,6 +42,8 @@ architecture behav of fir_filter is signal mul0_sig_in: signed(data_width-1 downto 0); signal mul0_coef_in: signed(coef_width-1 downto 0); signal mul0_out: signed(data_width+coef_width-1 downto 0); + signal mul0_sel: integer (range 0 to coef_num); + signal mul0_en: std_logic; signal acc_sum: signed(data_width+overflow_width+fraction_width-1 downto 0); @@ -50,7 +52,70 @@ architecture behav of fir_filter is signal data_delay: array (0 to coef_num-1) of signed (data_width-1 downto 0); + + signal fir_shift: std_logic; + + signal FSM_states is (clear, waiting, processing) + signal state_cur, state_next: FSM_states; begin + -- state machine here + -- inputs: en, + -- outputs: mul0_sel, mul0_en + fsm_logic process (en, clk) + variable mul0_sel_prev -- TODO past value so we know + -- what's next + begin + -- TODO shift the FIR regs + case state_cur is + when clear => + state_next <= waiting; + mul0_sel <= 0; + mul0_en <= '0'; + ready <= '0'; + fir_shift <= '0'; + when waiting => + when proc_coef => + if mul0_sel='1' then + state_next <= ?; + else + state_next <= processing; + end if; + mul0_sel <= mul0_sel_prev - 1; + mul0_en <= '1'; + ready <= '0'; --TODO confirm + fir_shift <= '0'; + when proc_last => + if (en='1') then + state_next <= waiting; + mul0_sel <= 0; + mul0_en <= '1'; + ready <= '0'; + fir_shift <= '1'; + else + state_next <= proc_last; + mul0_sel <= 0; + mul0_en <= '0'; + ready <= '1'; + fir_shift <= '0'; + end if; + when others => + state_next <= clear; + mul0_sel <= 0; + mul0_en <= '0'; + ready <= '0'; + fir_shift <= '0'; + end case; + end process fsm_logic; + + fsm_reg: process (clk, clr) + begin + if (clr='1') then + state_cur <= clear; + elsif (clk'event and clk='1') then + state_cur <= state_next; + end if; + end process fsm_reg; + -- our one multipler -- output will be data_width + coef_width - coefs_offset . coefs_offset mul0_out <= mul0_sig_in * mul0_coef_in; @@ -68,7 +133,6 @@ begin end if; end process; - -- data_width + coef_width bit from multipler -- data_width = N -- coef_width = M @@ -78,14 +142,16 @@ begin -- fraction_width = K -- multi out = N + M - Moff . Moff - process ( TODO ) + process (mul0_sel, mul0_en) + variable N: integer (range 0 to coef_num); begin - if (save coef(N)) then + N := mul0_sel; + if (mul0_en) then mul0_sign_in <= signal_delay(N); mul0_coef_in <= coefs(N); acc_in <= resize(mul0_out(data_width+data_width-1 downto - coefs_offset(N)-fraction_width) + coefs_offset(N)-fraction_width), running_sum'length); acc_en <= '1'; else @@ -96,14 +162,14 @@ begin end if; end process; - -- cycle here just means increment the saved registers + -- fir_shift here just means increment the saved registers data_delay(0) <= input; -- no delay - process (clr, clk, cycle) + process (clr, clk) begin if (clr='1') then data_delay(1 to coef_num-1) <= (others (others => '0')); elsif (clk'event and clk='1') then - if (cycle='1') then + if (fir_shift='1') then data_delay(1 to coef_num-1) <= data_delay(0 to coef_num-2); end if; -- cgit v1.2.3