首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

dual ram

dual ram


-- 双端口() ram22.vhd 2007.12.5

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

ENTITY ram22 IS
generic( Dwidth: integer :=14; -- 数据
Awidth: integer :=8); -- 地址
port(
clock : IN STD_LOGIC;
wren : IN STD_LOGIC; -- 高电平写入 ram
data_im_in : IN STD_LOGIC_VECTOR(Dwidth-1 downto 0);
data_re_in : IN STD_LOGIC_VECTOR(Dwidth-1 downto 0);
wr_adr : IN STD_LOGIC_VECTOR(Awidth-1 downto 0);
rd_adr : IN STD_LOGIC_VECTOR(Awidth-1 downto 0);
data_re_out : OUT STD_LOGIC_VECTOR(Dwidth-1 downto 0);
data_im_out : OUT STD_LOGIC_VECTOR(Dwidth-1 downto 0));
END ram22;

architecture blockdram of ram22 is

constant Addepth : natural := 2**Awidth;

type ram_type is array(0 to Addepth-1) of Std_Logic_Vector(Dwidth-1 downto 0);
signal mem0,mem1 : ram_type := (others => (others => '0'));
signal addr_reg0,addr_reg1: std_logic_vector(Awidth-1 downto 0); -- avoid double drives

begin

-- ram0
wr0: process( clock )
begin
if rising_edge(clock) then
if wren = '1' then
mem0(conv_integer(wr_adr)) <= data_re_in;
end if;
end if;
end process wr0;

rd0: process( clock )
begin
if rising_edge(clock) then
addr_reg0 <= rd_adr;
end if;
data_re_out <= mem0(conv_integer(addr_reg0));
end process rd0;
--data_re_out <= mem0(conv_integer(addr_reg0));

-- ram1
wr1: process( clock )
begin
if rising_edge(clock) then
if wren = '1' then
mem1(conv_integer(wr_adr)) <= data_im_in;
end if;
end if;
end process wr1;

rd1: process( clock )
begin
if rising_edge(clock) then
addr_reg1 <= rd_adr;
end if;
end process rd1;
data_im_out <= mem1(conv_integer(addr_reg1));

end blockdram;
尽管使用上面的代码在quartus中综合的时候,quartus也会使用generating altsyncram megafunction to implement对代码进行优化,但是他和直接使用 lpm_ram_dp 例化效果不是一致
直接使用 lpm_ram_dp 例化采用读优先逻辑,而上面的代码使用的是写优先逻辑

呵呵,lz还比较仔细,我认为ram的读写还是由wren 决定的

wr0: process( clock )
begin
if rising_edge(clock) then
if wren = '1' then 这里有判断wren的值,而对应的rd程序就没有。就是在clock上升沿且wren=1时写数,而rd段没有这个限制,只要clock上升就可以读出数据。因为是双端的,不会有地址数据冲突的现象。所以我个人觉得谁优先没有关系,吧wren控制好就可以了。
mem0(conv_integer(wr_adr)) <= data_re_in;
end if;
end if;
end process wr0;

rd0: process( clock )
begin
if rising_edge(clock) then
addr_reg0 <= rd_adr;
end if;
data_re_out <= mem0(conv_integer(addr_reg0));
end process rd0;
--data_re_out <= mem0(conv_integer(addr_reg0));

[此贴子已经被作者于2007-12-6 14:23:12编辑过]

这个版主不太冷 =========================== 我的中电网博客:http://blog.chinaecnet.com/u/20/index.htm
返回列表