gpt4 book ai didi

vhdl - 在 VHDL 中实现简单的双端口 block ram 未按预期执行

转载 作者:行者123 更新时间:2023-12-05 02:16:10 25 4
gpt4 key购买 nike

我一直在尝试在 VHDL 中实现一个简单的双端口 block RAM,但它在仿真中没有产生预期的结果。这是代码:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity rams is
generic ( g_adress_width: integer:= 18;
g_ram_size: integer:= 1000
);
port(
clka : in std_logic;
clkb : in std_logic;
wea : in std_logic;
web : in std_logic;
addra : in std_logic_vector(g_adress_width-1 downto 0);
addrb : in std_logic_vector(g_adress_width-1 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;
architecture syn of rams is
type ram_type is array (g_ram_size-1 downto 0) of std_logic_vector(15 downto 0);
signal RAM : ram_type;
begin
process (CLKA)
begin
if CLKA'event and CLKA = '1' then
DOA <= RAM(conv_integer(ADDRA));
if WEA = '1' then --always 0
RAM(conv_integer(ADDRA)) <= DIA; --does not execute
end if;
end if;
end process;

process (CLKB)
begin
if CLKB'event and CLKB = '1' then
DOB <= RAM(conv_integer(ADDRB));
if WEB = '1' then
RAM(conv_integer(ADDRB)) <= DIB;
end if;
end if;

end process;
end syn;

这是模拟:

Simulation

clkaclkb 都连接到同一个时钟。我给 dib 一些任意值(无符号 300 和 355)。

基本上,doa 一直在读取,所以我希望它是未定义的,直到用 dib 将某些内容写入那些 block ram 地址,但它始终显示未定义的值.

我希望发生的事情是 doaaddra 再次为 0 时读取 300,在 addra 为 15 时读取 355 . 像这样(请原谅我的绘画技巧):

enter image description here

如果有人能指出我做错事的正确方向,我将不胜感激。谢谢。

编辑:代码修改为这个并且现在可以工作(感谢 Paebbels 解决方案):

     signal RAM : ram_type; 
begin
process (CLKA)
begin
if CLKA'event and CLKA = '1' then
DOA <= RAM(to_integer(unsigned(ADDRA)));
if WEA = '1' then --always 0
RAM(to_integer(unsigned(ADDRA))) <= DIA; --does not happen
end if;

end if;

if CLKA'event and CLKA = '1' then
DOB <= RAM(to_integer(unsigned(ADDRB)));
if WEB = '1' then
RAM(to_integer(unsigned(ADDRB))) <= DIB;
end if;
end if;

end process;
end syn;

最佳答案

这种对双时钟 RAM 的描述是错误的。您需要使用:

  • 一个有两个时钟的进程,或者
  • 共享变量。

使用一个信号和两个进程是不正确的。它在一个信号上创建多个驱动器。这反过来又造成了多源问题。虽然您的模拟将运行,但由于您的用户定义数组类型中的解析类型 std_logic_vector,综合将失败。

此外,为了允许 BlockRAM 的推断,您需要在 VHDL 代码中表示 BlockRAM 的内部结构。这意味着您需要在地址路径上添加流水线寄存器。

你应该阅读 UG901 - Vivado Synthesis Guide并搜索“RAM HDL 编码技术”。

此外,您应该使用包 numeric_std 而不是 std_logic_unsigned,它不是官方 IEEE 包。


可在 PoC-Library 中找到有效的真双端口 (TDP) BlockRAM 实现: PoC.mem.ocram.tdp .此实现也适用于 Altera/Intel FPGA 和莱迪思 FPGA。

    -- RAM can be inferred correctly only if '-use_new_parser yes' is enabled in XST options
subtype word_t is std_logic_vector(D_BITS - 1 downto 0);
type ram_t is array(0 to DEPTH - 1) of word_t;

signal ram : ram_t;
signal a1_reg : unsigned(A_BITS-1 downto 0);
signal a2_reg : unsigned(A_BITS-1 downto 0);

begin

process (clk1, clk2)
begin -- process
if rising_edge(clk1) then
if ce1 = '1' then
if we1 = '1' then
ram(to_integer(a1)) <= d1;
end if;

a1_reg <= a1;
end if;
end if;

if rising_edge(clk2) then
if ce2 = '1' then
if we2 = '1' then
ram(to_integer(a2)) <= d2;
end if;

a2_reg <= a2;
end if;
end if;
end process;

q1 <= (others => 'X') when SIMULATION and is_x(std_logic_vector(a1_reg)) else
ram(to_integer(a1_reg)); -- returns new data
q2 <= (others => 'X') when SIMULATION and is_x(std_logic_vector(a2_reg)) else
ram(to_integer(a2_reg)); -- returns new data

关于vhdl - 在 VHDL 中实现简单的双端口 block ram 未按预期执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50620480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com