Verilog Code for Barrel Shifter: Syntax and Example
A
barrel shifter in Verilog shifts input bits by a variable amount in one clock cycle using multiplexers. You can implement it using a combination of shift operations and conditional logic inside an always block or with continuous assignments using bit slicing and concatenation.Syntax
A barrel shifter module typically has inputs for the data to shift, the shift amount, and the direction, and an output for the shifted result.
The main parts are:
- input [N-1:0] data_in: The data to be shifted.
- input [M-1:0] shift_amt: The number of positions to shift.
- input dir: Direction of shift (0 for left, 1 for right).
- output reg [N-1:0] data_out: The shifted output.
The shifting is done inside an always @(*) block using a case or if statements to select the shift amount.
verilog
module barrel_shifter(
input wire [7:0] data_in,
input wire [2:0] shift_amt,
input wire dir, // 0 = left shift, 1 = right shift
output reg [7:0] data_out
);
always @(*) begin
if (dir == 0) // left shift
data_out = data_in << shift_amt;
else // right shift
data_out = data_in >> shift_amt;
end
endmoduleExample
This example shows a barrel shifter that shifts an 8-bit input left or right by 0 to 7 bits. It uses an always block and shift operators.
When run in simulation, it outputs the shifted values for different shift amounts and directions.
verilog
module testbench();
reg [7:0] data_in;
reg [2:0] shift_amt;
reg dir;
wire [7:0] data_out;
barrel_shifter uut(
.data_in(data_in),
.shift_amt(shift_amt),
.dir(dir),
.data_out(data_out)
);
initial begin
data_in = 8'b10110011;
// Test left shifts
dir = 0;
for (shift_amt = 0; shift_amt < 8; shift_amt = shift_amt + 1) begin
#5;
$display("Left shift by %0d: %b", shift_amt, data_out);
end
// Test right shifts
dir = 1;
for (shift_amt = 0; shift_amt < 8; shift_amt = shift_amt + 1) begin
#5;
$display("Right shift by %0d: %b", shift_amt, data_out);
end
$finish;
end
endmoduleOutput
Left shift by 0: 10110011
Left shift by 1: 01100110
Left shift by 2: 11001100
Left shift by 3: 10011000
Left shift by 4: 00110000
Left shift by 5: 01100000
Left shift by 6: 11000000
Left shift by 7: 10000000
Right shift by 0: 10110011
Right shift by 1: 01011001
Right shift by 2: 00101100
Right shift by 3: 00010110
Right shift by 4: 00001011
Right shift by 5: 00000101
Right shift by 6: 00000010
Right shift by 7: 00000001
Common Pitfalls
Common mistakes when writing barrel shifters include:
- Using arithmetic shift operators instead of logical shifts, which can fill with sign bits instead of zeros.
- Not handling shift amounts larger than the data width, causing unexpected results.
- Confusing left and right shift directions.
- Not using
always @(*)for combinational logic, which can cause simulation mismatches.
verilog
/* Wrong: arithmetic right shift fills with sign bit */ assign data_out = data_in >>> shift_amt; // Avoid for unsigned data /* Right: use logical shift operators */ always @(*) begin if (dir == 0) data_out = data_in << shift_amt; else data_out = data_in >> shift_amt; end
Quick Reference
Tips for barrel shifter design:
- Use logical shift operators
<<and>>for unsigned data. - Use
always @(*)for combinational logic blocks. - Limit shift amount to the data width to avoid unexpected zeros.
- Test both shift directions thoroughly.
Key Takeaways
A barrel shifter shifts data by a variable amount in one cycle using logical shifts.
Use
always @(*) blocks for combinational barrel shifters in Verilog.Avoid arithmetic shifts for unsigned data to prevent sign extension errors.
Test all shift amounts and directions to ensure correct behavior.
Limit shift amounts to the data width to avoid unexpected results.