Single-port RAM lets you store and read data using one connection point. It is simple and useful for many digital designs.
Single-port RAM in 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.
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;
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;
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.
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;
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.
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
Solution
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.Step 2: Identify the correct function
It does not perform arithmetic, generate clocks, or control pins; it only stores and retrieves data.Final Answer:
Store data using one address and one data line -> Option BQuick Check:
Single-port RAM = Data storage [OK]
- Confusing RAM with arithmetic units
- Thinking RAM generates clocks
- Assuming RAM controls I/O pins
Solution
Step 1: Understand array declaration syntax
In VHDL, RAM is declared as an array of std_logic_vector with address range and data width.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.Final Answer:
type ram_type is array (0 to 15) of std_logic_vector(7 downto 0); signal ram : ram_type; -> Option CQuick Check:
Correct array declaration = type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);\nsignal ram : ram_type; [OK]
- Reversing array and vector ranges
- Using incorrect syntax for array of vectors
- Declaring signal without type
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?Solution
Step 1: Analyze write operation timing
On rising clock edge, if write enable (we) is '1', RAM at address is updated with data_in.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.Final Answer:
Data at address 3 is updated but data_out shows old data -> Option AQuick Check:
Write updates RAM, read outputs old data [OK]
- Assuming read shows new data immediately
- Confusing write enable effect
- Ignoring clock edge timing
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;Solution
Step 1: Check clock edge detection
Using clk'event and clk = '1' is valid but less recommended than rising_edge(clk).Step 2: Check address usage
Address 'addr' is likely std_logic_vector and must be converted to integer for RAM indexing.Final Answer:
Missing conversion from std_logic_vector to integer for addr -> Option DQuick Check:
Address must be integer index [OK]
- Using std_logic_vector directly as index
- Ignoring recommended rising_edge(clk)
- Thinking data_out can't be assigned in process
Solution
Step 1: Understand asynchronous reset effect
An asynchronous reset triggers immediately, allowing clearing all RAM locations regardless of clock.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.Final Answer:
Add an asynchronous reset in the process that sets all RAM locations to zero -> Option AQuick Check:
Async reset clears entire RAM [OK]
- Clearing only one address on reset
- Using synchronous reset for full RAM clear
- Believing reset can't clear RAM
Ready to prove it?
Pass the test and this pattern moves unknown
