Simple Dual-Port Block RAM with Single Clock (VHDL)
Filename: simple_dual_one_clock.vhd
-- Simple Dual-Port Block RAM with One Clock
-- Correct Modelization with a Shared Variable
-- File:simple_dual_one_clock.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity simple_dual_one_clock is
port(
clk : in std_logic;
ena : in std_logic;
enb : in std_logic;
wea : in std_logic;
addra : in std_logic_vector(9 downto 0);
addrb : in std_logic_vector(9 downto 0);
dia : in std_logic_vector(15 downto 0);
dob : out std_logic_vector(15 downto 0)
);
end simple_dual_one_clock;
architecture syn of simple_dual_one_clock is
type ram_type is array (1023 downto 0) of std_logic_vector(15 downto 0);
shared variable RAM : ram_type;
begin
process(clk)
begin
if clk'event and clk = '1' then
if ena = '1' then
if wea = '1' then
RAM(conv_integer(addra)) := dia;
end if;
end if;
end if;
end process;
process(clk)
begin
if clk'event and clk = '1' then
if enb = '1' then
dob <= RAM(conv_integer(addrb));
end if;
end if;
end process;
end syn;
Simple Dual-Port Block RAM with Dual Clocks (Verilog)
Filename: simple_dual_two_clocks.v
// Simple Dual-Port Block RAM with Two Clocks
// File: simple_dual_two_clocks.v
module simple_dual_two_clocks (clka,clkb,ena,enb,wea,addra,addrb,dia,dob);
input clka,clkb,ena,enb,wea;
input [9:0] addra,addrb;
input [15:0] dia;
output [15:0] dob;
reg [15:0] ram [1023:0];
reg [15:0] dob;
always @(posedge clka)
begin
if (ena)
begin
if (wea)
ram[addra] <= dia;
end
end
always @(posedge clkb)
begin
if (enb)
begin
dob <= ram[addrb];
end
end
endmodule
Simple Dual-Port Block RAM with Dual Clocks (VHDL)
Filename: simple_dual_two_clocks.vhd
-- Simple Dual-Port Block RAM with Two Clocks
-- Correct Modelization with a Shared Variable
-- File: simple_dual_two_clocks.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity simple_dual_two_clocks is
port(
clka : in std_logic;
clkb : in std_logic;
ena : in std_logic;
enb : in std_logic;
wea : in std_logic;
addra : in std_logic_vector(9 downto 0);
addrb : in std_logic_vector(9 downto 0);
dia : in std_logic_vector(15 downto 0);
dob : out std_logic_vector(15 downto 0)
);
end simple_dual_two_clocks;
architecture syn of simple_dual_two_clocks is
type ram_type is array (1023 downto 0) of std_logic_vector(15 downto 0);
shared variable RAM : ram_type;
begin
process(clka)
begin
if clka'event and clka = '1' then
if ena = '1' then
if wea = '1' then
RAM(conv_integer(addra)) := dia;
end if;
end if;
end if;
end process;
process(clkb)
begin
if clkb'event and clkb = '1' then
if enb = '1' then
dob <= RAM(conv_integer(addrb));
end if;
end if;
end process;
end syn;
真正的双端口块RAM示例
以下部分提供了True Dual Port Block的VHDL和Verilog编码示例
内存
读取优先模式下具有两个写入端口的双端口块RAM
Verilog示例
Filename: ram_tdp_rf_rf.v
// Dual-Port Block RAM with Two Write Ports
// File: rams_tdp_rf_rf.v
module rams_tdp_rf_rf
(clka,clkb,ena,enb,wea,web,addra,addrb,dia,dib,doa,dob);
input clka,clkb,ena,enb,wea,web;
input [9:0] addra,addrb;
input [15:0] dia,dib;
output [15:0] doa,dob;
reg [15:0] ram [1023:0];
reg [15:0] doa,dob;
always @(posedge clka)
begin
if (ena)
begin
if (wea)
ram[addra] <= dia;
doa <= ram[addra];
end
end
always @(posedge clkb)
begin
if (enb)
begin
if (web)
ram[addrb] <= dib;
dob <= ram[addrb];
end
end
endmodule
Dual-Port Block RAM with Two Write Ports in Read-First Mode
(VHDL)
Filename: ram_tdp_rf_rf.vhd
-- Dual-Port Block RAM with Two Write Ports
-- Correct Modelization with a Shared Variable
-- File: rams_tdp_rf_rf.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
entity rams_tdp_rf_rf is
port(
clka : in std_logic;
clkb : in std_logic;
ena : in std_logic;
enb : in std_logic;
wea : in std_logic;
web : in std_logic;
addra : in std_logic_vector(9 downto 0);
addrb : in std_logic_vector(9 downto 0);
dia : in std_logic_vector(15 downto 0);
dib : in std_logic_vector(15 downto 0);
doa : out std_logic_vector(15 downto 0);
dob : out std_logic_vector(15 downto 0)
);
end rams_tdp_rf_rf;
architecture syn of rams_tdp_rf_rf is
type ram_type is array (1023 downto 0) of std_logic_vector(15 downto 0);
shared variable RAM : ram_type;
begin
process(CLKA)
begin
if CLKA’event and CLKA = ‘1’ then
if ENA = ‘1’ then
DOA <= RAM(to_integer(unsigned(ADDRA)));
if WEA = ‘1’ then
RAM(to_integer(unsigned(ADDRA))) := DIA;
end if;
end if;
end if;
end process;
process(CLKB)
begin
if CLKB’event and CLKB = ‘1’ then
if ENB = ‘1’ then
DOB <= RAM(to_integer(unsigned(ADDRB)));
if WEB = ‘1’ then
RAM(to_integer(unsigned(ADDRB))) := DIB;
end if;
end if;
end if;
end process;
end syn;
Block RAM with Optional Output Registers (Verilog)
Filename: rams_pipeline.v
// Block RAM with Optional Output Registers
// File: rams_pipeline
module rams_pipeline (clk1, clk2, we, en1, en2, addr1, addr2, di, res1,
res2);
input clk1;
input clk2;
input we, en1, en2;
input [9:0] addr1;
input [9:0] addr2;
input [15:0] di;
output [15:0] res1;
output [15:0] res2;
reg [15:0] res1;
reg [15:0] res2;
reg [15:0] RAM [1023:0];
reg [15:0] do1;
reg [15:0] do2;
always @(posedge clk1)
begin
if (we == 1'b1)
RAM[addr1] <= di;
do1 <= RAM[addr1];
end
always @(posedge clk2)
begin
do2 <= RAM[addr2];
end
always @(posedge clk1)
begin
if (en1 == 1'b1)
res1 <= do1;
end
always @(posedge clk2)
begin
if (en2 == 1'b1)
res2 <= do2;
end
endmodule
Block RAM with Optional Output Registers (VHDL)
Filename: rams_pipeline.vhd
-- Block RAM with Optional Output Registers
-- File: rams_pipeline.vhd
library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity rams_pipeline is
port(
clk1, clk2 : in std_logic;
we, en1, en2 : in std_logic;
addr1 : in std_logic_vector(9 downto 0);
addr2 : in std_logic_vector(9 downto 0);
di : in std_logic_vector(15 downto 0);
res1 : out std_logic_vector(15 downto 0);
res2 : out std_logic_vector(15 downto 0)
);
end rams_pipeline;
architecture beh of rams_pipeline is
type ram_type is array (1023 downto 0) of std_logic_vector(15 downto 0);
signal ram : ram_type;
signal do1 : std_logic_vector(15 downto 0);
signal do2 : std_logic_vector(15 downto 0);
begin
process(clk1)
begin
if rising_edge(clk1) then
if we = '1' then
ram(to_integer(unsigned(addr1))) <= di;
end if;
do1 <= ram(to_integer(unsigned(addr1)));
end if;
end process;
process(clk2)
begin
if rising_edge(clk2) then
do2 <= ram(to_integer(unsigned(addr2)));
end if;
end process;
process(clk1)
begin
if rising_edge(clk1) then
if en1 = '1' then
res1 <= do1;
end if;
end if;
end process;
process(clk2)
begin
if rising_edge(clk2) then
if en2 = '1' then
res2 <= do2;
end if;
end if;
end process;
end beh;