Barrel Shifter

Download: barrel.zip

Contents

behavioral (C operators)
behavioral, multiplexer
logarithmic (base 2), hierachical
final version, with rotate operations

Version 1

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

Version 2

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

Version 3

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

Version with Rotator

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