summaryrefslogtreecommitdiff
path: root/shifter.v
blob: ed4eaa6d512a03cbbfba50417a78ffb0bc65abbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module shifter (
	input [15:0] v,      // number to shift
	input [15:0] by,     // bits to shift by
	input dir,           // 0 = left shift, 1 = right shift
	input [1:0] extend,  // 0 = zero extend, 1 = one extend, 2 = sign extend (or last bit), 3 = barrel shift
	output [15:0] result
);

	wire [31:0] x;
	wire [15:0] extension;
	wire [31:0] xshift;

	assign extension =
		extend == 2'b11 ? v :
		extend == 2'b10 ? {16{v[dir == 1'b0 ? 0 : 15]}} :
		{16{extend[0]}};

	assign x      = dir == 1'b0 ? {v, extension} : {extension, v};
	assign xshift = dir == 1'b0 ? x << by[3:0]   : x >> by[3:0];

	assign result =
		|(by[15:4]) ? extension :
		dir == 1'b0 ? xshift[31:16] : xshift[15:0];
endmodule