Bird
Raised Fist0
VHDLprogramming~5 mins

Single-port RAM in VHDL

Choose your learning style10 modes available
Introduction

Single-port RAM lets you store and read data using one connection point. It is simple and useful for many digital designs.

When you need to save data temporarily in a digital circuit.
When you want to read or write data but only one operation at a time.
When building small memory blocks inside FPGA or ASIC designs.
When you want to keep your design simple and use fewer resources.
Syntax
VHDL
type ram_type is array (0 to RAM_DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
signal ram : ram_type;

process(clk)
begin
  if rising_edge(clk) then
    if we = '1' then
      ram(address) <= data_in;  -- Write data
    else
      data_out <= ram(address); -- Read data
    end if;
  end if;
end process;

The RAM is defined as an array of data words.

Only one port is used for both reading and writing, controlled by a write enable signal.

Examples
This example shows a 16x8-bit single-port RAM with write enable and synchronous read/write.
VHDL
type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);
signal ram : ram_type;

process(clk)
begin
  if rising_edge(clk) then
    if we = '1' then
      ram(addr) <= data_in;
    else
      data_out <= ram(addr);
    end if;
  end if;
end process;
Here, the read happens every clock cycle, and write happens only if write enable is high.
VHDL
type ram_type is array (0 to 31) of std_logic_vector(15 downto 0);
signal ram : ram_type;

process(clk)
begin
  if rising_edge(clk) then
    if we = '1' then
      ram(address) <= data_in;
    end if;
    data_out <= ram(address);
  end if;
end process;
Sample Program

This is a complete single-port RAM design in VHDL. It stores 16 words of 8 bits each. You can write data when we is high and read data every clock cycle.

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

entity single_port_ram is
  generic (
    DATA_WIDTH : integer := 8;
    RAM_DEPTH  : integer := 16
  );
  port (
    clk      : in std_logic;
    we       : in std_logic;
    address  : in integer range 0 to RAM_DEPTH-1;
    data_in  : in std_logic_vector(DATA_WIDTH-1 downto 0);
    data_out : out std_logic_vector(DATA_WIDTH-1 downto 0)
  );
end entity;

architecture rtl of single_port_ram is
  type ram_type is array (0 to RAM_DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
  signal ram : ram_type := (others => (others => '0'));
begin
  process(clk)
  begin
    if rising_edge(clk) then
      if we = '1' then
        ram(address) <= data_in;
      end if;
      data_out <= ram(address);
    end if;
  end process;
end architecture;
OutputSuccess
Important Notes

Single-port RAM can only read or write one location at a time.

Reading and writing happen on the clock's rising edge for synchronous operation.

Initialize RAM contents if needed to avoid unknown values.

Summary

Single-port RAM uses one address port for both reading and writing.

Write enable controls if data is written or read on a clock edge.

It is simple and useful for small memory needs in digital designs.

Practice

(1/5)
1. What is the main function of a single-port RAM in VHDL?
easy
A. Generate clock signals
B. Store data using one address and one data line
C. Perform arithmetic operations
D. Control input/output pins

Solution

  1. Step 1: Understand the role of single-port RAM

    Single-port RAM is designed to store data at a specific address with one data input and output line.
  2. Step 2: Identify the correct function

    It does not perform arithmetic, generate clocks, or control pins; it only stores and retrieves data.
  3. Final Answer:

    Store data using one address and one data line -> Option B
  4. Quick Check:

    Single-port RAM = Data storage [OK]
Hint: Single-port RAM stores data at one address line [OK]
Common Mistakes:
  • Confusing RAM with arithmetic units
  • Thinking RAM generates clocks
  • Assuming RAM controls I/O pins
2. Which VHDL statement correctly declares a single-port RAM with 16 locations of 8-bit width?
easy
A. signal ram : std_logic_vector(7 downto 0) array (0 to 15);
B. signal ram : std_logic_vector(15 downto 0)(7 downto 0);
C. type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);\nsignal ram : ram_type;
D. type ram_type is array (7 downto 0) of std_logic_vector(0 to 15);\nsignal ram : ram_type;

Solution

  1. Step 1: Understand array declaration syntax

    In VHDL, RAM is declared as an array of std_logic_vector with address range and data width.
  2. Step 2: Check each option

    type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);\nsignal ram : ram_type; correctly declares an array from 0 to 15 with 8-bit vectors. Others have incorrect syntax or order.
  3. Final Answer:

    type ram_type is array (0 to 15) of std_logic_vector(7 downto 0); signal ram : ram_type; -> Option C
  4. Quick Check:

    Correct array declaration = type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);\nsignal ram : ram_type; [OK]
Hint: Use 'array (0 to N) of std_logic_vector(width downto 0)' [OK]
Common Mistakes:
  • Reversing array and vector ranges
  • Using incorrect syntax for array of vectors
  • Declaring signal without type
3. Given this VHDL process for single-port RAM:
process(clk) begin
  if rising_edge(clk) then
    if we = '1' then
      ram(to_integer(unsigned(addr))) <= data_in;
    end if;
    data_out <= ram(to_integer(unsigned(addr)));
  end if;
end process;

What happens when we is '1' and addr is 3?
medium
A. Data at address 3 is updated but data_out shows old data
B. Data at address 3 is not updated but data_out shows old data
C. Data at address 3 is updated with data_in and data_out shows new data
D. No change occurs in RAM or output

Solution

  1. Step 1: Analyze write operation timing

    On rising clock edge, if write enable (we) is '1', RAM at address is updated with data_in.
  2. Step 2: Analyze read operation timing

    Data_out is assigned from RAM at address after write, but read happens before write completes, so old data is output.
  3. Final Answer:

    Data at address 3 is updated but data_out shows old data -> Option A
  4. Quick Check:

    Write updates RAM, read outputs old data [OK]
Hint: Write updates RAM, read outputs previous data same cycle [OK]
Common Mistakes:
  • Assuming read shows new data immediately
  • Confusing write enable effect
  • Ignoring clock edge timing
4. Identify the error in this single-port RAM process:
process(clk) begin
  if clk'event and clk = '1' then
    if we = '1' then
      ram(addr) <= data_in;
    end if;
    data_out <= ram(addr);
  end if;
end process;
medium
A. Using clk'event and clk = '1' instead of rising_edge(clk)
B. No error, code is correct
C. Assigning data_out inside clocked process
D. Missing conversion from std_logic_vector to integer for addr

Solution

  1. Step 1: Check clock edge detection

    Using clk'event and clk = '1' is valid but less recommended than rising_edge(clk).
  2. Step 2: Check address usage

    Address 'addr' is likely std_logic_vector and must be converted to integer for RAM indexing.
  3. Final Answer:

    Missing conversion from std_logic_vector to integer for addr -> Option D
  4. Quick Check:

    Address must be integer index [OK]
Hint: Convert std_logic_vector addr to integer for RAM indexing [OK]
Common Mistakes:
  • Using std_logic_vector directly as index
  • Ignoring recommended rising_edge(clk)
  • Thinking data_out can't be assigned in process
5. How would you modify a single-port RAM VHDL design to asynchronously clear all memory contents to zero on a reset signal?
hard
A. Add an asynchronous reset in the process that sets all RAM locations to zero
B. Use a synchronous reset that clears only the current address data
C. Add a separate process that writes zeros to RAM on reset clock edge
D. Reset signal cannot clear RAM contents in VHDL

Solution

  1. Step 1: Understand asynchronous reset effect

    An asynchronous reset triggers immediately, allowing clearing all RAM locations regardless of clock.
  2. Step 2: Implement reset logic

    Inside the clocked process, add a condition for reset that loops through all RAM addresses and sets them to zero.
  3. Final Answer:

    Add an asynchronous reset in the process that sets all RAM locations to zero -> Option A
  4. Quick Check:

    Async reset clears entire RAM [OK]
Hint: Use async reset to zero all RAM locations immediately [OK]
Common Mistakes:
  • Clearing only one address on reset
  • Using synchronous reset for full RAM clear
  • Believing reset can't clear RAM
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard