module amplitude #( parameter width = 12 // bit width of the input data ) ( input wire clock, frame, reset, input wire [width-1:0] min_data, input wire [width-1:0] max_data, input wire [width-1:0] inp_data, output wire [width-1:0] out_data, output wire [1:0] out_flag ); reg int_case_reg, int_case_next; reg out_flag_reg, out_flag_next; reg int_flag_reg, int_flag_next; reg [width-1:0] int_mini_reg, int_mini_next; reg [width-1:0] out_data_reg, out_data_next; reg [width-1:0] inp_data_reg [1:0], inp_data_next [1:0]; wire int_comp_wire; reg int_comp_reg, int_comp_next; reg [5:0] int_cntr_reg, int_cntr_next; assign int_comp_wire = (inp_data_reg[1] < inp_data); always @(posedge clock) begin if (reset) begin int_case_reg <= 1'b0; int_mini_reg <= {(width){1'b0}}; inp_data_reg[0] <= {(width){1'b0}}; inp_data_reg[1] <= {(width){1'b0}}; out_data_reg <= {(width){1'b0}}; out_flag_reg <= 1'b0; int_flag_reg <= 1'b0; int_comp_reg <= 1'b0; int_cntr_reg <= 6'd0; end else begin int_case_reg <= int_case_next; int_mini_reg <= int_mini_next; inp_data_reg[0] <= inp_data_next[0]; inp_data_reg[1] <= inp_data_next[1]; out_data_reg <= out_data_next; out_flag_reg <= out_flag_next; int_flag_reg <= int_flag_next; int_comp_reg <= int_comp_next; int_cntr_reg <= int_cntr_next; end end always @* begin int_case_next = int_case_reg; int_mini_next = int_mini_reg; inp_data_next[0] = inp_data_reg[0]; inp_data_next[1] = inp_data_reg[1]; out_data_next = out_data_reg; out_flag_next = out_flag_reg; int_flag_next = int_flag_reg; int_comp_next = int_comp_reg; int_cntr_next = int_cntr_reg; case (int_case_reg) 0: begin if (frame) begin inp_data_next[0] = inp_data; inp_data_next[1] = inp_data_reg[0]; int_comp_next = int_comp_wire; out_data_next = {(width){1'b0}}; out_flag_next = 1'b0; // minimum if ((~int_comp_reg) & (int_comp_wire) & int_cntr_reg[5]) begin int_mini_next = inp_data_reg[0]; int_flag_next = 1'b1; end // maximum after minimum else if ((int_comp_reg) & (~int_comp_wire) & (int_flag_reg)) begin out_data_next = inp_data_reg[0] - int_mini_reg; int_flag_next = 1'b0; int_case_next = 1'b1; end else if (~int_cntr_reg[5]) begin int_cntr_next = int_cntr_reg + 6'd1; end end end 1: begin if (out_data_reg > min_data) begin int_cntr_next = 6'b0; // out_flag_next = 1'b1; out_flag_next = (inp_data_reg[1] < max_data); end int_case_next = 1'b0; end endcase end assign out_data = out_data_reg; assign out_flag = {~int_cntr_reg[5], out_flag_reg}; endmodule