这里有一个小技巧,就是在nc跑前仿(包括后仿的一些情况的时候),将ncelab的权限放低的话,可以大大加快仿真的速度。将本来的+rwc换成+r就可以了,具体的解释建议还是看一下ncvlog的helper/manual。这个简单的解释摘录一下
Read access is required if you want to probe objects in the design and generate an SHM,
VCD, or EVCD database. This lets you use the SimVision waveform viewer to view waveforms,
and most Tcl commands and SimVision features. Read access is also required for getting
signal values with, for example, the value or describe command, or vpi_get_value().
Write access is required if you want to deposit values using, for example, the force or
deposit command, or vpi_put_value().
Connectivity access is required in order to show load or driver information. This kind of
access is required, for example, by the drivers command and by the Trace Signals sidebar.
关注仿真速度,就这,来谈几点提高nc仿真速度的问题。是看了nc的simulation user guide的几点归纳。
首先要明确的就是对仿真器来说,behavior/RTL都要比gate仿真快。
再者,只要dumping waveform都会很慢。
开很多的文件接口IO,都会很大程度上拖慢仿真器的performance。
PLI也是一个影响因素,但是我不懂,不深究。
如果使用了大量的hierachy的指定信号的方式也会大大拖慢速度。
接着,谈到coding style。就是多用non-blocking,否则会拖慢optimization的速度;always 块里面不要用system task,否则会就不会优化速度了。n-bit的dff最好写到一起,不要分开,不然就会慢。还有就是如果是普通的DFF模型的话,加上delay,会对 仿真有帮助,相信大家都懂得,但是注意的是,不要光在d-->q的时候加上,如果有asynchronous reset的时候也加上吧。但是保证所有的dff模型的delay完全一致,才好。下面一个重要的问题就是primitive和自己手写的dff之间的区 别,就是他们仿真的速度差异。nc user guide上面是这么解释的。
使用UDP要比always block的DFF仿真速度快,因为UDP是进入就值变换,而always 在time slice开始进入,而在time slice结尾才进行赋值给Q。这样还是说的比较明白的,UDP是样子的行为,对比always的行为。
接着是latch的coding style。
1、敏感列表中有3个或者更少的标量(单bit?)
2、always block里只有一个if,没有else
3、使用non-blocking
4、non-blocking左侧为标量(单bit?)
还有提到的一点就是reg要比net更占用内存空间,所以如果用reg的话要比net更快。
下面举一个例子来说明如何通过coding style来去掉一些inferring glitch。本来的功能如果是这样的
always @ (a or b or c) begin {h, j, k} = 3'b0; case {a, b, c} 3'b001: k = 1'b1; 3'b010: j = 1'b1; 3'b011: k = 1'b1; 3'b111: h = 1'b1; endcase end
下面的coding style就是more readable, prevents inferred latches, and has no unintended glitches.
always @(a or b or c) case {a, b, c} 3'b001 : {h,j,k} <= 3'b001; 3'b010 : {h,j,k} <= 3'b010; 3'b011 : {h,j,k} <= 3'b001; 3'b111 : {h,j,k} <= 3'b100; default : {h,j,k} <= 3'b000; endcase
还有就是仿真的时候不要用那种0->X->1,1->X->0的带有clock skew的时钟来仿真,很容易出问题。变化都是在一个time slice里面,只不过步骤越多就有越多的delta cycle来划分这个time slice,那么不光影响仿真速度【因为比如你写的是@(posedge clk),那么0->X与X->1都是posedge clk 就会导致你多次的进入同一个always里面,大大影响速度】,更会由于在同一个time slice里面挤了很多的blocking assignment或者是UDP的变化导致结果不可控,最好不要这么搞,不然很容易出现一些无法解释的东西。