0
0
VhdlHow-ToBeginner · 3 min read

VHDL Code for Single Port RAM: Syntax and Example

A single port RAM in VHDL can be created using a process that handles both read and write operations on a single port. The clk signal controls when data is written, and the address input selects the memory location for reading or writing.
📐

Syntax

The basic syntax for a single port RAM in VHDL includes defining a memory array, input signals for clock, address, data, and control signals for write enable. A process triggered by the clock handles writing data to the memory and reading data from it.

  • clk: Clock signal to synchronize operations.
  • we: Write enable signal; when high, data is written.
  • addr: Address input to select memory location.
  • din: Data input to write into memory.
  • dout: Data output to read from memory.
vhdl
type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);
signal ram : ram_type := (others => (others => '0'));

process(clk) is
begin
  if rising_edge(clk) then
    if we = '1' then
      ram(to_integer(unsigned(addr))) <= din;
    end if;
    dout <= ram(to_integer(unsigned(addr)));
  end if;
end process;
💻

Example

This example shows a complete VHDL entity and architecture for a 16x8 single port RAM. It writes data on the rising edge of the clock when we is high and continuously outputs the data at the given address.

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

entity single_port_ram is
  port(
    clk  : in std_logic;
    we   : in std_logic;
    addr : in std_logic_vector(3 downto 0);
    din  : in std_logic_vector(7 downto 0);
    dout : out std_logic_vector(7 downto 0)
  );
end entity;

architecture rtl of single_port_ram is
  type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);
  signal ram : ram_type := (others => (others => '0'));
begin
  process(clk) is
  begin
    if rising_edge(clk) then
      if we = '1' then
        ram(to_integer(unsigned(addr))) <= din;
      end if;
      dout <= ram(to_integer(unsigned(addr)));
    end if;
  end process;
end architecture;
Output
No console output; hardware simulation shows memory stores and outputs data correctly.
⚠️

Common Pitfalls

Common mistakes include:

  • Not using rising_edge(clk) to synchronize memory operations, causing timing issues.
  • Forgetting to convert the address from std_logic_vector to integer using to_integer(unsigned(addr)).
  • Trying to read and write asynchronously without clock control, which can cause unpredictable behavior.
vhdl
process(clk) is
begin
  if clk = '1' then  -- Incorrect: should use rising_edge(clk)
    if we = '1' then
      ram(to_integer(unsigned(addr))) <= din;  -- Corrected: addr converted to integer
    end if;
    dout <= ram(to_integer(unsigned(addr)));
  end if;
end process;

-- Corrected version:
process(clk) is
begin
  if rising_edge(clk) then
    if we = '1' then
      ram(to_integer(unsigned(addr))) <= din;
    end if;
    dout <= ram(to_integer(unsigned(addr)));
  end if;
end process;
📊

Quick Reference

Remember these tips when writing single port RAM in VHDL:

  • Use rising_edge(clk) for clock synchronization.
  • Convert address signals properly to integer indices.
  • Write data only when we is high.
  • Read data continuously from the memory array.

Key Takeaways

Use a clocked process with rising_edge(clk) to control RAM operations.
Convert address inputs from std_logic_vector to integer before indexing memory.
Write data only when the write enable signal is active.
Read data continuously from the memory array at the given address.
Avoid asynchronous reads/writes to prevent unpredictable behavior.