| 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 |