我的VHDL代码中有一个断言,用于验证通过组件实体传递的泛型。断言的严重性设置为FAILURE,因为如果泛型被滥用,我想退出模拟。当使用Active-HDL进行模拟时(实际上是任何版本,但我特别使用版本12-14a),当泛型被滥用并且模拟在执行任何其他操作之前退出时,会触发断言。然而,当使用ModelSim DE进行模拟时(我只尝试了10.6c,32位),断言不是第一个被评估的东西,并且对于与值相关的不同数组长度的信号分配会出现不同的错误泛型(这就是断言存在的原因)。这是我的MCVE:
example.vhd
:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic
(
INPUT_LEN : integer := 4;
OUTPUT_LEN : integer := 5
);
port
(
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0)
);
end entity example;
architecture rtl of example is
begin
-- We want this evaluated first.
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
-- This is actually what is evaluated first.
my_output <= my_input;
end architecture rtl;
正如您所看到的,my_output
和my_input
受到泛型值的影响,我希望首先发生断言,以便将有用的错误消息打印到控制台,而不是当前的Fatal: (vsim-3420) Array lengths do not match. Left is 32 (31 downto 0). Right is 8 (7 downto 0).
。
我使用以下两个ModelSim命令编译和模拟:
vcom -work work example.vhd
vsim -c -lib work example
我的问题是,是否有vsim
指令强制ModelSim首先评估断言?或者更广泛地说,一个命令,它会在执行之前查找和评估断言还有什么呢?似乎Active-HDL默认情况下会这样做,但是ModelSim没有...我已经浏览了vsim
的文档,我试过-immedassert
标志但这并没有改变任何事情。
我也在使用非常古老的代码,这些代码在很多不同的地方使用(显然比我的MCVE复杂得多),所以最好的解决方案是不来修改源代码。
感谢您的帮助。
答案 0 :(得分:2)
所有并发语句都在流程语句或流程语句和块语句中详细说明。两个并发语句,信号分配和断言没有保证执行顺序。依靠实现定义的明显排序会导致非便携式设计描述。
仍然可以订购断言。在阐述过程中可以得到断言。
这可以通过添加(在这种情况下)一个函数来证明,该函数返回一个布尔值作为一个永远不会被使用的对象的初始值(并且在合成期间将被消除):
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic
(
INPUT_LEN : integer := 4;
OUTPUT_LEN : integer := 5
);
port
(
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0)
);
end entity example;
architecture rtl of example is
function is_it_safe return boolean is
begin
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
return TRUE;
end function;
constant safe: boolean := is_it_safe;
begin
-- We want this evaluated first
assert (INPUT_LEN = OUTPUT_LEN)
report " ORIGINAL INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
-- This is actually what is evaluated first.
my_output <= my_input;
end architecture rtl;
泛型的默认值允许对代码进行分析,详细说明和模拟(仅作为最小,完整和可验证的示例)。
原始断言中的报告消息已更改,以便在任何实施不包含行号时进行识别。
因为这两个泛型具有不同的默认值,所以它可以保证引起断言:
ghdl -a example.vhdl
ghdl -e example
ghdl -r example
example.vhdl:20:9:@0ms:(assertion failure): INPUT_LEN and OUTPUT_LEN must be equal!
./example:error: assertion failed
./example:error: error during elaboration
第20行是函数is_it_safe。
对于Modelsim的排序将成立,因为在模拟初始化之前会对对象进行详细说明(现在出现一个错误或另一个错误)。参见IEEE Std 1076-2008 14.4阐述声明,14.4.2.5对象声明和14.7模型的执行,14.7.5.2初始化。
这里的想法是建立一个有序的单个执行断言,该断言最初是一个并发语句(它被详细描述为一个没有敏感性列表的进程和一个没有子句的最终wait语句,参见11.5并发断言语句。) / p>
注意到目前为止没有答案回答关于如何影响Modelsim中流程执行顺序的狭隘问题。
不应该命令并发语句执行。在模拟开始时(14.7.5.2)暂停执行的所有进程列表的顺序将是实现定义和非可移植的。原版海报已经证明了这一点。
在精化过程中使用的函数中移动断言或提供新副本可以保证在初始化期间任何赋值语句之前执行断言语句。
还要注意,断言测试相同类型的两个常量值的相等性的想法可以被视为一种反模式,就像JHBonarius所评论的那样。编程中采用的修复方法与硬件描述几乎没有关系,只是在缺少标准化错误消息时才产生特定的消息。
VHDL已经捕获了原始代码中的错误,尽管需要VHDL或工具实现熟悉。
通过提供对象值的函数中的断言,可以消除并发断言语句。
答案 1 :(得分:0)
您可以通过将其置于流程中来实现顺序处理。例如:
library ieee;
use ieee.std_logic_1164.all;
entity example is
generic (
INPUT_LEN : integer := 5;
OUTPUT_LEN : integer := 6);
port (
my_input : in std_logic_vector(INPUT_LEN-1 downto 0);
my_output : out std_logic_vector(OUTPUT_LEN-1 downto 0));
end entity;
architecture rtl of example is
begin
assign_my_output: process(my_input) begin
assert (INPUT_LEN = OUTPUT_LEN)
report "INPUT_LEN and OUTPUT_LEN must be equal!"
severity FAILURE;
my_output <= my_input;
end process;
end architecture rtl;
vcom -work work example.vhd
vsim work.example
运行1 ns
#**失败:INPUT_LEN和OUTPUT_LEN必须相等!
答案 2 :(得分:-1)
VHDL是一种强类型语言。我不确定Modelsim
的构造可以让你先运行断言。
您可以尝试输入my_output&lt; = my_input作为my_output <= std_logic_vector(my_input)
这将让Modelsim模拟您的设计,但只要您尝试RUN
您的设计,它就会抛出错误。
如果没有类型转换,它甚至不会让你模拟你的设计。