特权同学

Testbench——HDL的并行性

0
阅读(24252) 评论(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应该注意的细节。