module uwt_bior31 #( parameter L = 1 // transform level ) ( input wire clock, frame, reset, input wire [23:0] x, output wire [23:0] d, output wire [23:0] a, output wire [23:0] peak, output wire [1:0] flag ); localparam index1 = 1 << (L - 1); localparam index2 = 2 << (L - 1); localparam index3 = 3 << (L - 1); localparam peak_index = ((index3 + 1) >> 1) + 1; localparam peak_shift = ((L - 1) << 1) + (L - 1); localparam zero = 24'h800000; // Tapped delay line reg [23:0] tap_reg [index3:0]; reg [23:0] tap_next [index3:0]; reg [23:0] d_reg, d_next; reg [23:0] a_reg, a_next; reg [23:0] peak_reg, peak_next; reg [23:0] tmp1_reg, tmp1_next; reg [23:0] tmp2_reg, tmp2_next; reg less_reg, less_next; reg more_reg, more_next; reg [1:0] flag_reg, flag_next; reg int_case_reg, int_case_next; integer i; always @(posedge clock) begin if (reset) begin d_reg <= 0; a_reg <= 0; peak_reg <= 0; tmp1_reg <= 0; tmp2_reg <= 0; less_reg <= 1'b0; more_reg <= 1'b0; flag_reg <= 0; int_case_reg <= 1'b0; for(i = 0; i <= index3; i = i + 1) begin tap_reg[i] <= 0; end end else begin d_reg <= d_next; a_reg <= a_next; peak_reg <= peak_next; tmp1_reg <= tmp1_next; tmp2_reg <= tmp2_next; less_reg <= less_next; more_reg <= more_next; flag_reg <= flag_next; int_case_reg <= int_case_next; for(i = 0; i <= index3; i = i + 1) begin tap_reg[i] <= tap_next[i]; end end end always @* begin d_next = d_reg; a_next = a_reg; peak_next = peak_reg; tmp1_next = tmp1_reg; tmp2_next = tmp2_reg; less_next = less_reg; more_next = more_reg; flag_next = flag_reg; int_case_next = int_case_reg; for(i = 0; i <= index3; i = i + 1) begin tap_next[i] = tap_reg[i]; end case (int_case_reg) 0: begin if (frame) begin // Tapped delay line: shift one for(i = 0; i < index3; i = i + 1) begin tap_next[i+1] = tap_reg[i]; end // Input in register 0 tap_next[0] = x; tmp1_next = tap_reg[index3] + {tap_reg[index2][22:0], 1'b0} + tap_reg[index2]; tmp2_next = {tap_reg[index1][22:0], 1'b0} + tap_reg[index1] + tap_reg[0]; more_next = (d_reg > zero); less_next = (d_reg < zero); flag_next[0] = (less_reg) & (~less_next); flag_next[1] = (more_reg) & (~more_next); peak_next = (tap_reg[peak_index] >> peak_shift); int_case_next = 1'b1; end end 1: begin // Compute d and a with the filter coefficients. // The coefficients are [1, 3, -3, -1] and [1, 3, 3, 1] d_next = zero - tmp1_reg + tmp2_reg; a_next = tmp1_reg + tmp2_reg; int_case_next = 1'b0; end endcase end // output logic assign d = d_reg; assign a = a_reg; assign peak = peak_reg; assign flag = flag_reg; endmodule