mirror of
https://github.com/trcwm/Speech256.git
synced 2025-06-07 16:48:32 +02:00
Fix bugs in the filter engine FSM. Verified correct behaviour with a 2nd order section.
This commit is contained in:
parent
541fb228ed
commit
cf89706963
@ -44,8 +44,8 @@ module FILTER (
|
|||||||
|
|
||||||
//////////// internal signals //////////
|
//////////// internal signals //////////
|
||||||
reg signed [9:0] coefmem [0:11]; // coefficient memory / shift register
|
reg signed [9:0] coefmem [0:11]; // coefficient memory / shift register
|
||||||
reg signed [15:0] state1 [0:11]; // state 1 memory / shift register
|
reg signed [15:0] state1 [0:5]; // state 1 memory / shift register
|
||||||
reg signed [15:0] state2 [0:11]; // state 2 memory / shift register
|
reg signed [15:0] state2 [0:5]; // state 2 memory / shift register
|
||||||
reg signed [15:0] accu; // accumulator
|
reg signed [15:0] accu; // accumulator
|
||||||
|
|
||||||
reg mul_start;
|
reg mul_start;
|
||||||
@ -55,6 +55,7 @@ module FILTER (
|
|||||||
reg update_states;
|
reg update_states;
|
||||||
reg update_coeffs;
|
reg update_coeffs;
|
||||||
reg [3:0] cur_state;
|
reg [3:0] cur_state;
|
||||||
|
reg unsigned [2:0] section;
|
||||||
|
|
||||||
wire mul_done;
|
wire mul_done;
|
||||||
wire signed [15:0] mul_result, accu_in, mul_in;
|
wire signed [15:0] mul_result, accu_in, mul_in;
|
||||||
@ -74,8 +75,8 @@ module FILTER (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// signal input mux for multipliers
|
// signal input mux for multipliers
|
||||||
assign mul_in = (state_sel) ? state1[11] : state2[11];
|
assign mul_in = (state_sel) ? state2[5] : state1[5];
|
||||||
assign accu_in = (accu_sel) ? sig_in : accu;
|
assign accu_in = (accu_sel) ? accu : sig_in;
|
||||||
assign mul_coeff = coefmem[11];
|
assign mul_coeff = coefmem[11];
|
||||||
assign sig_out = accu;
|
assign sig_out = accu;
|
||||||
|
|
||||||
@ -86,10 +87,13 @@ module FILTER (
|
|||||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
// reset cycle here ..
|
// reset cycle here ..
|
||||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
for(i=0; i<12; i=i+1)
|
for(i=0; i<6; i=i+1)
|
||||||
begin
|
begin
|
||||||
state1[i] <= 0;
|
state1[i] <= 0;
|
||||||
state2[i] <= 0;
|
state2[i] <= 0;
|
||||||
|
end
|
||||||
|
for(i=0; i<12; i=i+1)
|
||||||
|
begin
|
||||||
coefmem[i] <= 0;
|
coefmem[i] <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -104,6 +108,7 @@ module FILTER (
|
|||||||
mul_start <= 0;
|
mul_start <= 0;
|
||||||
cur_state <= 4'b0000;
|
cur_state <= 4'b0000;
|
||||||
done <= 0;
|
done <= 0;
|
||||||
|
section <= 0;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -114,13 +119,13 @@ module FILTER (
|
|||||||
// update the filter states if necessary
|
// update the filter states if necessary
|
||||||
if (update_states == 1)
|
if (update_states == 1)
|
||||||
begin
|
begin
|
||||||
for(i=1; i<12; i=i+1)
|
for(i=1; i<6; i=i+1)
|
||||||
begin
|
begin
|
||||||
state1[i] <= state1[i-1];
|
state1[i] <= state1[i-1];
|
||||||
state2[i] <= state2[i-1];
|
state2[i] <= state2[i-1];
|
||||||
end
|
end
|
||||||
state1[0] <= accu;
|
state1[0] <= accu;
|
||||||
state2[0] <= state1[11];
|
state2[0] <= state1[5];
|
||||||
end
|
end
|
||||||
|
|
||||||
// update the coefficients if necessary
|
// update the coefficients if necessary
|
||||||
@ -135,7 +140,7 @@ module FILTER (
|
|||||||
if (coef_load == 1)
|
if (coef_load == 1)
|
||||||
begin
|
begin
|
||||||
coefmem[0] <= coef_in;
|
coefmem[0] <= coef_in;
|
||||||
$display("Loaded coefficient: coefmem[0] = %x", coef_in);
|
//$display("Loaded coefficient: coefmem[0] = %xh", coef_in);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
coefmem[0] <= coefmem[11];
|
coefmem[0] <= coefmem[11];
|
||||||
@ -163,9 +168,10 @@ module FILTER (
|
|||||||
4'b0000: // IDLE state
|
4'b0000: // IDLE state
|
||||||
begin
|
begin
|
||||||
done <= 1;
|
done <= 1;
|
||||||
|
section <= 0;
|
||||||
if (start == 1)
|
if (start == 1)
|
||||||
begin
|
begin
|
||||||
// // state1 * coeff[0]
|
// state1 * coeff[0]
|
||||||
state_sel <= 0; // state 1 as mul input
|
state_sel <= 0; // state 1 as mul input
|
||||||
mul_start <= 1; // trigger multiplier
|
mul_start <= 1; // trigger multiplier
|
||||||
cur_state <= 4'b0001;
|
cur_state <= 4'b0001;
|
||||||
@ -175,18 +181,23 @@ module FILTER (
|
|||||||
// to reach a valid state
|
// to reach a valid state
|
||||||
begin
|
begin
|
||||||
cur_state <= 4'b0010;
|
cur_state <= 4'b0010;
|
||||||
|
//for(i=0; i<6; i=i+1)
|
||||||
|
//begin
|
||||||
|
// $display("s1[%d] = %x", i, state1[i]);
|
||||||
|
// $display("s2[%d] = %x", i, state2[i]);
|
||||||
|
//end
|
||||||
end
|
end
|
||||||
4'b0010: // wait for multiplier to complete
|
4'b0010: // wait for multiplier to complete
|
||||||
begin
|
begin
|
||||||
if (mul_done == 1)
|
if (mul_done == 1)
|
||||||
begin
|
begin
|
||||||
cur_state <= 4'b0011;
|
cur_state <= 4'b0011;
|
||||||
end
|
|
||||||
end
|
|
||||||
4'b0011: // update accu
|
|
||||||
begin
|
|
||||||
accu_sel <= 0; // accu = sig_in + mul_result
|
accu_sel <= 0; // accu = sig_in + mul_result
|
||||||
do_accu <= 1;
|
do_accu <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
4'b0011: // update accu, 1st section only!
|
||||||
|
begin
|
||||||
cur_state <= 4'b0100;
|
cur_state <= 4'b0100;
|
||||||
update_coeffs <= 1; // advance to coeff[1]
|
update_coeffs <= 1; // advance to coeff[1]
|
||||||
end
|
end
|
||||||
@ -205,20 +216,48 @@ module FILTER (
|
|||||||
begin
|
begin
|
||||||
if (mul_done == 1)
|
if (mul_done == 1)
|
||||||
begin
|
begin
|
||||||
|
section <= section + 4'b001; // increment section number
|
||||||
cur_state <= 4'b0111;
|
cur_state <= 4'b0111;
|
||||||
|
accu_sel <= 1; // accu = accu + mul_result
|
||||||
|
do_accu <= 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
4'b0111: // update accumulator and filter states
|
4'b0111: // update accumulator and filter states
|
||||||
begin
|
begin
|
||||||
accu_sel <= 1; // accu = accu + mul_result
|
|
||||||
do_accu <= 1;
|
|
||||||
update_coeffs <= 1; // advance to next section..
|
update_coeffs <= 1; // advance to next section..
|
||||||
update_states <= 1;
|
update_states <= 1;
|
||||||
cur_state <= 4'b0000;
|
|
||||||
|
// check if this is the last section..
|
||||||
|
if (section==4'b0110)
|
||||||
|
cur_state <= 4'b0000; // one complete filter set done..
|
||||||
|
else
|
||||||
|
cur_state <= 4'b1000; // next..
|
||||||
end
|
end
|
||||||
4'b1000: // stop, for now ..
|
4'b1000:
|
||||||
begin
|
begin
|
||||||
done <= 1;
|
// next section: state1 * coeff[0]
|
||||||
|
cur_state <= 4'b1001;
|
||||||
|
state_sel <= 0; // state 1 as mul input
|
||||||
|
mul_start <= 1; // trigger multiplier
|
||||||
|
end
|
||||||
|
4'b1001: // Dummy cycle to wait for mul_done
|
||||||
|
// to reach a valid state
|
||||||
|
begin
|
||||||
|
cur_state <= 4'b1010;
|
||||||
|
end
|
||||||
|
4'b1010: // wait for multiplier to complete
|
||||||
|
begin
|
||||||
|
if (mul_done == 1)
|
||||||
|
begin
|
||||||
|
cur_state <= 4'b1011;
|
||||||
|
accu_sel <= 1; // accu = accu + mul_result
|
||||||
|
do_accu <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
4'b1011: // update accu, 2nd..5th section only!
|
||||||
|
begin
|
||||||
|
update_coeffs <= 1; // advance to coeff[1]
|
||||||
|
cur_state <= 4'b0100;
|
||||||
end
|
end
|
||||||
default:
|
default:
|
||||||
cur_state <= 4'b0000;
|
cur_state <= 4'b0000;
|
||||||
|
@ -34,32 +34,59 @@ module FILTER_TB;
|
|||||||
rst_an = 0;
|
rst_an = 0;
|
||||||
|
|
||||||
sig_in = 16'h0100;
|
sig_in = 16'h0100;
|
||||||
coef_in = 10'h000; // sign-magnitude
|
coef_in = 0;
|
||||||
coef_load = 0;
|
coef_load = 0;
|
||||||
start = 0;
|
start = 0;
|
||||||
check_finish = 0;
|
check_finish = 0;
|
||||||
|
|
||||||
#10
|
#10
|
||||||
rst_an = 1;
|
rst_an = 1;
|
||||||
#10
|
|
||||||
coef_load = 1;
|
|
||||||
coef_in = 10'h21F; // sign-magnitude
|
|
||||||
|
|
||||||
// load all the coefficients
|
// load all the coefficients
|
||||||
for(i=1; i<12; i=i+1)
|
|
||||||
begin
|
|
||||||
#10
|
#10
|
||||||
coef_load = 1;
|
coef_load = 1;
|
||||||
coef_in = 10'h00F; // sign-magnitude
|
// section 1
|
||||||
end
|
coef_in = {1'b0, 9'd128}; // sign-magnitude a1 = -0.25
|
||||||
|
#10
|
||||||
|
coef_in = {1'b1, 9'd256}; // sign-magnitude a2 = 0.5
|
||||||
|
#10
|
||||||
|
// section 2
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
// section 3
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
// section 4
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
// section 5
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
// section 6
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
|
#10
|
||||||
|
coef_in = {1'b0, 9'd0}; // sign-magnitude a1 = 0;
|
||||||
#10
|
#10
|
||||||
coef_load = 0;
|
coef_load = 0;
|
||||||
#10
|
|
||||||
start = 1;
|
start = 1;
|
||||||
#50000;
|
#50000;
|
||||||
check_finish = 1;
|
check_finish = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
always@(posedge clk)
|
||||||
|
begin
|
||||||
|
if ((done == 1) && (coef_load != 1))
|
||||||
|
$display("%d", sig_out);
|
||||||
|
end
|
||||||
|
|
||||||
always
|
always
|
||||||
#5 clk = !clk;
|
#5 clk = !clk;
|
||||||
|
|
||||||
|
34
verilog/filter/results.md
Normal file
34
verilog/filter/results.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Results
|
||||||
|
|
||||||
|
The testbench should approximately give the following step response results:
|
||||||
|
|
||||||
|
(leading zeroes are okay)
|
||||||
|
- 256
|
||||||
|
- 320
|
||||||
|
- 208
|
||||||
|
- 148
|
||||||
|
- 189
|
||||||
|
- 229
|
||||||
|
- 219
|
||||||
|
- 196
|
||||||
|
- 196
|
||||||
|
- 207
|
||||||
|
- 210
|
||||||
|
- 205
|
||||||
|
- 202
|
||||||
|
- 204
|
||||||
|
- 206
|
||||||
|
- 205
|
||||||
|
- 204
|
||||||
|
- 204
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
- 205
|
||||||
|
|
||||||
|
Note that there might be a few +/- 1 round-off errors.
|
@ -141,10 +141,11 @@ module SPMUL (
|
|||||||
begin
|
begin
|
||||||
domul <= 0;
|
domul <= 0;
|
||||||
done <= 1;
|
done <= 1;
|
||||||
|
// correct for the coeff sign bit
|
||||||
if (coefreg[9] == 0)
|
if (coefreg[9] == 0)
|
||||||
result_out <= {1'b0, accumulator[23:9]};
|
result_out <= {1'b0, accumulator[23:9]};
|
||||||
else
|
else
|
||||||
result_out <= {1'b1, ~accumulator[23:9]};
|
result_out <= {1'b1, ~accumulator[23:9]} + 1;
|
||||||
state <= 0;
|
state <= 0;
|
||||||
end
|
end
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user