【问题标题】:VHDL Parametric caseVHDL 参数化案例
【发布时间】:2015-01-24 19:31:15
【问题描述】:

我的合成工具有问题。我正在编写一个模块,并试图使其参数化和可扩展。在我的设计中,我有一个 FSM 和一些计数器。计数器具有参数宽度(它们是数据路径宽度的函数)。问题是我正在使用该计数器来驱动案例陈述。合成器给了我这个错误:

2049990 错误 - (VHDL-1544) 数组类型 case 表达式必须是本地静态子类型

我也尝试过使用子类型,但它不起作用。声明是:

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。我读过我可以使用变量,但我想找到一个不同的解决方案,如果它存在的话。我无法想象在合成之前没有任何方法可以为合成器提供参数。

【问题讨论】:

  • 哪一行代码会引发错误?另外,你说综合给出了错误......你确定这在模拟中正常工作吗?
  • @BrianDrummond - case type_counter_word'(counter_word) is 引发错误,这不是唯一的综合问题,而是如何确保案例覆盖率,不,它在模拟中不起作用。表达式的类型必须是局部静态的以确保选择覆盖,如果 WIDTH_DATA 或 WIDTH_WORD 是全局静态而非局部静态的泛型,则声明为 type_counter_word 的变量将不起作用。

标签: vhdl hardware


【解决方案1】:

这在 VHDL-2008 中已修复。您只能通过使用级联 if 语句(使用伴随的优先级逻辑)在早期标准中解决它。在确定选择是否是局部静态的时,变量不会产生影响。

【讨论】:

  • 如果我使用 if 语句,我的设计会变慢......对吗?避免这种情况的唯一方法是对数据路径宽度使用固定数字,或更改综合工具。
  • 这取决于所涉及的逻辑。如果您只是使用单一案例测试所有案例,而其他案例则像您的示例中那样捕获其余案例,那么与为 if-else 合成的逻辑相比,没有有效的区别。优先逻辑仅在您有多个案例要评估时才起作用,即使那样它也不总是关键路径的一部分。如果是,您可以注册比较并在下一个周期测试布尔结果。
  • 如果您的目标是具有宽 LUT 的现代 FPGA,实现 if-elsif-else 优先级逻辑的多个级联多路复用器往往会映射到单个 LUT,在这种情况下,没有真正的速度差异与由 case 语句合成的解码器相比。数字逻辑最小化的许多“规则”假设目标是离散门、ASIC 或类似物,它们并不总是适用于 FPGA。
【解决方案2】:

我不确定您的do_stuff()do_other_stuff() 操作有多复杂,但如果您只是进行简单的信号分配,您可以查看ieee.std_logic_misc 库中的and_reduce() 函数。

举个例子:

output <= '1' when and_reduce(type_counter_word'(counter_word)) = '1' else '0';

否则,正如 Kevin 的回答所暗示的,使用 if 语句的进程块可能是您的最佳选择。

【讨论】:

  • 我有几个案例陈述,他们通常不会只有 2 个可能的案例,但更多,所以我不能使用 and_reduce 并且我不确定 and_reduce() 可以解决问题.
【解决方案3】:

关于凯文的回答足够好的时间,我写了这个来证明:

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 限定表达式

限定表达式是一种基本操作(参见 5.1),用于显式声明作为表达式或聚合的操作数的类型,可能还有子类型。

这个例子分析、阐述和模拟,但什么都不做。它将调用顺序过程语句 do_other_stuff,它什么也不做。

(对于 do_stuff 和 do_other 内容,不允许使用空接口列表)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-10
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多