注意这是哥的原创。
起因是看到了M8051里面的memory,都有个define的延时,所以这里想查一下nc的选项看能不能给在ncelab的选项里面 直接给避过去,但是发现有了些学问,听我慢慢到来。
首先 行为级描述的延时都是不可搞的 就是你在ncelab里面设置了0延时 但是其实是不起作用的
ncelab里面搞0延时的选项是-delay_mode zero,具体详情可以在查看一下nc的帮助 这个选项能起什么作用呢
一、先让我们来看看线网时延,举例如下
1.wire #5 arb;
这个代表的意识就是arb这个wire的反映要慢#5,这个的意思就是说,当你在赋值的时候就会发现如果像上面这样声明的话就会有着相当于赋值时延的现象出现,同时是可以和赋值时延累加的,再举个例子
2. wire #3 arb; assign #8 arb = com_a & com_b;
这个的结果就是arb比真正com_a & com_b的结果要晚变化#11,就是相当于线网延时和赋值延时连续的延时的结果。再有特例如下
3.wire #5 arb = com_c & com_d;
这个真正的,不叫座线网延时了,因为有赋值语句,只不过是一个简写,应该归到赋值延时里面。
二、再来看看行为级描述的延时
1. reg rst_n;initial begin rst_n = 1'b0; #200 rst_n = 1'b1;end
这样的 #200是不能通过nc的参数-delay_mode zero搞掉的,同样的下面的例子也是不可以的
2.reg q_0;always @(posedge clk or negedge rst_n) begin if(~rst_n) q_0 <= 1'b0; else q_0 <= #5 a_in;end
这里相当于都是对reg类型的变量做的延时,所以我觉得应该是-delay_mode zero都是对于wire类型而言的,所以reg类型的延时都是没用的,都相当于是行为级的描述,所以都是人为加上去的,通过参数搞不掉。
三、接着再来看看赋值时延,这个是最麻烦的,首先来说,是可以通过参数给搞掉的
1. assign #5 reg_0 = a_in;
明显的这句话的意思就是#5后,再将a_in的值赋给reg_0这个wire,但是加了delay_mode zero的选项之后就会发现这个延时不见了 仿真的时候很明显的 reg_0 与a_in的变化会是对的齐齐的,这个delay是可以用nc的参数搞掉的
2.not #50 (y_out, a_in);
这个门级的表述的意思其实也是很好懂的 虽然我们不会经常用 就是 assign #50 y_out = ~a_in;
同样的 delay_mode zero可以把这个延时通过nc选项给消掉 其他基本门电路也是基本这个样子的比如什么and xor or 之类的都是一样的
接下来再细分析一下这个赋值延时,我只说最通用的,就是assign这种情况的,首先,它也是可以按照min:type:max这种形式来给出值的,第二就是说它其实有三个时间在里面
assign #(rise, fall, turn-off) LHS = RHS;
时间分别是指的上升时延,下降时延,关闭时延,接下来我来给出一个表格来说明跳变的时候的时延关系
0 | 1 | X | Z | |
0 | rise | MIN | turn-off | |
1 | fall | MIN | turn-off | |
X | fall | rise | turn-off | |
Z | fall | rise | MIN |
行代表当前状态,列代表将要进入的状态,中间写的就是时延的时间了。
所要说明的意思就是,不管什么状态往'0'跳的时候都是延时的fall,跳'1'的时候都是rise延时,跳'x'的时候,都是这几个延时里面最小的延时,跳'z'的时候都是turn-off延时,就是这样。