module shift #( parameter shift = 24, // right shift of the result parameter width = 27, // bit width of the input data parameter widthr = 12 // bit width of the output data ) ( input wire clock, frame, reset, input wire [5:0] amp_data, input wire [width-1:0] inp_data, output wire [widthr-1:0] out_data ); localparam widthp = width + 6; reg [5:0] amp_data_reg; reg [width-1:0] inp_data_reg; reg [widthr-1:0] out_data_reg; wire [widthr-1:0] out_data_wire; wire [widthp-1:0] mul_data_wire; assign out_data_wire = mul_data_wire[shift+widthr-1:shift] + {{(widthr-1){mul_data_wire[widthp-1]}}, mul_data_wire[shift-1]}; lpm_mult #( .lpm_hint("MAXIMIZE_SPEED=9"), .lpm_representation("UNSIGNED"), .lpm_type("LPM_MULT"), .lpm_pipeline(3), .lpm_widtha(width), .lpm_widthb(6), .lpm_widthp(widthp)) mult_unit ( .clock(clock), .clken(1'b1), .dataa(inp_data_reg), .datab(amp_data_reg), .result(mul_data_wire)); always @(posedge clock) begin if (reset) begin amp_data_reg <= 6'b0; inp_data_reg <= {(width){1'b0}}; out_data_reg <= {(widthr){1'b0}}; end else if (frame) begin amp_data_reg <= amp_data; inp_data_reg <= inp_data; out_data_reg <= out_data_wire; end end assign out_data = out_data_reg; endmodule