Bird
Raised Fist0
VHDLprogramming~10 mins

Single-port RAM in VHDL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Single-port RAM in VHDL
Start
↓
Check Write Enable
↓
Write Data
↓
Output Data
↓
End
The RAM checks if write is enabled; if yes, it writes data at the address, else it reads data from the address and outputs it.
Execution Sample
VHDL
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ram_sp 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 ram_sp;

architecture rtl of ram_sp 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;
        dout <= din;
      else
        dout <= ram(to_integer(unsigned(addr)));
      end if;
    end if;
  end process;
end rtl;
This code defines a 16x8-bit single-port RAM with synchronous write and synchronous read on clock rising edge.
Execution Table
StepclkweaddrdinActionram[addr]dout
10 -> 1 (rising)0000100000000No write (we=0), read ram[1]0000000000000000
21 -> 0 (falling)0000100000000No clock edge, no action0000000000000000
30 -> 1 (rising)1001010101010Write din to ram[2], then output din1010101010101010
41 -> 0 (falling)1001010101010No clock edge, no action1010101010101010
50 -> 1 (rising)0001000000000No write, read ram[2]1010101010101010
6End---Simulation ends1010101010101010
💡 Simulation ends after last rising clock edge; RAM contents stable.
Variable Tracker
VariableStartAfter Step 1After Step 3After Step 5Final
ram[1]0000000000000000000000000000000000000000
ram[2]0000000000000000101010101010101010101010
dout0000000000000000101010101010101010101010
Key Moments - 3 Insights
Why does dout update even when we=0 (no write)?
Because dout always reads the RAM at the given address on the rising clock edge, regardless of write enable, as shown in steps 1 and 5.
When exactly does the RAM write happen?
RAM writes happen only on the rising edge of clk when we='1', as seen in step 3 where ram[2] updates.
Why is the RAM content unchanged on falling clock edges?
The process triggers only on rising edges of clk, so no RAM update or output change occurs on falling edges (steps 2 and 4).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of dout at step 5?
A11111111
B10101010
C00000000
D00000001
💡 Hint
Check the 'dout' column at step 5 in the execution_table.
At which step does the RAM write occur?
AStep 3
BStep 1
CStep 5
DStep 2
💡 Hint
Look for the step where 'Action' mentions writing to ram[addr].
If we change we to '1' at step 1, what would happen to ram[1]?
AIt stays 00000000
BIt becomes undefined
CIt changes to din value at step 1
DIt changes at step 5
💡 Hint
Refer to how ram updates when we='1' on rising clock edges in the variable_tracker.
Concept Snapshot
Single-port RAM in VHDL:
- Uses one port for read/write.
- Write occurs on rising clock edge if we='1'.
- Read occurs every rising clock edge.
- Address selects memory location.
- Data input (din) written; data output (dout) read.
- RAM modeled as array of std_logic_vector.
Full Transcript
This visual execution shows a single-port RAM in VHDL. The RAM has a clock input, a write enable signal, an address input, data input, and data output. On each rising clock edge, if write enable is high, the RAM writes the input data to the memory at the given address. Regardless of write enable, the RAM outputs the data stored at the address on each rising clock edge. The execution table traces clock edges, write enable, address, data input, and the resulting RAM content and output. Variable tracking shows how RAM contents and output change step-by-step. Key moments clarify when writing happens and why output updates even without writing. The quiz tests understanding of RAM behavior at specific steps. This helps beginners see how single-port RAM works in hardware description language VHDL.

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