Skip to content

Commit

Permalink
biquad.vhd: multiply and resize in different cycles
Browse files Browse the repository at this point in the history
The long combinatorial logic to implement resize chained with DPS48s may make
timing closure difficult. So, break these operations in two different cycles.
  • Loading branch information
guilhermerc committed Mar 28, 2024
1 parent 25f90e6 commit 80ce66e
Showing 1 changed file with 46 additions and 22 deletions.
68 changes: 46 additions & 22 deletions modules/common/biquad/biquad.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ ARCHITECTURE behave OF biquad IS
-(g_COEFF_FRAC_WIDTH + g_X_FRAC_WIDTH + g_EXTRA_BITS)) :=
(OTHERS => '0');

SIGNAL state : NATURAL RANGE 0 TO 3 := 0;
SIGNAL b0_times_w_tmp, a1_times_w_d1_tmp, a2_times_w_d2_tmp,
b1_times_w_d1_tmp, b2_times_w_d2_tmp :
SFIXED((g_COEFF_INT_WIDTH + w'LEFT + 1)-1 DOWNTO
-g_COEFF_FRAC_WIDTH + w'RIGHT) := (OTHERS => '0');

SIGNAL state : NATURAL RANGE 0 TO 4 := 0;
BEGIN
PROCESS(clk_i) IS
BEGIN
Expand All @@ -101,50 +106,68 @@ BEGIN
b2_times_w_d2 <= (OTHERS => '0');
aux_a <= (OTHERS => '0');
aux_b <= (OTHERS => '0');
b0_times_w_tmp <= (OTHERS => '0');
a1_times_w_d1_tmp <= (OTHERS => '0');
a2_times_w_d2_tmp <= (OTHERS => '0');
b1_times_w_d1_tmp <= (OTHERS => '0');
b2_times_w_d2_tmp <= (OTHERS => '0');
state <= 0;
y_valid_o <= '0';
ELSE
y_valid_o <= '0';

CASE state IS
-- Computes: w[n] = x[n] - a1*w[n - 1] - a2*w[n - 2]
-- Computes: w[n] = x[n] - a1*w[n - 1] - a2*w[n - 2] (resized)
WHEN 0 =>
IF x_valid_i THEN
w <= resize(x_i + aux_a, w'LEFT, w'RIGHT);
state <= 1;
END IF;

-- Computes: b0*w[n]
-- w[n - 1] (for the next iteration)
-- w[n - 2] (for the next iteration)
-- Computes: b0*w[n] (full precision)
-- w[n - 1] for the next iteration
-- w[n - 2] for the next iteration
WHEN 1 =>
b0_times_w <= resize(coeffs_i.b0*w, b0_times_w'LEFT,
b0_times_w'RIGHT);
b0_times_w_tmp <= coeffs_i.b0*w;
w_d1 <= w;
w_d2 <= w_d1;
state <= 2;

-- Computes: y[n] = w[n] + b1*w[n - 1] + b2*w[n - 2]
-- a1*w[n - 1] (for the next iteration)
-- a2*w[n - 2] (for the next iteration)
-- b1*w[n - 1] (for the next iteration)
-- b2*w[n - 2] (for the next iteration)
-- Computes: b0*w[n] (resized)
-- a1*w[n - 1] for the next iteration (full precision)
-- a2*w[n - 2] for the next iteration (full precision)
-- b1*w[n - 1] for the next iteration (full precision)
-- b2*w[n - 2] for the next iteration (full precision)
WHEN 2 =>
y_o <= resize(b0_times_w + aux_b, y_o'LEFT, y_o'RIGHT);
y_valid_o <= '1';
a1_times_w_d1 <= resize(coeffs_i.a1*w_d1, a1_times_w_d1'LEFT,
b0_times_w <= resize(b0_times_w_tmp, b0_times_w'LEFT,
b0_times_w'RIGHT);
a1_times_w_d1_tmp <= coeffs_i.a1*w_d1;
a2_times_w_d2_tmp <= coeffs_i.a2*w_d2;
b1_times_w_d1_tmp <= coeffs_i.b1*w_d1;
b2_times_w_d2_tmp <= coeffs_i.b2*w_d2;
state <= 3;

-- Computes: a1*w[n - 1] for the next iteration (resized)
-- a2*w[n - 2] for the next iteration (resized)
-- b1*w[n - 1] for the next iteration (resized)
-- b2*w[n - 2] for the next iteration (resized)
-- y[n] = w[n] + b1*w[n - 1] + b2*w[n - 2] (resized)
WHEN 3 =>
a1_times_w_d1 <= resize(a1_times_w_d1_tmp, a1_times_w_d1'LEFT,
a1_times_w_d1'RIGHT);
a2_times_w_d2 <= resize(coeffs_i.a2*w_d2, a2_times_w_d2'LEFT,
a2_times_w_d2 <= resize(a2_times_w_d2_tmp, a2_times_w_d2'LEFT,
a2_times_w_d2'RIGHT);
b1_times_w_d1 <= resize(coeffs_i.b1*w_d1, b1_times_w_d1'LEFT,
b1_times_w_d1 <= resize(b1_times_w_d1_tmp, b1_times_w_d1'LEFT,
b1_times_w_d1'RIGHT);
b2_times_w_d2 <= resize(coeffs_i.b2*w_d2, b2_times_w_d2'LEFT,
b2_times_w_d2 <= resize(b2_times_w_d2_tmp, b2_times_w_d2'LEFT,
b2_times_w_d2'RIGHT);
state <= 3;
y_o <= resize(b0_times_w + aux_b, y_o'LEFT, y_o'RIGHT);
y_valid_o <= '1';
state <= 4;

-- Computes: -a1*w[n - 1] - a2*w[n - 2] (for the next iteration)
-- b1*w[n - 1] + b2*w[n - 2] (for the next iteration)
WHEN 3 =>
-- Computes: -a1*w[n - 1] - a2*w[n - 2] for the next iteration (resized)
-- b1*w[n - 1] + b2*w[n - 2] for the next iteration (resized)
WHEN 4 =>
aux_a <= resize(-a1_times_w_d1 - a2_times_w_d2, aux_a'LEFT,
aux_a'RIGHT);
aux_b <= resize(b1_times_w_d1 + b2_times_w_d2, aux_b'LEFT,
Expand All @@ -158,5 +181,6 @@ BEGIN
busy_o <= '1' WHEN (state = 0 AND x_valid_i = '1') ELSE
'1' WHEN state = 1 ELSE
'1' WHEN state = 2 ELSE
'1' WHEN state = 3 ELSE
'0';
END ARCHITECTURE behave;

0 comments on commit 80ce66e

Please sign in to comment.