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.
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;
| Step | clk | we | addr | din | Action | ram[addr] | dout |
|---|---|---|---|---|---|---|---|
| 1 | 0 -> 1 (rising) | 0 | 0001 | 00000000 | No write (we=0), read ram[1] | 00000000 | 00000000 |
| 2 | 1 -> 0 (falling) | 0 | 0001 | 00000000 | No clock edge, no action | 00000000 | 00000000 |
| 3 | 0 -> 1 (rising) | 1 | 0010 | 10101010 | Write din to ram[2], then output din | 10101010 | 10101010 |
| 4 | 1 -> 0 (falling) | 1 | 0010 | 10101010 | No clock edge, no action | 10101010 | 10101010 |
| 5 | 0 -> 1 (rising) | 0 | 0010 | 00000000 | No write, read ram[2] | 10101010 | 10101010 |
| 6 | End | - | - | - | Simulation ends | 10101010 | 10101010 |
| Variable | Start | After Step 1 | After Step 3 | After Step 5 | Final |
|---|---|---|---|---|---|
| ram[1] | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 |
| ram[2] | 00000000 | 00000000 | 10101010 | 10101010 | 10101010 |
| dout | 00000000 | 00000000 | 10101010 | 10101010 | 10101010 |
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.
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;we is '1' and addr is 3?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;Pass the test and this pattern moves unknown