Testbench——HDL的并行性
0赞为什么C不能取代verilog和VHDL作为硬件描述语言?因为C缺少了硬件描述最基本的三个思想:连通性(Connectivity),时间性(Time)和并行性(Concurrency)。
连通性是指使用一个简单并相互连接的模块来描述设计的能力,原理图设计工具就是连通性完美的支持工具。
时间性是指表现设计状态演进的时间变化的能力,这个能力不同于衡量一个代码执行运行多久的时间。
并行性是指描述同时发生相互独立的行为的能力。
Testbench——读写紊乱状态
在同一时刻对同一个寄存器进行读写容易发生紊乱状态。以下的例子,第一个always块对count操作(写),第二个always却要显示它。那么会出现什么状态呢?
module rw_race(clk);
input clk;
integer count;
always @ (posedge clk)
begin
count = count + 1;
end
always @ (posedge clk)
begin
$write("Count is equal to %0d\n", count);
end
endmodule
由于testbench基于计算机,那么处理的时候也是分时复用的,从而这两个always块会先后执行。也就是说会出现两种情况,这里假设count在执行前为10,若先执行第一个块,那么后第二个块执行的结果显示count=11;若先执行第二个块再执行第一个块,显示的结果count=10。
往往这样的紊乱状态不是我们希望看到的,很可能会给我们的测试工作带来许多不必要的麻烦。那么,有什么解决办法呢?
module rw_race(clk);
input clk;
integer count;
always @ (posedge clk)
begin
count <= count + 1;
end
always @ (posedge clk)
begin
$write(“Count is equal to %0d\n", count);
end
endmodule
采用非阻塞赋值语句后,这个紊乱的状态就会得到解决。在第一个always块count增加的同时第二个always块也在执行,那么最后显示的count值是count增1之前的数值。
再看下面的例子。
module rw_race;
wire [7:0] out;
assign out = count + 1;
integer count;
initial
begin
count = 0;
$write("Out = %b\n", out);
end
endmodule
会得到什么结果呢?这取决于你所使用的仿真器和命令行。一般的,Verilog-XL会输出”xxxxxxxx”,而VCS则会认为是”00000001”。那么如何改进呢?
module rw_race;
wire [7:0] out, tmp;
assign #1 out = tmp - 1;
assign #3 tmp = count + 1;
integer count;
initial
begin
count = 0;
#4; // "out" will be 0 or x’s.
$write("Out = %b\n", out);
end
endmodule
这些都是一个好的testbench应该注意的细节。