0
0
VerilogHow-ToBeginner · 3 min read

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
endmodule
💻

Example

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
endmodule
Output
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 always block, 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 always block instead of using assign for 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.