0
0
VhdlHow-ToBeginner · 4 min read

VHDL Code for Simple Processor: Syntax and Example

A simple processor in VHDL can be created using an entity with a clock, reset, and basic instruction decoding inside a process block. The processor typically includes registers, an ALU, and a control unit coded with process and case statements to handle instructions.
📐

Syntax

A simple processor in VHDL uses an entity to define inputs and outputs, and an architecture to describe its behavior. Inside the architecture, a process block triggered by the clock handles instruction execution. Registers store data, and a case statement decodes instructions.

  • entity: Defines the processor interface.
  • architecture: Contains the processor logic.
  • process(clk): Runs on clock edges.
  • case instruction is: Decodes instructions.
vhdl
entity SimpleProcessor is
    Port (
        clk     : in  std_logic;
        reset   : in  std_logic;
        instr   : in  std_logic_vector(3 downto 0);
        data_in : in  std_logic_vector(7 downto 0);
        data_out: out std_logic_vector(7 downto 0)
    );
end SimpleProcessor;

architecture Behavioral of SimpleProcessor is
    signal regA : std_logic_vector(7 downto 0) := (others => '0');
    signal regB : std_logic_vector(7 downto 0) := (others => '0');
begin
    process(clk, reset)
    begin
        if reset = '1' then
            regA <= (others => '0');
            regB <= (others => '0');
            data_out <= (others => '0');
        elsif rising_edge(clk) then
            case instr is
                when "0001" =>  -- Load data_in to regA
                    regA <= data_in;
                when "0010" =>  -- Load data_in to regB
                    regB <= data_in;
                when "0011" =>  -- Add regA and regB
                    data_out <= std_logic_vector(unsigned(regA) + unsigned(regB));
                when others =>
                    null;
            end case;
        end if;
    end process;
end Behavioral;
💻

Example

This example shows a very simple processor that can load two 8-bit values into registers and add them. It uses a 4-bit instruction input to decide the operation. The output shows the sum of the two registers after the add instruction.

vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity SimpleProcessor is
    Port (
        clk     : in  std_logic;
        reset   : in  std_logic;
        instr   : in  std_logic_vector(3 downto 0);
        data_in : in  std_logic_vector(7 downto 0);
        data_out: out std_logic_vector(7 downto 0)
    );
end SimpleProcessor;

architecture Behavioral of SimpleProcessor is
    signal regA : std_logic_vector(7 downto 0) := (others => '0');
    signal regB : std_logic_vector(7 downto 0) := (others => '0');
begin
    process(clk, reset)
    begin
        if reset = '1' then
            regA <= (others => '0');
            regB <= (others => '0');
            data_out <= (others => '0');
        elsif rising_edge(clk) then
            case instr is
                when "0001" =>  -- Load data_in to regA
                    regA <= data_in;
                when "0010" =>  -- Load data_in to regB
                    regB <= data_in;
                when "0011" =>  -- Add regA and regB
                    data_out <= std_logic_vector(unsigned(regA) + unsigned(regB));
                when others =>
                    null;
            end case;
        end if;
    end process;
end Behavioral;
Output
No direct console output; data_out shows sum of regA and regB after add instruction
⚠️

Common Pitfalls

Common mistakes when writing a simple processor in VHDL include:

  • Not resetting registers properly, causing unknown values.
  • Forgetting to use rising_edge(clk) for synchronous logic.
  • Mixing std_logic_vector with arithmetic without conversion.
  • Not handling others case in case statements, which can cause latches.

Always convert std_logic_vector to unsigned or signed before arithmetic operations.

vhdl
wrong: data_out <= regA + regB;  -- Error: no conversion
right: data_out <= std_logic_vector(unsigned(regA) + unsigned(regB));
📊

Quick Reference

Tips for writing simple processors in VHDL:

  • Use process(clk, reset) for synchronous logic.
  • Reset all registers to known values.
  • Use case statements for instruction decoding.
  • Convert vectors to numeric types for math.
  • Keep instructions simple and clear.

Key Takeaways

Use a clocked process with reset to control processor operations.
Decode instructions with a case statement inside the process.
Convert std_logic_vector to unsigned before arithmetic.
Always reset registers to avoid unknown states.
Keep instruction set and logic simple for clarity.