vhdl中的索引约束冲突

vhdl中的索引约束冲突,vhdl,simulation,fifo,digital-logic,Vhdl,Simulation,Fifo,Digital Logic,我的代码模拟有问题。我有一个由双端口内存组成的异步FIFO。写入操作与写入时钟同步执行,读取操作提供我要读取的位置的地址。同步由读写指针执行 基本上我有这样的东西: architecture rtl of async_memory is type RAM is array (MEM_DEPTH - 1 downto 0) of std_logic_vector(DATAWIDTH - 1 downto 0); signal memory : RAM; begin

我的代码模拟有问题。我有一个由双端口内存组成的异步FIFO。写入操作与写入时钟同步执行,读取操作提供我要读取的位置的地址。同步由读写指针执行

基本上我有这样的东西:

architecture rtl of async_memory is 
     type RAM is array (MEM_DEPTH - 1 downto 0) of std_logic_vector(DATAWIDTH - 1 downto 0);
     signal memory : RAM;

begin
     MEM_WRITE:process(clk,rstn)
     begin
     .....
        memory(to_integer(unsigned(addr_wr_i))) <= data_i;
     .....
     end process;

     MEM_READ:data_o <= memory(to_integer(unsigned(addr_rd_i)));
MEM_READ:data_o <= memory(to_integer(unsigned(addr_rd_i)) mod MEM_DEPTH);
异步内存的体系结构rtl是 RAM类型是标准逻辑向量(数据宽度-1到0)的数组(内存深度-1到0); 信号存储器:RAM; 开始 内存写入:进程(clk、rstn) 开始 ..... 内存(到整数(无符号(addr\u wr\u i)))1111->1000 现在的问题是:有没有办法避免模拟错误?我是这样想的:

architecture rtl of async_memory is 
     type RAM is array (MEM_DEPTH - 1 downto 0) of std_logic_vector(DATAWIDTH - 1 downto 0);
     signal memory : RAM;

begin
     MEM_WRITE:process(clk,rstn)
     begin
     .....
        memory(to_integer(unsigned(addr_wr_i))) <= data_i;
     .....
     end process;

     MEM_READ:data_o <= memory(to_integer(unsigned(addr_rd_i)));
MEM_READ:data_o <= memory(to_integer(unsigned(addr_rd_i)) mod MEM_DEPTH);

MEM\u READ:data\u o为synth和sim保留相同的文件

使用和不使用“mod MEM_深度”进行合成。如果它们大小相同,则综合优化已删除MOD运算符。。。那么,没问题

我的首选方法是:编写一个“to_address”函数,执行所有类型转换,返回一个有效地址。将包含MOD运算符的返回语句包装在
--pragma translate off
--pragma translate on
之间(有关实际接受的语法,请咨询synth工具)。然后是一个简单的返回语句

请注意,读和写地址可能首先声明为未签名。任何时候在级联类型转换时,设计都可能有问题

function to_address(addr : unsigned) return natural is
   temp : natural := to_integer(addr);
begin
   --pragma translate off
   return temp mod MEM_DEPTH;
   --pragma translate on
   return temp;
end to_address.

然后模拟将命中第一个
返回
,而合成将进入第二个。注释出来,并坚持手动检查此函数来检查代码时间…

抛开为什么有人想对零时间模型应用时间抖动刺激的问题,除了使用函数调用“过滤”地址之外,还有另一种解决方案

异步RAM使用的经典模型包括一个读启用,它通过要求地址在读启用为真时保持稳定来降低功耗。EMI的降低也与节能齐头并进。这同样适用于真正的异步写入端口,该端口要求非时钟写入通过仅在地址稳定时发生的写入启用发出信号。时钟读写很容易,假设地址在时钟边缘是稳定的

VHDL中的默认模型是惯性延迟,它对切换延迟进行建模——与OP相关,所有地址“位”不会同时传播,从而在内存大小不是2的幂次方时导致零时间内存模型的索引范围超出范围

惯性延迟还有一个拒绝时间,用于消除比拒绝时间短的脉冲。要求拒绝时间小于相关延迟,并且拒绝时间默认为信号分配的第一个波形元素(可以是唯一元素)中指定的延迟时间

(参见IEEE标准1076-2008 10.5.2简单信号分配。)

信号更新在VHDL中计划在投影输出波形队列中,该队列包含值更新的值和时间

我们不能简单地用拒绝时间安排数据更新,因为排队的值需要读取当前内存内容

我们可以使用惯性延迟模型滤除读加输入上的开关噪声,该模型基于其抑制极限

由于索引内存读取需要整数(或自然)索引,因此可以添加另一个信号,保持读取地址的整数值并执行脉冲抑制(以及等于或大于拒绝时间表达式的分配延迟)

除此之外,IEEE Std 1076.6-2004(RTL合成,现已撤销)是支持合成结构生产硬件的基础。合成供应商仍将以此为起点。在8.8.4信号分配语句中,我们可以看到延迟机制被忽略。after和after后面的时间表达式也被忽略(8.8.4.1)

因此,我们可以将计时添加到零时间模型中,以支持模拟中的脉冲抑制:

architecture fum of async_memory is
    type RAM is array (MEMDEPTH - 1 downto 0) of 
            std_logic_vector(DATAWIDTH - 1 downto 0);
    signal memory:  RAM;
    signal addr_rd: natural;
begin

MEM_WRITE:
    process( clk, rstn)
    begin
        if rstn = '0' then
            memory <= (others => (others => '0'));
        elsif rising_edge(clk) then
            if wen = '0' then
                memory(to_integer(unsigned(addr_wr_i))) <= data_i;
            end if;
        end if;
    end process;
MEM_READ:
    data_o <= memory(addr_rd);
PULSE_REJECT:
    addr_rd <= reject 1.8 ns inertial to_integer(unsigned(addr_rd_i)) after 1.9 ns;
end architecture;
异步内存的架构fum是 类型RAM是的数组(MEMDEPTH-1到0) 标准逻辑向量(数据宽度-1到0); 信号存储器:RAM; 信号地址:自然; 开始 请记住: 工艺(clk、rstn) 开始 如果rstn='0',则 内存(其他=>0'); elsif上升沿(clk)则 如果wen='0',则 内存(到整数(无符号(addr\u wr\u i)))