0
0
VerilogHow-ToBeginner · 3 min read

Verilog Code for SIPO Shift Register: Syntax and Example

A Serial-In Parallel-Out (SIPO) shift register in Verilog reads data serially on each clock pulse and outputs the stored bits in parallel. Use a reg array to store bits, shift them on the clock's rising edge, and output the register content in parallel.
📐

Syntax

The basic syntax for a SIPO shift register includes defining inputs for clock and serial data, an output for parallel data, and a reg array to hold the bits. On each rising edge of the clock, the register shifts left and the new serial bit is loaded at the rightmost position.

  • input clk: Clock signal to trigger shifting.
  • input serial_in: Serial data input bit.
  • output reg [N-1:0] parallel_out: Parallel output of all stored bits.
  • always @(posedge clk): Block triggered on clock rising edge.
  • Shift register logic: parallel_out << 1 shifts bits left, new bit loaded at LSB.
verilog
module sipo_shift_register(
    input clk,
    input serial_in,
    output reg [3:0] parallel_out
);

always @(posedge clk) begin
    parallel_out <= {parallel_out[2:0], serial_in};
end

endmodule
💻

Example

This example shows a 4-bit SIPO shift register. It takes serial bits one by one on serial_in at each clock pulse and outputs the 4-bit parallel value on parallel_out. The bits shift left, with the newest bit entering at the right.

verilog
module sipo_shift_register(
    input clk,
    input serial_in,
    output reg [3:0] parallel_out
);

always @(posedge clk) begin
    parallel_out <= {parallel_out[2:0], serial_in};
end

endmodule

// Testbench
module testbench();
    reg clk = 0;
    reg serial_in = 0;
    wire [3:0] parallel_out;

    sipo_shift_register uut(.clk(clk), .serial_in(serial_in), .parallel_out(parallel_out));

    always #5 clk = ~clk; // 10 time units clock period

    initial begin
        // Send bits 1,0,1,1 serially
        serial_in = 1; #10;
        serial_in = 0; #10;
        serial_in = 1; #10;
        serial_in = 1; #10;
        $finish;
    end

    initial begin
        $monitor("At time %0t: parallel_out = %b", $time, parallel_out);
    end
endmodule
Output
At time 10: parallel_out = 0001 At time 20: parallel_out = 0010 At time 30: parallel_out = 0101 At time 40: parallel_out = 1011
⚠️

Common Pitfalls

Common mistakes when writing a SIPO shift register include:

  • Not using a clock edge trigger (posedge clk) causing incorrect timing.
  • Forgetting to declare parallel_out as reg, which is needed for assignment inside always blocks.
  • Incorrect bit concatenation order, which reverses the bit order.
  • Not initializing the register, which can cause unknown outputs at start.
verilog
/* Wrong: Using blocking assignment and no clock edge */
always @(*) begin
    parallel_out = {parallel_out[2:0], serial_in}; // Wrong: combinational, no clock
end

/* Right: Use non-blocking assignment on posedge clock */
always @(posedge clk) begin
    parallel_out <= {parallel_out[2:0], serial_in};
end
📊

Quick Reference

Tips for writing SIPO shift registers in Verilog:

  • Use always @(posedge clk) for synchronous shifting.
  • Use non-blocking assignment <= inside always blocks.
  • Concatenate bits with {} to shift and insert new bit.
  • Declare output as reg if assigned inside always.
  • Initialize registers if needed to avoid unknown states.

Key Takeaways

Use a clock edge triggered always block to shift bits synchronously.
Declare the parallel output as reg to assign inside always blocks.
Shift bits by concatenating the register with the new serial input.
Use non-blocking assignments (<=) for correct sequential logic.
Initialize registers to avoid unknown startup values.