Generics VHDL通用比较与综合

Generics VHDL通用比较与综合,generics,comparison,vhdl,synthesis,Generics,Comparison,Vhdl,Synthesis,我在使用泛型合成代码时遇到了一个问题: 我的实体是: entity MyEntity is generic( OUTWIDTH : integer range 8 to 64; NBREG : integer range 2 to 8); port( port1 .... port2 .... ); end entity; architecture rtl of MyEntity is constant KEEP_VAL : std_logic_vect

我在使用泛型合成代码时遇到了一个问题: 我的实体是:

entity MyEntity is
  generic(
  OUTWIDTH : integer range 8 to 64;
  NBREG : integer range 2 to 8);
  port(
    port1 ....
    port2 ....
  );  
end entity;

architecture rtl of MyEntity is
constant KEEP_VAL : std_logic_vector(OUTWIDTH/8-1 downto 0) := (others=>'1'); -- used to compare my signal with (others=>'1')
signal keep : std_logic_vector((NBREG*OUTWIDTH/8)-1 downto 0);

begin

process(clk)
variable v1 : integer range 0 to NBREG-1
begin
if(rising_edge(clk)) then
   --SOME CODE
   ....
   ....
   -- The comparison I want to do :
  if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL) then  -- the line where the error appears
       -- DO sthg
end if;
end process;
end rtl;
要继续,我想知道具有一般宽度(向外宽度)的信号的所有位是否都是“1”。前面的代码在模拟中运行良好,但不需要合成。 自由人的综合: @E:CD289:应为常量表达式

我假设我可以用一个函数(每个位上的for循环并与'1'比较)来实现它,但是否还有其他“直接”选项


谢谢。

虽然你的问题没有a的支持,因此很难为你提供适当的帮助,但我可以做出一个假设

首先:编写正确模拟但不会合成的VHDL非常容易。您必须专门为合成编写VHDL

合成器出现的问题可能是由变量
v1
引起的。合成这条线有点困难:

if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL)
这条单行线将变量(=异步)算法(例如
v1*(向外/8)
与多路复用器和比较操作结合在一起。您希望如何在逻辑中实现这一点?首先多路复用,然后比较?所有比较,然后选择正确的结果


可能最好将这些操作分开:实现一个多路复用器(使用信号而不是变量进行选择)和一个比较器。

尽管你的问题不受支持,因此很难正确地帮助你,我可以做一个假设

首先:编写正确模拟但不会合成的VHDL非常容易。您必须编写专门用于合成的VHDL

合成器出现的问题可能是由变量
v1
引起的。合成这一行有点困难:

if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL)
这条单行线将变量(=异步)算法(例如
v1*(向外/8)
与多路复用器和比较操作结合在一起。您希望如何在逻辑中实现这一点?首先多路复用,然后比较?所有比较,然后选择正确的结果


可能最好将这些操作分开:实现一个多路复用器(使用信号而不是变量进行选择)和一个比较器。

一些合成器将无法使用非常量值来指示一个片的范围。一件事(几种中的一种)您可以做的是将数组映射到二维数组中,并使用非常量索引访问所需内容,而无需任何特殊切片

type keep_sliced_type is array(natural range <>) of std_logic_vector(outwidth/8-1 downto 0);
signal keep_sliced : keep_sliced_type(0 to nbreg-1);

...

g_map : for i in 0 to nbreg-1 generate
begin
    keep_sliced(i) <= keep(i*outwidth/8+outwidth/8-1 downto i*outwidth/8); --range is composed entirely of constants
end generate;

...

    if keep_sliced(v1)=keep_val then --replaces your erroring line
type keep_sliced_type是标准逻辑向量的数组(自然范围)(向外/8-1向下到0);
信号保持切片:保持切片类型(0至nbreg-1);
...
g_映射:为0中的i生成nbreg-1
开始

keep_sliced(i)某些合成器将无法使用非常量值来指定切片的范围。您可以做的一件事(其中几件)是将数组映射到二维数组中,并使用非常量索引来访问您想要的内容,而无需任何特殊切片

type keep_sliced_type is array(natural range <>) of std_logic_vector(outwidth/8-1 downto 0);
signal keep_sliced : keep_sliced_type(0 to nbreg-1);

...

g_map : for i in 0 to nbreg-1 generate
begin
    keep_sliced(i) <= keep(i*outwidth/8+outwidth/8-1 downto i*outwidth/8); --range is composed entirely of constants
end generate;

...

    if keep_sliced(v1)=keep_val then --replaces your erroring line
type keep_sliced_type是标准逻辑向量的数组(自然范围)(向外/8-1向下到0);
信号保持切片:保持切片类型(0至nbreg-1);
...
g_映射:为0中的i生成nbreg-1
开始

保持分割(i)如果编辑问题以显示错误与比较行关联的行(如果条件),则会很有帮助如果编辑问题以显示错误与比较行关联的行(如果条件),则会很有帮助一般来说,合成不支持由运行时变量指定的范围。你是对的,我认为问题是关于KEEP_VAL常量的,但它是关于KEEP变量的。我改变了过程来修复它。@Thrarry_jeff我曾经为桶形移位器编写了各种实现,并使用XST和Vivado进行合成以进行测试类似这样的行为。在XST中使用非常量范围的方法合成得很好,但在Vivado中产生了类似的错误。@QuantumRipple是的,我有同样的经验,Vivado不支持与ISE相同的方法。我实际上与Xilinx讨论过它。他们改进了一些东西,而不是所有东西。变量不是异步的(这是时钟行为和时序分析的术语)。变量不是静态的。如果我是对的,切片操作需要一个静态表达式。通常,合成不支持由运行时变量指定的范围。你是对的,我认为问题是关于KEEP_VAL常量的,但它是关于KEEP变量的。我更改了过程以修复它。@jeff我曾经写过一个var桶形移位器的实现,并用XST和Vivado合成它们来测试这样的行为。在XST中使用非常量范围的方法合成得很好,但在Vivado中产生了类似的错误。@QuantumRipple是的,我有与Vivado相同的经验,但不支持与ISE相同的方法。我实际上与Xil进行了一些讨论他们改进了一些东西,而不是所有东西。变量不是异步的(这是时钟行为和时序分析的术语)。变量不是静态的。如果我是对的,切片操作需要静态表达式。