Download: barrel.zip
This is a behavioral version, using C operators for shifting
// behavioral version /* * control * 00 no operation * 01 logical shift left * 10 logical shift right * 11 arithmetic shift right */ module barrel1(in,out,shamt,control); input [31:0] in; output [31:0] out; input [4:0] shamt; input [1:0] control; reg [31:0] out; // we want se<<(32-shamt) // but se<<32 = se and -shamt = ~shamt + 1 (two's complement) // can do (se<<1) by setting lsb to zero: wire [31:0] se; assign se = {{31{in[31]}},1'b0}; always case (control) 2'b00: out <= in; 2'b01: out <= (in<<shamt); 2'b10: out <= (in>>shamt); 2'b11: out <= (in>>shamt)| (se<<~shamt); //out <= (in>>>shamt); default: out <= in; endcase endmodule
This version avoids duplicate constructions and uses a multiplexer to choose the final result.
// multiplexer version, still behavioral /* * control * 00 no operation * 01 logical shift left * 10 logical shift right * 11 arithmetic shift right */ module barrel2(in,out,shamt,control); input [31:0] in; output [31:0] out; input [4:0] shamt; input [1:0] control; reg [31:0] out; wire [31:0] out1,out2; assign out1 = (in<<shamt); assign out2 = (in>>shamt); wire [31:0] se; assign se = {{31{in[31]}},1'b0}; always case (control) 2'b00: out <= in; 2'b01: out <= out1; 2'b10: out <= out2; 2'b11: out <= out2 | (se<<~shamt); default: out <= in; endcase endmodule
This version uses a logarithmic (base 2) hierarchical structure.
// logarithmic shifter (base 2) /* * control * 00 nop no operation * 01 sll shift left logical * 10 srl shift right logical * 11 sra shift right arithmetic */ module barrel(inp,control,shift,out); input [31:0] inp; input [1:0] control; input [4:0] shift; output [31:0] out; reg [31:0] bit4,bit3,bit2,bit1,out; parameter nop = 2'b00, sll = 2'b01, srl = 2'b10, sra = 2'b11; // bit 4 (16) always if (shift[4]) case (control) nop: bit4 = inp; sll: bit4 = {inp[15:0],16'h0000}; srl: bit4 = {8'h0000,inp[31:16]}; sra: bit4 = {(inp[31]? 16'hFFFF: 16'h0000),inp[31:16]}; endcase else bit4=inp; // bit 3 (8) always if (shift[3]) case (control) nop: bit3 = bit4; sll: bit3 = {bit4[23:0],8'h00}; srl: bit3 = {8'h00,bit4[31:8]}; sra: bit3 = {(bit4[31]? 8'hFF: 8'h00),bit4[31:8]}; endcase else bit3 = bit4; // bit 2 (4) always if (shift[2]) case (control) nop: bit2 = bit3; sll: bit2 = {bit3[27:0],4'b0000}; srl: bit2 = {4'b0000,inp[31:4]}; sra: bit2 = {(bit3[31]? 4'b1111: 4'b0000),bit3[31:4]}; endcase else bit2 = bit3; // bit 1 (2) always if (shift[1]) case (control) nop: bit1 = bit2; sll: bit1 = {bit2[29:0],2'b00}; srl: bit1 = {2'b00,bit2[31:2]}; sra: bit1 = {(bit2[31]? sra: 2'b00),bit2[31:2]}; endcase else bit1 = bit2; // bit 0 (1) always if (shift[0]) case (control) nop: out = bit1; sll: out = {bit1[30:0],1'b0}; srl: out = {1'b0,bit1[31:1]}; sra: out = {bit1[31],bit1[31:1]}; endcase else out = bit1; endmodule
This is our final version, with bit-rotation
/* * control * 000 sll shift left logical * 001 srl shift right logical * 011 sra shift right arithmetic * 100 rol rotate left * 101 ror rotate right */ module barrel(inp,control,shift,out); input [31:0] inp; input [2:0] control; input [4:0] shift; output [31:0] out; reg [31:0] bit4,bit3,bit2,bit1,out; parameter sll = 3'b000, srl = 3'b001, sra = 3'b011, rol = 3'b100, ror = 3'b101; // bit 4 (16) always if (shift[4]) case (control) sll: bit4 = {inp[15:0],16'h0000}; srl: bit4 = {16'h0000,inp[31:16]}; sra: bit4 = {(inp[31]? 16'hFFFF: 16'h0000),inp[31:16]}; rol: bit4 = {inp[15:0],inp[31:16]}; ror: bit4 = {inp[15:0],inp[31:16]}; default: bit4 = inp; endcase else bit4=inp; // bit 3 (8) always if (shift[3]) case (control) sll: bit3 = {bit4[23:0],8'h00}; srl: bit3 = {8'h00,bit4[31:8]}; sra: bit3 = {(bit4[31]? 8'hFF: 8'h00),bit4[31:8]}; rol: bit3 = {bit4[23:0],bit4[31:24]}; ror: bit3 = {bit4[7:0],bit4[31:8]}; default: bit3 = bit4; endcase else bit3 = bit4; // bit 2 (4) always if (shift[2]) case (control) sll: bit2 = {bit3[27:0],4'h0}; srl: bit2 = {4'h0,bit3[31:4]}; sra: bit2 = {(bit3[31]? 4'hf: 4'h0),bit3[31:4]}; rol: bit2 = { bit3[27:0],bit3[31:28]}; ror: bit2 = { bit3[3:0],bit3[31:4]}; default: bit2 = bit3; endcase else bit2 = bit3; // bit 1 (2) always if (shift[1]) case (control) sll: bit1 = {bit2[29:0],2'b00}; srl: bit1 = {2'b00,bit2[31:2]}; sra: bit1 = {(bit2[31]? 2'b11: 2'b00),bit2[31:2]}; rol: bit1 = {bit2[29:0],bit2[31:30]}; ror: bit1 = {bit2[1:0],bit2[31:2]}; default: bit1 = bit2; endcase else bit1 = bit2; // bit 0 (1) always if (shift[0]) case (control) sll: out = {bit1[30:0],1'b0}; srl: out = {1'b0,bit1[31:1]}; sra: out = {bit1[31],bit1[31:1]}; rol: out = {bit1[30:0],bit1[31]}; ror: out = {bit1[0],bit1[31:1]}; default: out = bit1; endcase else out = bit1; endmodule
Maintained by John Loomis, last updated 29 September 2008