在编写验证tc时,常常会用到force信号来模拟输入,在前仿中常常与上升沿对齐时来force input随机变量,这次在对应后仿时遇到个问题,便记录出来。
1. 如果force的值为固定值,即0/1等,即可直接赋值
2. 当需要force随机变量时,等式右端必须为static类型,举例说明
static bit[3:0] random_din; //声明static变量
...
...
repeat(50) begin
@(posedge clk); //对齐上升沿
std::randomize(random_din); //随机输入变量
... //一些其他需要用到random_din的操作
force din = random_din; //force随机变量输入
repeat($urandom_range(10)) @(posedge clk);
...
end
...
问题在于后仿时,这样写可能会导致时序违例,一般由于force的输入信号多个bit位与时钟沿同时对齐,导致某一bit触发器会产生不期望的x态输出,从而影响输出结果。
这时可能需要将输入比上升沿晚一些,或者在下降沿force进去,我最初会这样改:
static bit[3:0] random_din; //声明static变量
...
...
repeat(50) begin
@(posedge clk); //对齐上升沿
std::randomize(random_din); //随机输入变量
... //一些其他需要用到random_din的操作
#1ns; //*** 等待几个延时 ***
force din = random_din; //force随机变量输入
repeat($urandom_range(10)) @(posedge clk);
...
end
...
或者
static bit[3:0] random_din; //声明static变量
...
...
repeat(50) begin
@(posedge clk); //对齐上升沿
std::randomize(random_din); //随机输入变量
... //一些其他需要用到random_din的操作
@(negedge clk); //*** 对齐下降沿 ***
force din = random_din; //force随机变量输入
repeat($urandom_range(10)) @(posedge clk);
...
end
...
但未想到的问题来了,经过检查波形,在上升沿时,din会在一个周期内被force两次,上升沿一次,1ns或者下降沿时也会force一次,导致后仿依然存在概率性时序违例
由于内网涉密等原因,原波形不做截图,只能Excel模拟一下…
经过对波形及tc代码重新检视,找到了问题原因:
static变量的生命周期是整个程序运行期间,一旦发生改变,则被force的信号也会立即改变,由于某些情况,我不期望输入在变量随机后立即被force,在变量随机后我会有其他操作,这样带来的问题是:当变量随机一旦随机后,我force的din便会立即更改,等经过手动延时或下降沿时,din会被二次force随机后的值,等于din会被连续两次force相同的随机后变量
遂再次进行更改,最终得以实现目的:
static bit[3:0] random_din; //声明static变量
static bit[3:0] random_din_copy; //声明static变量
...
...
repeat(50) begin
@(posedge clk); //对齐上升沿
std::randomize(random_din); //随机输入变量
... //一些其他需要用到random_din的操作
@(negedge clk); //*** 延时或对齐下降沿 ***
random_din_copy = random_din; //在延时或下降沿到来后 再进行右端赋值
force din = random_din_copy; //force随机变量输入
repeat($urandom_range(10)) @(posedge clk);
...
end
...
最终波形: