module uwt_bior31 #( parameter L = 1 // transform level ) ( input wire clk, reset, input wire data_ready, input wire [31:0] x, output wire [31:0] d, output wire [31:0] a, output wire [31: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 = 32'h80000000; // Tapped delay line reg [31:0] tap [index3:0]; reg [31:0] d_reg, d_next; reg [31:0] a_reg, a_next; reg [31:0] peak_reg, peak_next; reg [31:0] tmp1_reg, tmp1_next; reg [31:0] tmp2_reg, tmp2_next; reg less_reg, less_next; reg more_reg, more_next; reg [1:0] flag_reg; integer i; always @(posedge clk) begin if (reset) begin d_reg <= 0; a_reg <= 0; peak_reg <= 0; flag_reg <= 0; tmp1_reg <= 0; tmp2_reg <= 0; less_reg <= 1'b0; more_reg <= 1'b0; for(i = 0; i <= index3; i = i + 1) begin tap[i] <= 0; end end else if (data_ready) 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[0] <= (more_reg) & (~more_next); flag_reg[1] <= (less_reg) & (~less_next); // Tapped delay line: shift one for(i = 0; i < index3; i = i + 1) begin tap[i+1] <= tap[i]; end // Input in register 0 tap[0] <= x; end end always @* begin // Compute d and a with the filter coefficients. // The coefficients are [1, 3, -3, -1] and [1, 3, 3, 1] tmp1_next = tap[index3] + {tap[index2][30:0], 1'b0} + tap[index2]; tmp2_next = {tap[index1][30:0], 1'b0} + tap[index1] + tap[0]; d_next = zero - tmp1_reg + tmp2_reg; a_next = tmp1_reg + tmp2_reg; more_next = (d_reg > zero); less_next = (d_reg < zero); /* d_next = zero - (tap[index3]) - (tap[index2] << 1) - tap[index2] + (tap[index1] << 1) + tap[index1] + (tap[0]); a_next = (tap[index3]) + {tap[index2] << 1} + tap[index2] + (tap[index1] << 1) + tap[index1] + (tap[0]); */ peak_next = (tap[peak_index] >> peak_shift); end // output logic assign d = d_reg; assign a = a_reg; assign peak = peak_reg; assign flag = flag_reg; endmodule