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
