module analyser ( input wire clk, reset, input wire data_ready, input wire [1:0] uwt_flag, input wire [11:0] uwt_data, input wire [11:0] threshold, output wire peak_ready, output wire [11:0] peak ); reg [1:0] state_reg, state_next; reg [3:0] counter_reg, counter_next; reg peak_ready_reg, peak_ready_next; reg [11:0] peak_reg, peak_next; reg [15:0] buffer [15:0]; wire [15:0] sample; wire [11:0] baseline; integer i; assign sample = {4'd0, uwt_data}; assign baseline = buffer[15][15:4]; always @(posedge clk) begin if (reset) begin state_reg <= 2'd0; counter_reg <= 4'd0; peak_ready_reg <= 1'b0; peak_reg <= 12'd0; for(i = 0; i <= 15; i = i + 1) begin buffer[i] <= 12'd0; end end else begin state_reg <= state_next; counter_reg <= counter_next; peak_ready_reg <= peak_ready_next; peak_reg <= peak_next; if (data_ready & uwt_flag[1]) begin for(i = 0; i < 15; i = i + 1) begin buffer[i+1] <= buffer[i] + sample; end buffer[0] <= sample; end end end always @* begin state_next = state_reg; counter_next = counter_reg; peak_ready_next = peak_ready_reg; peak_next = peak_reg; case (state_reg) 0: // skip first 16 samples begin peak_next = 12'd0; peak_ready_next = 1'b0; if (data_ready) begin counter_next = counter_reg + 4'd1; if (&counter_reg) begin state_next = 2'd1; end end end 1: // skip first 16 minima begin if (data_ready & uwt_flag[1]) begin counter_next = counter_reg + 4'd1; if (&counter_reg) begin state_next = 2'd2; end end end 2: // calculate peak height begin if (data_ready & uwt_flag[0]) begin peak_next = (uwt_data > baseline) ? (uwt_data - baseline) : 12'd0; peak_ready_next = (peak_next > threshold); end else begin peak_ready_next = 1'b0; end end default: begin peak_next = 12'd0; peak_ready_next = 1'b0; state_next = 2'd0; end endcase end assign peak_ready = peak_ready_reg; assign peak = peak_reg; endmodule