Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
    • Flip-Flops and Registers
    • Counters and Timers
    • Shift Registers and LFSRs
      • Serial and Parallel Data Movement
      • Universal Shift Register
      • LFSR for PRBS Generation
    • Pipelining
    • Stalls, Bubbles and Hazards
    • Retiming
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Shift Registers and LFSRs
  1. Topics
  2. RTL Design
  3. Sequential Design
  4. Shift Registers and LFSRs
  5. Serial and Parallel Data Movement

Part 3 · Sequential · Intermediate

Serial and Parallel Data Movement

PISO and SIPO shift registers with LSB-first order and a loopback test.

On this page

    Why this matters

    Send a byte MSB-first into a receiver that expects LSB-first and it arrives bit-reversed. Every value except the bit-palindromes is then wrong, and a loopback test with matching reversals cannot see it.

    After this lesson you can: build a parallel-in serial-out and a serial-in parallel-out register, state the bit order, and weigh a serial link against a parallel bus.

    Two directions

    Name

    Input

    Output

    Use

    PISO (parallel-in, serial-out)

    A whole word, loaded at once

    One bit per clock

    Transmitter / serializer

    SIPO (serial-in, parallel-out)

    One bit per clock

    A whole word, valid after W bits

    Receiver / deserializer

    Bit order must match on both ends. This page uses LSB-first order, as in UART. I²C data bytes are sent MSB-first.

    The PISO output is bit 0 and the register shifts right. New bits enter the SIPO at the top and shift down, so the first bit sent lands in bit 0 after W shifts.

    The two modules are connected only by one wire (wire_bit) and a shared shift enable. A real link adds start/stop framing and a bit counter so the receiver knows where a byte begins; the UART transmitter is exactly that.

    Each slot is one clock cycle, sampled just after its rising edge. A bit on wire_bit in slot k is captured by the receiver at the edge that opens slot k+1.

    • Slot 0: load is high; the edge that opens slot 1 copies 0011 into the transmitter, so wire_bit shows bit 0 = 1.

    • Slots 1 to 4: shift is high. wire_bit carries 1, 1, 0, 0, which is 0011 read from the right.

    • rx: each new bit enters at the MSB, so rx reads 8 (1000), c (1100), 6 (0110), then 3 (0011) in slot 5, equal to the source.

    • Slot 5: shift falls after four shifts and rx holds the word. 0011 is not a palindrome, so a reversed link would have shown c instead.

    Cost and trade-offs

    Parallel bus

    Serial link

    W wires, one word per clock

    1 wire, one word per W clocks

    Fast, uses many pins/tracks

    Slow per wire but cheap in pins and routing

    Timing skew between wires

    Single signal; clock recovery needed at high speeds

    Common mistakes

    Common pitfall

    Get bit order and shift direction agreed in writing. A byte sent MSB-first into a receiver that expects LSB-first arrives bit-reversed, and every value except the 16 bit-palindromes, such as 0x00, 0xFF, 0x81, 0xA5 and 0x3C, looks plausible but wrong. That is why the test below also sends 0x01 and 0x96.

    Check yourself In the SIPO, after 8 shifts the first transmitted bit is where?

    In bit 0 of pdata. Each new bit enters at the MSB and shifts down one position per clock, so the first bit has travelled the full length of the register by the eighth shift.

    Testbench

    The serializer, deserializer and loopback test below move seven byte patterns across one wire, including non-palindromic 0x01 and 0x96. Each wire bit is checked independently against the source byte in LSB-first order, so matching reversal bugs in both endpoints cannot hide. Both modules require W >= 2 (with W = 1 the selects become the reversed sreg[0:1] and pdata[0:1], which are illegal); an elaboration-time guard reports a clear error, though some tools may still diagnose the invalid select.

    piso.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    module piso #(parameter int W = 8) (   // W >= 2
      input  logic         clk, rst_n,
      input  logic         load,
      input  logic [W-1:0] pdata,
      input  logic         shift,
      output logic         sout
    );
      if (W < 2) begin : g_w_check
        $error("piso: W must be at least 2");
      end
      logic [W-1:0] sreg;
      always_ff @(posedge clk or negedge rst_n)
        if (!rst_n)      sreg <= '0;
        else if (load)   sreg <= pdata;                  // load wins over shift
        else if (shift)  sreg <= {1'b0, sreg[W-1:1]};    // LSB leaves first
      assign sout = sreg[0];
    endmodule
    
    module sipo #(parameter int W = 8) (   // W >= 2
      input  logic         clk, rst_n,
      input  logic         shift,
      input  logic         sin,
      output logic [W-1:0] pdata
    );
      if (W < 2) begin : g_w_check
        $error("sipo: W must be at least 2");
      end
      always_ff @(posedge clk or negedge rst_n)
        if (!rst_n)      pdata <= '0;
        else if (shift)  pdata <= {sin, pdata[W-1:1]};   // new bit enters at the MSB
    endmodule
    

    Remember

    • This page uses LSB-first order, as UART does; I2C data bytes go MSB-first.

    • The first bit sent lands in bit 0 of the receiver after W shifts.

    • A real link adds framing and a bit counter so the receiver knows where a byte begins.

    Rule of thumb: agree bit order and shift direction in writing, and check each wire bit against the source byte.

    Keep going

    • Practice: Shift register with parameterised depth and parallel load

    • Code lab: 8-bit shift register

    • Interview: run a mock interview on this topic

    Related topics

    • Universal shift register

    • UART transmitter

    Previous

    73 / 350

    Next: Universal Shift Register

    Up next

    Up nextUniversal Shift Register

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • LFSR for PRBS Generation
    clkloadshiftwire_bitrx08c63
    The page's piso and sipo shortened to W = 4, sending 0011: the wire carries 1, 1, 0, 0 least significant bit first while rx fills from the top until it equals the source; rx in hex