0
0
VhdlHow-ToBeginner · 4 min read

VHDL Code for PISO Shift Register: Syntax and Example

A PISO shift register in VHDL loads parallel data inputs and shifts them out serially on each clock pulse. The code includes a process triggered by clock and load signals, where parallel data is loaded when load is high, and shifted out bit by bit when load is low.
📐

Syntax

The PISO shift register uses a clock, a load signal, parallel data inputs, and a serial output. The main process is sensitive to the clock and uses an if rising_edge(clk) statement. When load is high, the parallel data is loaded into an internal register. When load is low, the register shifts right by one bit, outputting the least significant bit.

  • clk: Clock signal to synchronize operations.
  • load: Control signal to load parallel data.
  • parallel_in: Input vector of parallel bits.
  • serial_out: Output bit shifted out serially.
  • shift_reg: Internal register holding data during shifting.
vhdl
process(clk)
begin
  if rising_edge(clk) then
    if load = '1' then
      shift_reg <= parallel_in;
    else
      serial_out <= shift_reg(0);
      shift_reg <= '0' & shift_reg(shift_reg'length-1 downto 1);
    end if;
  end if;
end process;
💻

Example

This example shows a 4-bit PISO shift register. It loads 4 bits in parallel when load is high, then shifts them out one bit per clock cycle when load is low.

vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity PISO_Shift_Register is
  Port (
    clk        : in  STD_LOGIC;
    load       : in  STD_LOGIC;
    parallel_in: in  STD_LOGIC_VECTOR(3 downto 0);
    serial_out : out STD_LOGIC
  );
end PISO_Shift_Register;

architecture Behavioral of PISO_Shift_Register is
  signal shift_reg : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
begin
  process(clk)
  begin
    if rising_edge(clk) then
      if load = '1' then
        shift_reg <= parallel_in;
      else
        serial_out <= shift_reg(0);
        shift_reg <= '0' & shift_reg(3 downto 1);
      end if;
    end if;
  end process;
end Behavioral;
Output
On each clock cycle with load=1, parallel_in is loaded into shift_reg; with load=0, bits shift right and serial_out outputs the least significant bit.
⚠️

Common Pitfalls

Common mistakes include:

  • Not using rising_edge(clk) for clock detection, causing unreliable timing.
  • Forgetting to load data when load is high, so shift register never updates.
  • Incorrect bit shifting direction, which reverses output order.
  • Not initializing the shift register, leading to unknown outputs at start.

Always ensure the shift direction matches your design and initialize signals properly.

vhdl
process(clk)
begin
  if rising_edge(clk) then
    if load = '1' then
      -- Wrong: missing loading parallel data
      null;
    else
      serial_out <= shift_reg(0);
      shift_reg <= '0' & shift_reg(3 downto 1);
    end if;
  end if;
end process;

-- Correct version:
process(clk)
begin
  if rising_edge(clk) then
    if load = '1' then
      shift_reg <= parallel_in;
    else
      serial_out <= shift_reg(0);
      shift_reg <= '0' & shift_reg(3 downto 1);
    end if;
  end if;
end process;
📊

Quick Reference

  • clk: Clock input, triggers shift/load.
  • load: High to load parallel data, low to shift.
  • parallel_in: Parallel data input vector.
  • serial_out: Serial output bit.
  • shift_reg: Internal register holding data.

Use rising_edge(clk) to detect clock edges and shift bits right with zero fill on left.

Key Takeaways

Use rising_edge(clk) to synchronize loading and shifting in the PISO register.
Load parallel data into the shift register when load signal is high.
Shift bits right and output the least significant bit serially when load is low.
Initialize the shift register to avoid unknown startup values.
Check shift direction carefully to match your serial output order.