system-verilog - 子模块是由求解器独立刺激还是通过连接的顶层模块刺激?
问题描述
我正在尝试通过Dan Gizzelquist的示例练习完成教程。
其中一个练习(练习 4)实现了一个移位寄存器,由两个子模块和一个顶层模块组成。
编辑: 添加练习源代码:
我将在此处发布 vhdl 源代码,如果您更喜欢 verilog,在此链接的 exercise-04 文件夹中也有 verilog 源代码。
lfsr_fib.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity lfsr_fib is
generic (LN : natural := 8;
TAPS : std_logic_vector(LN-1 downto 0) := x"2d";
INITIAL_FILL : std_logic_vector(LN-1 downto 0) := x"01");
port (i_clk, i_reset, i_ce, i_in : in std_logic;
o_bit : out std_logic := INITIAL_FILL(0));
end entity lfsr_fib;
architecture behavior of lfsr_fib is
signal sreg : std_logic_vector(LN-1 downto 0) := INITIAL_FILL;
begin
process(i_clk)
begin
if (rising_edge(i_clk)) then
if (i_reset = '1') then
sreg <= INITIAL_FILL;
elsif (i_ce = '1') then
sreg(LN-2 downto 0) <= sreg(LN-1 downto 1);
sreg(LN-1) <= (xor (sreg and TAPS)) xor i_in;
end if;
end if;
end process;
process(sreg)
begin
o_bit <= sreg(0);
end process;
end behavior;
dblpipe.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dblpipe is
port (i_clk, i_ce, i_data : in std_logic;
o_data : out std_logic := '0');
end entity dblpipe;
architecture behavior of dblpipe is
component lfsr_fib
port(i_clk, i_reset, i_ce, i_in : in std_logic;
o_bit : out std_logic);
end component;
signal a_data, b_data : std_logic;
begin
----
----
one: lfsr_fib port map (
i_clk => i_clk,
i_reset => '0',
i_ce => i_ce,
i_in => i_data,
o_bit => a_data);
two: lfsr_fib port map (
i_clk => i_clk,
i_reset => '0',
i_ce => i_ce,
i_in => i_data,
o_bit => b_data);
process(a_data, b_data)
begin
o_data <= a_data xor b_data;
end process;
----
----
end behavior;
正式的属性文件:
`default_nettype none
//
module dblpipe_vhd(i_clk, i_ce, o_data);
input wire i_clk;
input wire i_ce;
input wire o_data;
`ifdef FORMAL
// Your goal: to get the following assertion to pass
//
// assume(one.sreg = two.sreg);
// assert(one.sreg == two.sreg);
always @(*)
begin
assert(o_data == 1'b0);
end
always @(*)
begin
if(i_clk)
begin
assume(one.i_clk);
assume(two.i_clk);
end
else
begin
assume(!one.i_clk);
assume(!two.i_clk);
end
end
//Trigger a counter example at step 18 - to check if the assumptions made where applied
// always @(posedge i_clk)
// if(f_time >= 18)
// assert(f_time < 18);
`endif
endmodule
bind dblpipe dblpipe_vhd copy (.*);
sby 控制脚本:
[options]
mode prove
[engines]
smtbmc
# abc pdr
# abc pdr
# aiger avy
# aiger suprove
[script]
read -vhdl lfsr_fib.vhd
read -vhdl dblpipe.vhd
read -formal dblpipe_vhd.sv
prep -top dblpipe
[files]
lfsr_fib.vhd
dblpipe.vhd
dblpipe_vhd.sv
相关问题1:
玩弄不同的断言导致了以下 K-Induction Trace:
我的问题是,为什么跟踪显示子模块的时钟正在滴答作响,而顶层时钟却没有?
即使添加以下代码也不会让时钟同时滴答作响:
always @(*)
begin
if(i_clk)
begin
assume(one.i_clk);
assume(two.i_clk);
end
else
begin
assume(!one.i_clk);
assume(!two.i_clk);
end
end
然而 i_ce 显然以某种方式连接,因为它在所有模块之间同步: i_ce Traces
相关问题 2
为什么这个问题的解决方案是断言两个 sreg 是相等的,而不是假设它们是相等的?
由于我们正在定义哪些输入对我来说是理所当然的,这听起来更像是在这种情况下应该使用假设。
always @(*)
assert(one.sreg == two.sreg);
代替:
always @(*)
assume(one.sreg = two.sreg);
相关问题 3
有人可以向我解释为什么输入数据没有在包装模块中连接吗?这样我就无法在跟踪视图中看到哪些数据被馈送到顶级模块中......但是如果我将它添加到模块定义中,它仍然在跟踪文件中始终保持为 0。
module dblpipe_vhd(i_clk, i_ce, o_data);
input wire i_clk;
input wire i_ce;
input wire o_data;
我过去遇到的大多数问题都可以通过一遍又一遍地阅读可用的文档来解决,但是对于这些问题,我自己却找不到解决方案。
解决方案
关于问题 1
您看到的跟踪可能有某种工具错误,导致它无法dblpipe_vhd .i_clk
正确设置 的值。我这样说,因为您的断言似乎正在触发。该工具可能会看到直接下面没有时钟逻辑dblpipe_vhd
并将时钟视为冗余。
该工具(以及其他形式验证工具)自动推断时钟并以不同的方式处理它们,以不同于描述逻辑的“常规”信号。你写的assumes
时钟可能不会做任何事情。
(我不太熟悉sby
,但我可以想象它实际上使用smt_clock
信号来为逻辑提供时钟,而其他时钟只是用于调试目的。)
关于问题 2
IMO,要通过断言,两个 LSFR 从同一状态开始就o_data
足够了。assume
由于您从不应用重置,因此该工具可以自由选择初始状态。我猜作者试图说明这一点。
不知道为什么要在不先应用重置的情况下进行证明。那里有复位信号以确保可预测的启动状态。如果不先重置它们,您将永远不会真正使用它们。
关于问题 3
dblpipe_vhd
不是顶级模块。dblpipe
是。在语句下面添加了一个dblpipe_vhd
被调用的实例。它只断言反对,所以它只需要那个信号。copy
dblpipe
bind
o_data
推荐阅读
- reactjs - 绑定 this 但仍然得到 setState is not a function
- git - 单个 git 存储库的多个用户
- python-3.x - 在 Pandas 中通过多个分隔符将一列拆分为多列
- express - 带有反应电子 js 前端的后端 Express API
- flutter - 巨大的 firebase admob stacktrace 列表 - 与 FirebaseAdMobPlugin 相关?
- django - 有没有办法从模型实例 dict 对象中的连接表中获取列?
- flutter - 如何在状态更改后强制小部件重新创建自己?
- python - scrpy.spyder 上的 start_request 似乎无法正常工作
- ubuntu - 如何防止使用 Nginx 的乘客停止
- java - DateTimeParseException:无法解析文本“2020-04-01T08:53:47.000+02:00 00:00”,在索引 29 处找到未解析的文本