OpenFPGA/openfpga_flow/benchmarks/quicklogic_tests/iir/rtl/iir.v

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