先看下面的代码
module top(data);
logic clk;
inout data;
logic temp;
logic sampale_data;
logic [7:0] data_rec;
task send_data(input [7:0] da);
begin
@(posedge clk);
#1;
force data=da[7];
$display(data);
@(posedge clk);
#1;
force data=da[6]; $display(data);
@(posedge clk);
#1;
force data=da[5];$display(data);
@(posedge clk);
#1;
force data=da[4];$display(data);
@(posedge clk);
#1;
force data=da[3]; $display(data);
@(posedge clk);
#1;
force data=da[2];$display(data);
@(posedge clk);
#1;
force data=da[1];$display(data);
@(posedge clk);
#1;
force data=da[0]; $display(data);
end
endtask
initial
begin
#1000;
@(negedge clk);
send_data(8'b1100_1100);
$stop;
send_data(8'b0011_0011);
$stop;
end
always @(posedge clk)
begin
sampale_data<=data;
data_rec<={data_rec[6:0],data};
end
initial
begin
clk=0;
forever #5 clk=~clk;
end
endmodule
仿真波形结果如下:
在第一次调用send_data(8'b1100_1100);后,最后一个比特输出应该是0,但是从仿真波形看是1,这是因为第一次调用send_data(8'b1100_1100)时,最后一次force后,task任务立即退出,执行第二次调用send_data(8'b0011_0011);第二次调用task会将第一次调用task的force语句赋值覆盖。但是第二次调用task的第一次force是在时钟上升沿之后,而且强制赋值也是0,不明白为什么仿真波形中标记红色的显示为1。通过$display打印出每次force赋值后的值是正确的。目前尚不清楚原因。
通过sampale_data对data进行采样发现,采集的数据错误。所以按照上面的方法写的激励不对。
为了解决上述问题,将上述代码更改如下:
module tb(data);
logic clk;
inout data;
logic temp;
logic sampale_data;
logic [7:0] data_rec;
task send_data(input [7:0] da);
begin
@(negedge clk);
#1;
force data=da[7];
$display(data);
@(negedge clk);
#1;
force data=da[6]; $display(data);
@(negedge clk);
#1;
force data=da[5];$display(data);
@(negedge clk);
#1;
force data=da[4];$display(data);
@(negedge clk);
#1;
force data=da[3]; $display(data);
@(negedge clk);
#1;
force data=da[2];$display(data);
@(negedge clk);
#1;
force data=da[1];$display(data);
@(negedge clk);
#1;
force data=da[0]; $display(data);
#7;
/* @(posedge clk);
release data; */
end
endtask
initial
begin
#1000;
@(negedge clk);
send_data(8'b1100_1100);//@(posedge clk);
$stop;
send_data(8'b0011_0011);
release data;
$stop;
end
always @(posedge clk)
begin
sampale_data<=data;
data_rec<={data_rec[6:0],data};
end
initial
begin
clk=0;
forever #5 clk=~clk;
end
endmodule
更改的地方主要有两点:
(1)在时钟的下降沿使用force强制赋值。
(2)在task中最后一次force时,延时时间大于时钟周期的一半,小于一个时钟周期。
通过仿真波形,以及$display打印结果分析,这样写激励是正确的。