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 into two different cycles.
  • Loading branch information
guilhermerc committed Mar 28, 2024
1 parent 4e6bc2d commit d62d31d
Showing 1 changed file with 47 additions and 22 deletions.
69 changes: 47 additions & 22 deletions modules/common/biquad/biquad.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ 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;
-- Signals to hold full precision operations' results
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 +107,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 +182,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 d62d31d

Please sign in to comment.