Modelsim与Quartus全局静态错误争议:谁的处理合规?
咱们先还原一下你遇到的场景:你写了一段VHDL代码,把单个信号和三位信号拼接后,作为子模块的四位输入端口实参。这段代码如下:
library ieee; use ieee.std_logic_1164.all; entity submodule is port( four_bits_input : in std_logic_vector(3 downto 0); four_bits_output : out std_logic_vector(3 downto 0) ); end entity; architecture behav of submodule is begin four_bits_output <= four_bits_input; end architecture; ------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity globally_static_test is port ( one_bits_input : in std_logic; three_bits_input : in std_logic_vector(2 downto 0); four_bits_output : out std_logic_vector(3 downto 0) ); end entity; architecture behav of globally_static_test is begin submodule_inst : entity work.submodule port map( four_bits_input => one_bits_input & three_bits_input -- Modelsim Error is here. ,four_bits_output => four_bits_output ); end architecture;
这段代码在Quartus Prime 17.1(采用VHDL 1993标准)里能顺利完成综合和适配,但在Modelsim v10.5b Intel FPGA Starter Edition(默认VHDL 2002标准)里编译时触发了错误:
(vcom-1436) Actual expression (infix expression) of formal "four_bits_input" is not globally static.
而且这种拼接赋值的方式在很多项目里都常用,你想知道到底哪个工具的处理符合VHDL规范对吧?
核心原因:VHDL版本规范的差异
要搞清楚这个问题,得先明确**全局静态表达式(globally static expression)**的定义:VHDL标准里,这类表达式的值在编译阶段就能完全确定,不需要等到仿真或硬件运行时才能计算。
1. 旧版VHDL(1993/2002)的规则
在VHDL 1993和2002版本中,对于模块实例化的端口映射,当形式端口是in模式时,实参如果是一个表达式(而非直接的信号名),标准要求这个表达式必须是全局静态表达式。而你代码里的one_bits_input & three_bits_input是两个信号的拼接,信号的值是运行时动态变化的,所以这个表达式不属于全局静态表达式——Modelsim在VHDL 2002模式下报错,是严格遵循旧版规范的行为。
2. Quartus为什么能通过?
综合工具(比如Quartus)和仿真工具(比如Modelsim)的定位完全不同:
- 仿真工具需要严格遵循VHDL的仿真语义规则,确保代码的行为在仿真阶段完全符合标准定义;
- 综合工具的目标是把代码映射成可实现的硬件电路,只要代码的硬件逻辑意义明确(这里就是把两个信号直接布线拼接成4位输入,硬件上完全可行),它就会接受这种写法,不会像仿真工具那样严格执行静态表达式的检查。
所以Quartus的通过并不代表它违反规范,只是工具侧重点不同导致的差异。
3. VHDL 2008的放宽规则
你提到把Modelsim的编译选项改成VHDL 2008后错误消失,这正好对应了新版标准的变化:VHDL 2008放宽了端口映射实参的限制,允许非全局静态的表达式作为in端口的实参——这种拼接信号的写法在新版规范里是完全合法的。
结论
- 从严格的旧版VHDL(1993/2002)规范来看,Modelsim的报错是符合规范的;
- Quartus的通过是综合工具的特性,它更关注硬件可实现性而非仿真语义的严格检查,这是合理的工具行为;
- 如果要同时兼容仿真和综合,推荐统一使用VHDL 2008标准,这样既能让Modelsim正常编译,也能在Quartus里顺利综合,而且这种拼接写法本身在新版规范里是被允许的。
内容的提问来源于stack exchange,提问作者grorel

