【问题标题】:VHDL 2008 and CASE statementVHDL 2008 和 CASE 声明
【发布时间】:2015-03-18 10:02:44
【问题描述】:

我有一个关于案例陈述和 VHDL 2008 的问题。我有一个以这种方式定义的实体:

entity multiplier_v2 is
generic(    WIDTH_WORD  : integer := 32;
            WIDTH_RSA   : integer := 2048;
            LENGTH_ADDRESS : integer := 6 );
port (
    reset                   :   in std_logic;
    clk                     :   in std_logic;
    start                   :   in std_logic;
    input_1                 :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    input_2                 :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    module                  :   in std_logic_vector(WIDTH_WORD - 1 downto 0);
    output                  :   out std_logic_vector(WIDTH_WORD - 1 downto 0);
    ack_data                :   out std_logic;
    data_valid              :   out std_logic;
    new_module              :   in std_logic;

在模块内部,我以这种方式声明了一个信号:

signal counter_ack                  : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);

我在 case 语句中使用了这个信号:

case counter_ack is
when (others => '1') =>
    ack_data <= '0';
when others => 
    counter_ack <= counter_ack + 1;
end case;

现在,我很确定我的综合工具中启用了 VHDL-2008 选项,但我的代码的那部分出现以下错误:

2049990 错误 - E:/My_Designs/Custom Module/Montgomery_Multiplier/Diamond/src/multiplier_v2.vhd(456,6-461,15) (VHDL-1544) 数组类型案例表达式必须是本地静态子类型

我读到这个错误应该在 VHDL-2008 中修复。有什么想法吗?

【问题讨论】:

  • 我不确定它在 VHDL-2008 中是否合法(即使某些工具可能会接受它),因为范围不受限制。 IMO,您最好使用“if counter_ack = 2**counter_ack'length-1 then ack_data
  • @JonathanDrolet 感谢您的帮助。其实不知道合法不合法。我在许多论坛中看到这是一个建议的解决方案。我可以使用 if 语句,但它在综合方面与案例不同(我的源代码中有几个类似的案例)。那我真的不明白哪里出了问题。当我将组件放在我的 VHDL 源代码中时,合成器知道信号的大小。它不是不受约束的。那为什么用“如果”应该可以而用“案例”不行呢?也许我的错是作为一个 C 程序员来思考。
  • VHDL 是强类型的(C 不是),旨在在编译时捕获尽可能多的错误。尽管代码应该如何解释很清楚,但 VHDL 要求您明确编写它,以防万一。隐式类型转换之类的东西存在于 C 中,但不存在于 VHDL 中。 VHDL-2008 软化了迂腐,但永远不会消除它。我的 if 代码行将 std_logic_vector(我假设您使用 ieee.numeric_std_unsigned)与一个整数进行比较,这是合法的,因为有一个重载的比较运算符。
  • @haster8558,如果您使用这样的 case 语句,它将产生与 if 语句相同的结果。您可能会考虑发布更多代码。你如何重置计数器?你可以考虑减到 0。
  • 您可以考虑限制选项的大小。 (LENGTH_ADDRESS -1 到 0 => '0')

标签: vhdl hardware fpga


【解决方案1】:

我使用 VHDL 2008 编译器选项在 Quartus II 中编译了下面显示的代码。我没有错误。您的案例陈述是否正在处理中?

LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_signed.all;

ENTITY casestate IS
generic(    WIDTH_WORD  : integer := 32;
            WIDTH_RSA   : integer := 2048;
            LENGTH_ADDRESS : integer := 6 );
port (
    reset                   :   in std_logic;
    clk                     :   in std_logic;
    ack_data                :   out std_logic
     );
END casestate;

ARCHITECTURE fpga OF casestate IS
    signal counter_ack                  : std_logic_vector(LENGTH_ADDRESS - 1 downto 0);

BEGIN

process(clk,reset)
begin
if(reset = '0')then
    ack_data <= '0';
elsif(rising_edge(clk))then
    case counter_ack is
        when (others => '1') =>
            ack_data <= '0';
        when others => 
            counter_ack <= counter_ack + 1;
            ack_data <= '1';
        end case;
end if;
end process;
end fpga;

【讨论】:

  • 是的,它正在处理中。在我看来,Diamond(莱迪思半导体 IDE)很烂。我对 synplify 也没有错误。 VHDL-2008 处理不好。我可以选择 Diamond 中的合成工具(Synplify 或 Lattice 合成工具)。第一个工作,第二个没有。现在我想如果我想使用 Lattice 逻辑分析仪,我一定不能使用 VHDL-2008。
  • @Nicolas,请不要使用“std_logic_signed”包。你打算用 counter_ack 做什么来重置它?按照编码,您的设计需要在复位期间将 counter_ack 保持在其当前值。这会将您的复位信号连接到功能逻辑,这可能会产生问题 WRT 全局复位线。
  • @Jim 我写这段代码只是为了测试编译器是否给我错误。我真的不在乎这段代码是否有意义,但你是对的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 2012-11-29
  • 2015-10-06
相关资源
最近更新 更多