239 lines
4.5 KiB
Verilog
239 lines
4.5 KiB
Verilog
module iir (clk, reset, start, din, params, dout, ready,iir_start,iir_done);
|
|
input clk, reset, start;
|
|
input [7:0] din;
|
|
input [15:0] params;
|
|
output [7:0] dout;
|
|
reg [7:0] dout;
|
|
output ready;
|
|
reg ready;
|
|
reg temp_ready;
|
|
reg [6:0] finite_counter;
|
|
wire count0;
|
|
input iir_start;
|
|
output iir_done;
|
|
wire iir_done;
|
|
reg del_count0;
|
|
|
|
reg [15:0] a1, a2, b0, b1, b2, yk1, yk2;
|
|
reg [7:0] uk, uk1, uk2 ;
|
|
reg [28:0] ysum ;
|
|
reg [26:0] yk ;
|
|
reg [22:0] utmp;
|
|
reg [3:0] wait_counter ;
|
|
// temporary variable
|
|
wire [31:0] yo1, yo2;
|
|
//wire [23:0] b0t, b1t, b2t;
|
|
wire [22:0] b0t, b1t, b2t;
|
|
wire [22:0] b0tpaj, b1tpaj, b2tpaj;
|
|
|
|
reg [3:0] obf_state, obf_next_state ;
|
|
|
|
reg [7:0] temp_uk, temp_uk1, temp_uk2 ;
|
|
reg [15:0] temp_a1, temp_a2, temp_b0, temp_b1, temp_b2, temp_yk1, temp_yk2;
|
|
reg [28:0] temp_ysum ;
|
|
reg [26:0] temp_yk ;
|
|
reg [22:0] temp_utmp;
|
|
reg [7:0] temp_dout;
|
|
reg [3:0] temp_wait_counter ;
|
|
|
|
parameter
|
|
idle = 4'b0001 ,
|
|
load_a2 = 4'b0010 ,
|
|
load_b0 = 4'b0011 ,
|
|
load_b1 = 4'b0100 ,
|
|
load_b2 = 4'b0101 ,
|
|
wait4_start = 4'b0110 ,
|
|
latch_din = 4'b0111 ,
|
|
compute_a = 4'b1000 ,
|
|
compute_b = 4'b1001 ,
|
|
compute_yk = 4'b1010 ,
|
|
wait4_count = 4'b1011 ,
|
|
latch_dout = 4'b1100 ;
|
|
|
|
always @(obf_state or start or din or wait_counter or iir_start or count0)
|
|
begin
|
|
case (obf_state )
|
|
idle :
|
|
begin
|
|
if (iir_start)
|
|
obf_next_state = load_a2 ;
|
|
else
|
|
obf_next_state = idle;
|
|
temp_a1 = params ;
|
|
end
|
|
load_a2 :
|
|
begin
|
|
obf_next_state = load_b0 ;
|
|
temp_a2 = params ;
|
|
end
|
|
load_b0 :
|
|
begin
|
|
obf_next_state = load_b1 ;
|
|
temp_b0 = params ;
|
|
end
|
|
load_b1 :
|
|
begin
|
|
obf_next_state = load_b2 ;
|
|
temp_b1 = params ;
|
|
end
|
|
load_b2 :
|
|
begin
|
|
obf_next_state = wait4_start ;
|
|
temp_b2 = params ;
|
|
end
|
|
wait4_start :
|
|
begin
|
|
if (start)
|
|
begin
|
|
obf_next_state = latch_din ;
|
|
temp_uk = din ;
|
|
end
|
|
else
|
|
begin
|
|
obf_next_state = wait4_start ;
|
|
temp_uk = uk;
|
|
end
|
|
temp_ready = wait4_start;
|
|
end
|
|
latch_din :
|
|
begin
|
|
obf_next_state = compute_a ;
|
|
end
|
|
compute_a :
|
|
begin
|
|
obf_next_state = compute_b ;
|
|
|
|
temp_ysum = yo1[31:3] + yo2[31:3];
|
|
end
|
|
compute_b :
|
|
begin
|
|
obf_next_state = compute_yk ;
|
|
|
|
// temp_utmp = b0t[23:0] + b1t[23:0] + b2t[23:0];
|
|
temp_utmp = b0t + b1t + b2t;
|
|
end
|
|
compute_yk :
|
|
begin
|
|
obf_next_state = wait4_count ;
|
|
temp_uk1 = uk ;
|
|
temp_uk2 = uk1 ;
|
|
temp_yk = ysum[26:0] + {utmp[22], utmp[22], utmp[22], utmp[22], utmp};
|
|
temp_wait_counter = 4 ;
|
|
end
|
|
|
|
wait4_count :
|
|
begin
|
|
if (wait_counter==0 )
|
|
begin
|
|
obf_next_state = latch_dout ;
|
|
|
|
temp_dout = yk[26:19];
|
|
temp_yk1 = yk[26:11] ;
|
|
temp_yk2 = yk1 ;
|
|
end
|
|
else
|
|
begin
|
|
obf_next_state = wait4_count ;
|
|
temp_dout = dout;
|
|
temp_yk1 = yk1;
|
|
//temp_yk2 = yk2;
|
|
end
|
|
|
|
temp_wait_counter = wait_counter - 1;
|
|
end
|
|
latch_dout :
|
|
if (count0)
|
|
obf_next_state = idle;
|
|
else
|
|
obf_next_state = wait4_start ;
|
|
endcase
|
|
end
|
|
|
|
|
|
|
|
//assign yo1 = mul_tc_16_16(yk1, a1, clk);
|
|
assign yo1 = yk1 * a1;
|
|
//assign yo2 = mul_tc_16_16(yk2, a2, clk);
|
|
assign yo2 = yk2*a2;
|
|
//assign b0t = mul_tc_8_16(uk, b0, clk);
|
|
//assign b1t = mul_tc_8_16(uk1, b1, clk);
|
|
//assign b2t = mul_tc_8_16(uk2, b2, clk);
|
|
assign b0t = uk*b0;
|
|
assign b1t = uk1*b1;
|
|
assign b2t = uk2*b2;
|
|
// paj added to solve unused high order bit
|
|
assign b0tpaj = b0t;
|
|
assign b1tpaj = b1t;
|
|
assign b2tpaj = b2t;
|
|
|
|
// A COEFFICENTS
|
|
always @(posedge clk or posedge reset) begin
|
|
if (reset ) begin
|
|
uk <= 0 ;
|
|
uk1 <= 0 ;
|
|
uk2 <= 0 ;
|
|
yk1 <= 0 ;
|
|
yk2 <= 0 ;
|
|
yk <= 0 ;
|
|
ysum <= 0 ;
|
|
utmp <= 0 ;
|
|
a1 <= 0 ;
|
|
a2 <= 0 ;
|
|
b0 <= 0 ;
|
|
b1 <= 0 ;
|
|
b2 <= 0 ;
|
|
dout <= 0 ;
|
|
obf_state <= idle ;
|
|
ready <= 0;
|
|
end
|
|
else begin
|
|
obf_state <= obf_next_state ;
|
|
uk1 <= temp_uk1;
|
|
uk2 <= temp_uk2;
|
|
yk <= temp_yk;
|
|
uk <= temp_uk ;
|
|
a1 <= temp_a1 ;
|
|
a2 <= temp_a2 ;
|
|
b0 <= temp_b0 ;
|
|
b1 <= temp_b1 ;
|
|
b2 <= temp_b2 ;
|
|
ysum <= temp_ysum;
|
|
utmp <= temp_utmp;
|
|
dout <= temp_dout;
|
|
yk1 <= temp_yk1;
|
|
yk2 <= temp_yk2;
|
|
ready <= temp_ready;
|
|
end
|
|
end
|
|
|
|
// wait counter, count 4 clock after sum is calculated, to
|
|
// time outputs are ready, and filter is ready to accept next
|
|
// input
|
|
always @(posedge clk or posedge reset ) begin
|
|
if (reset )
|
|
wait_counter <= 0 ;
|
|
else begin
|
|
wait_counter <= temp_wait_counter ;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (reset)
|
|
finite_counter<=100;
|
|
else
|
|
if (iir_start)
|
|
finite_counter<=finite_counter -1;
|
|
else
|
|
finite_counter<=finite_counter;
|
|
end
|
|
|
|
assign count0=finite_counter==7'b0;
|
|
|
|
always @(posedge clk) begin
|
|
del_count0 <= count0;
|
|
end
|
|
|
|
assign iir_done = (count0 && ~del_count0);
|
|
|
|
endmodule
|