Verilog Code for SISO Shift Register: Syntax and Example
A SISO (Serial-In Serial-Out) shift register in Verilog can be created using a register array and a clocked always block that shifts data on each clock edge. Use
always @(posedge clk or posedge reset) to update the register and shift bits serially from input to output.Syntax
The basic syntax for a SISO shift register uses an always block triggered on the positive edge of the clock or reset signal. Inside, the register shifts bits to the right, and the new serial input bit is loaded at the leftmost position.
clk: Clock signal triggering the shift.reset: Asynchronous reset to clear the register.serial_in: New bit input to be shifted in.shift_reg: Register holding the shifted bits.serial_out: Output bit shifted out from the right.
verilog
module siso_shift_register(
input wire clk,
input wire reset,
input wire serial_in,
output wire serial_out
);
reg [3:0] shift_reg; // 4-bit shift register
assign serial_out = shift_reg[0]; // Output is the rightmost bit
always @(posedge clk or posedge reset) begin
if (reset) begin
shift_reg <= 4'b0000; // Clear register on reset
end else begin
shift_reg <= {serial_in, shift_reg[3:1]}; // Shift right and insert new bit
end
end
endmoduleExample
This example shows a 4-bit SISO shift register that shifts in bits serially on each clock pulse. When reset is high, the register clears to zero. The serial_out outputs the oldest bit shifted out.
verilog
module testbench();
reg clk = 0;
reg reset = 0;
reg serial_in = 0;
wire serial_out;
siso_shift_register uut (
.clk(clk),
.reset(reset),
.serial_in(serial_in),
.serial_out(serial_out)
);
// Clock generation
always #5 clk = ~clk; // 10 time units period
initial begin
$monitor($time, ": serial_in=%b, serial_out=%b", serial_in, serial_out);
reset = 1; #10;
reset = 0;
// Shift in bits 1,0,1,1
serial_in = 1; #10;
serial_in = 0; #10;
serial_in = 1; #10;
serial_in = 1; #10;
// Shift in bits 0,0,1,0
serial_in = 0; #10;
serial_in = 0; #10;
serial_in = 1; #10;
serial_in = 0; #10;
$finish;
end
endmoduleOutput
0: serial_in=0, serial_out=0
10: serial_in=1, serial_out=0
20: serial_in=0, serial_out=0
30: serial_in=1, serial_out=1
40: serial_in=1, serial_out=0
50: serial_in=0, serial_out=1
60: serial_in=0, serial_out=1
70: serial_in=1, serial_out=0
80: serial_in=0, serial_out=1
Common Pitfalls
Common mistakes when writing a SISO shift register include:
- Not using a clock edge in the
alwaysblock, causing combinational logic instead of sequential. - Forgetting to reset the register, which can leave it in an unknown state.
- Incorrect bit ordering when shifting, which reverses the data flow.
- Assigning output inside the
alwaysblock instead of usingassignfor continuous output.
verilog
/* Wrong: Missing clock edge, causes combinational loop */ always @(serial_in) begin shift_reg <= {shift_reg[2:0], serial_in}; end /* Correct: Use clock edge and reset */ always @(posedge clk or posedge reset) begin if (reset) shift_reg <= 4'b0000; else shift_reg <= {serial_in, shift_reg[3:1]}; end
Quick Reference
Tips for writing a SISO shift register in Verilog:
- Use
always @(posedge clk or posedge reset)for synchronous operation with asynchronous reset. - Shift bits by concatenating the new input bit with the upper bits of the register.
- Assign the output bit continuously from the rightmost register bit.
- Initialize or reset the register to avoid unknown states.
Key Takeaways
Use a clocked always block with posedge clk and posedge reset for synchronous shifting.
Shift register bits by concatenating the new serial input with the upper bits of the register.
Assign the serial output continuously from the rightmost bit of the register.
Always reset the shift register to a known state to avoid unknown outputs.
Avoid combinational logic for shifting; use sequential logic triggered by clock edges.