VHDL通用比较与综合
VHDL generic comparison and 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_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;
继续,我想知道具有通用宽度 (OUTWIDTH) 的信号的所有位是否都是“1”。前面的代码在模拟中运行良好,但不希望被综合。
为 Libero 合成:
@E:CD289:期待常量表达式
我想我可以用一个函数来做到这一点(在每个位上循环并与“1”进行比较)但是还有其他 "direct" 选项吗?
谢谢。
虽然你的问题没有得到minimal complete verifiable example的支持,因此很难正确帮助你,我可以做一个假设。
首先:编写正确模拟但不会综合的VHDL 非常容易。你必须专门为综合写VHDL。
合成器给出的问题可能是由变量 v1
引起的。合成这条线有点困难:
if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL)
这一行结合了可变(=异步)算术(例如v1*(OUTWIDTH/8)
与多路复用器和比较操作。您希望如何在逻辑上实现它?首先多路复用,然后比较?所有比较和那么 select 正确的结果?
可能最好将操作分开:实现多路复用器(select 使用信号,而不是变量)和比较器。
一些合成器将无法使用非常量值来指示切片的范围。您可以做的一件事(其中的几件事)是将您的数组映射到一个二维数组,并使用您的非常量索引来访问您想要的内容,而无需任何特殊切片。
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
此外,使用变量通常不是一个好主意,但我不会在这里深入探讨。公平警告,我只是在答案框中写了这段代码。它可能有轻微的语法错误。
我在使用泛型合成代码时遇到问题: 我的实体是:
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;
继续,我想知道具有通用宽度 (OUTWIDTH) 的信号的所有位是否都是“1”。前面的代码在模拟中运行良好,但不希望被综合。 为 Libero 合成: @E:CD289:期待常量表达式
我想我可以用一个函数来做到这一点(在每个位上循环并与“1”进行比较)但是还有其他 "direct" 选项吗?
谢谢。
虽然你的问题没有得到minimal complete verifiable example的支持,因此很难正确帮助你,我可以做一个假设。
首先:编写正确模拟但不会综合的VHDL 非常容易。你必须专门为综合写VHDL。
合成器给出的问题可能是由变量 v1
引起的。合成这条线有点困难:
if(keep((v1+1)*(OUTWIDTH/8)-1 downto v1*(OUTWIDTH/8)) = KEEP_VAL)
这一行结合了可变(=异步)算术(例如v1*(OUTWIDTH/8)
与多路复用器和比较操作。您希望如何在逻辑上实现它?首先多路复用,然后比较?所有比较和那么 select 正确的结果?
可能最好将操作分开:实现多路复用器(select 使用信号,而不是变量)和比较器。
一些合成器将无法使用非常量值来指示切片的范围。您可以做的一件事(其中的几件事)是将您的数组映射到一个二维数组,并使用您的非常量索引来访问您想要的内容,而无需任何特殊切片。
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
此外,使用变量通常不是一个好主意,但我不会在这里深入探讨。公平警告,我只是在答案框中写了这段代码。它可能有轻微的语法错误。