VHDL 参数化案例
VHDL Parametric case
我的综合工具有问题。我正在编写一个模块,并试图使其参数化和可扩展。在我的设计中,我有一个 FSM 和一些计数器。计数器具有参数宽度(它们是数据路径宽度的函数)。问题是我正在使用该计数器来驱动案例陈述。合成器给我返回这个错误:
2049990 ERROR - (VHDL-1544) array type case expression must be of a locally static subtype
我也尝试过使用子类型,但它不起作用。声明是:
constant LENGTH_COUNTER_WORD : integer := integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
案例:
case type_counter_word'(counter_word) is
when (others => '1') =>
do_stuff();
when others =>
do_other_stuff();
end case;
我无法切换到 VHDL-2008。我读过我可以使用变量,但我想找到一个不同的解决方案(如果存在的话)。我无法想象在合成之前没有任何方法可以给合成器参数。
这已在 VHDL-2008 中修复。您只能通过使用级联 if
语句(使用附带的优先级逻辑)在早期标准中解决它。在确定选择是否为局部静态时,变量不会产生影响。
我不确定你的 do_stuff()
和 do_other_stuff()
操作有多复杂,但如果你只是做简单的信号分配,你可以查看 and_reduce()
中的函数ieee.std_logic_misc
图书馆。
举个例子:
output <= '1' when and_reduce(type_counter_word'(counter_word)) = '1' else '0';
否则,正如 Kevin 的回答所暗示的那样,使用 if
语句的流程块可能是您的最佳选择。
关于凯文的回答足够好,我写了这个来证明:
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
entity counterword is
generic (
WIDTH_DATA: positive := 16;
WIDTH_WORD: positive := 8
);
end entity;
architecture foo of counterword is
constant LENGTH_COUNTER_WORD : integer :=
integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is
std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
procedure do_stuff is
begin
end;
procedure do_other_stuff is
begin
end;
begin
UNLABELLED:
process (counter_word)
begin
-- case type_counter_word'(counter_word) is
-- when (others => '1') =>
-- do_stuff;
-- when others =>
-- do_other_stuff;
-- end case;
if counter_word = type_counter_word'(others => '1') then
do_stuff;
else
do_other_stuff;
end if;
end process;
end architecture;
请注意,因为 type_counter_word 是子类型,您可以在聚合的限定表达式中提供子类型约束:
if counter_word = type_counter_word'(others => '1') then
来自 IEEE 标准 1076-2008:
9.3.5 Qualified expressions
限定表达式是一种基本操作(参见 5.1),用于显式声明作为表达式或聚合的操作数的类型,可能还有子类型。
这个例子分析、阐述和模拟,什么都不做。它将调用顺序过程语句 do_other_stuff,它什么也不做。
(对于 do_stuff 和 do_other 内容,不允许使用空接口列表)。
我的综合工具有问题。我正在编写一个模块,并试图使其参数化和可扩展。在我的设计中,我有一个 FSM 和一些计数器。计数器具有参数宽度(它们是数据路径宽度的函数)。问题是我正在使用该计数器来驱动案例陈述。合成器给我返回这个错误:
2049990 ERROR - (VHDL-1544) array type case expression must be of a locally static subtype
我也尝试过使用子类型,但它不起作用。声明是:
constant LENGTH_COUNTER_WORD : integer := integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
案例:
case type_counter_word'(counter_word) is
when (others => '1') =>
do_stuff();
when others =>
do_other_stuff();
end case;
我无法切换到 VHDL-2008。我读过我可以使用变量,但我想找到一个不同的解决方案(如果存在的话)。我无法想象在合成之前没有任何方法可以给合成器参数。
这已在 VHDL-2008 中修复。您只能通过使用级联 if
语句(使用附带的优先级逻辑)在早期标准中解决它。在确定选择是否为局部静态时,变量不会产生影响。
我不确定你的 do_stuff()
和 do_other_stuff()
操作有多复杂,但如果你只是做简单的信号分配,你可以查看 and_reduce()
中的函数ieee.std_logic_misc
图书馆。
举个例子:
output <= '1' when and_reduce(type_counter_word'(counter_word)) = '1' else '0';
否则,正如 Kevin 的回答所暗示的那样,使用 if
语句的流程块可能是您的最佳选择。
关于凯文的回答足够好,我写了这个来证明:
library ieee;
use ieee.std_logic_1164.all;
use ieee.math_real.all;
entity counterword is
generic (
WIDTH_DATA: positive := 16;
WIDTH_WORD: positive := 8
);
end entity;
architecture foo of counterword is
constant LENGTH_COUNTER_WORD : integer :=
integer(ceil(log2(real(WIDTH_DATA/WIDTH_WORD))));
subtype type_counter_word is
std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
signal counter_word : std_logic_vector( LENGTH_COUNTER_WORD - 1 downto 0);
procedure do_stuff is
begin
end;
procedure do_other_stuff is
begin
end;
begin
UNLABELLED:
process (counter_word)
begin
-- case type_counter_word'(counter_word) is
-- when (others => '1') =>
-- do_stuff;
-- when others =>
-- do_other_stuff;
-- end case;
if counter_word = type_counter_word'(others => '1') then
do_stuff;
else
do_other_stuff;
end if;
end process;
end architecture;
请注意,因为 type_counter_word 是子类型,您可以在聚合的限定表达式中提供子类型约束:
if counter_word = type_counter_word'(others => '1') then
来自 IEEE 标准 1076-2008:
9.3.5 Qualified expressions
限定表达式是一种基本操作(参见 5.1),用于显式声明作为表达式或聚合的操作数的类型,可能还有子类型。
这个例子分析、阐述和模拟,什么都不做。它将调用顺序过程语句 do_other_stuff,它什么也不做。
(对于 do_stuff 和 do_other 内容,不允许使用空接口列表)。