Quartus II中的推断锁存器必然是透明的

时间:2015-06-09 09:03:56

标签: vhdl fpga synthesis quartus

我有一个应该代表分布式RAM"的模块,其中多个寄存器可以并行写入并通过单个MUX读取。 一个最小的例子是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity memory is 
    port
    (
        i_clk               : in  std_logic;
        i_reset_n           : in  std_logic;
        i_write_en          : in  std_logic;
        i_some_condition    : in  std_logic;
        i_other_condition   : in  std_logic;
        i_data              : in  std_logic_vector(15 downto 0);
        i_addr              : in  std_logic_vector(3 downto 0);
        o_data              : out std_logic_vector(15 downto 0)
    );
end memory;

architecture synthesis of memory is
    type RAM_T is array (15 downto 0) of std_logic_vector(15 downto 0);
    signal ram : RAM_T;
begin
    p: process(i_clk, i_reset_n)
    begin
        if i_reset_n = '0' then     
            ram <= (others => (others => '0'));
        elsif i_clk'event and i_clk = '1' then
            if i_write_en = '1' then
                if i_some_condition = '1' then
                    ram(1) <= i_data;
                end if;
                if i_other_condition = '1' then
                    ram(2) <= i_data;
                end if;
                -- and so on
            end if;            
        end if;
    end process p;

    o_data <= ram(to_integer(unsigned(i_addr)));
end;

现在,Quartus II(14.1网络版)警告说

  

警告(10631):在memory.vhd(21)处的VHDL过程语句警告:推断信号或变量&#34; ram&#34;的锁存器,它在一个或多个路径中保持其先前的值通过过程

如果我查看RTL和技术地图视图,我只会看到边缘触发的触发器。如果&#34;锁定推断&#34;这意味着&#34;触发推理&#34;,那就是我的意图。 但我怎么能确定&#34; latch&#34;并不意味着&#34;透明锁存器&#34;,即级别sensitiv 存储元件?我怎么能在警告信息中区分这个?

This question是相关的,但是询问为什么会发生这种情况,我会询问术语和使用“&#34; latch&#34;”这个词。)

1 个答案:

答案 0 :(得分:1)

如果可以在:

中分配每个ram位
elsif i_clk'event and i_clk = '1' then
  ...
end if;

你的过程的一部分,那么你的代码很好,这是Quartus错了。这里不应该推断出锁存器。只有具有低有效异步复位功能的DFF。

但是,如果从未分配某些位(例如ram(0)),则根据VHDL语义,这些位仅被分配(并且它们总是被赋值为'0')

  • i_clki_reset_n
  • 上有活动
  • i_reset_n很低。

在恢复您的流程的任何其他情况下(i_clki_reset_ni_reset_n不低的事件),他们会保留其价值。

有几种方法可以解释和实现这种行为(请记住,VHDL模拟语义是由语言参考手册准确定义的,但合成语义远没有很好地定义,并且很大程度上取决于您使用的特定综合工具):

  • 有些合成器可以判断这些位是常数'0'并且应该简化。这种解释在技术上并不正确,因为如果永远不会声明i_reset_n,则永远不会分配这些位,并且应该保留它们的上电值,这不一定是已知的。但是有了一些FPGA目标,这是有道理的。

  • 其他一些合成器可能会认为这是典型的锁存行为,具有低电平有效使能(i_reset_n)和常数'0'输入或等效输入。它们也可能通过为所有这些位仅保留一个锁存器来简化。

我在Vivado 2014.4上尝试了两个版本的代码:

  • 您发布的那个(-- and so on评论); Vivado为ram的224个剩余位推断出32个DFF和一个锁存器。

  • 一种变体,-- and so on评论被一些代码替换,可以分配ram(15 downto 3)ram(0)中的任何一个。 Vivado推断出256个DFF并且没有锁存器。

摘要:检查

中是否可以实际分配ram的每个位
elsif i_clk'event and i_clk = '1' then
  ...
end if;