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_vectorto integer usingto_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
weis 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.