0

我有一个 FIFO,它的大小是根据包中的参数确定的:

signal fifo : std_logic_vector(FIFO_SIZE*8 -1 downto 0);

我还有一个 4 位向量 (numOfBytes),表示在任何给定时间 FIFO 中有多少字节(最多 8 个)。
我希望根据 numOfBytes 信号确定 FIFO 中的数据输出(单个字节):
Do <= fifo(to_integer(unsigned(numOfBytes)*8 -1 downto to_integer(unsigned(numOfBytes)*8 -8) when numOfBytes /= x"0" else (others => '0');
在模拟时,这很好用,但是当我尝试合成它(使用 Synopsys DC)时,我在链接设计时得到一个详细说明错误“需要恒定值 (ELAB-922)”。

ELAB 代码的意思是“出现此错误消息是因为 RTL 描述的指示行中的表达式未按照语言要求计算为常量值。”

我还能如何制作输出多路复用器以便它进行合成?如果不是参数,我会将 Do 行更改为常规多路复用器,但它不能与参数一起使用。(当 fifo 为 4 字节时,我不能调用 fifo(63 downto 54)...)

ps 我一开始尝试使用 conv_integer ,但由于在网上找到了答案,所以改为 to_integer(unsigned()) 。

4

3 回答 3

2

用于构造范围的信号索引必须是编译时常量,以便综合接受它们。

有两种方法可以解决这个问题:

1) 更改您的 FIFO 以使用数组。这是声明任何形式的内存(例如 FIFO)的标准方式。

type fifo_type is array(0 to FIFO_SIZE-1) of std_logic_vector(8-1 downto 0);
signal fifo : fifo_type;
...
Do <= fifo(to_integer(unsigned(numOfBytes))-1) when(numOfBytes/=0) else (others=>'0');

2)使用循环将变量转换为常量。这是编写通用多路复用器的常用方法。

Do <= (others=>'0');
for i in 0 to FIFO_SIZE-1 loop
    if(numOfBytes=i+1) then
        Do <= fifo((i+1)*8-1 downto i*8);
    end if;
end loop;

我会推荐第一种方法用于较大的、基于内存的 FIFO,而第二种方法用于较小的、基于寄存器的 FIFO。

于 2013-10-02T12:37:55.397 回答
1

如果使用多个字节创建的 FIFO,而不是将其组合成相同的,std_logic_vector则 Synopsys DC 可能能够处理它。代码可能如下所示:

library ieee;
use ieee.numeric_std.all;

architecture syn of mdl is

  ... Declaration of FIFO_SIZE natural constant

  type fifo_t is array(natural range <>) of std_logic_vector(7 downto 0);
  signal fifo : fifo_t(FIFO_SIZE - 1 downto 0);

begin

  ... Handling FIFO insert and remove

  Do <= fifo(to_integer(unsigned(numOfBytes))) when numOfBytes /= x"0" else (others => '0');

end architecture;
于 2013-10-02T12:38:15.033 回答
0

如果您不需要 FIFO 的运行时动态大小,generic请在您的实体上使用 a。

如果你真的需要一个动态大小的 FIFO,你将不得不像其他人所说的那样在进程中使用循环。但是要非常小心你如何使用这样的 FIFO,就好像你在有人读或写的时候改变它的大小一样,可能会发生不好的事情!

于 2013-10-04T10:55:34.707 回答