verilog代码中避免出现latch方法

标签:
veriloglatch |
分类: 学习心得 |
在组合逻辑中,有时候往往不需要生成latch,所以必须知道某些信号会综合为latch,通过实践发现下面两类会出现latch:
http://s2/mw690/0033TwPDzy6Ka2uCZcR01&690
在上图两段代码都是标准的if-else
和case语句,但是第二段代码却可以生产latch,通过将第二段代码综合后看RTL就可以清楚看到:
http://s13/mw690/0033TwPDzy6Ka2Y9t3S1c&690
第二段代码产生了4个latch。第二段代码之所以会出现latch,是因为:
out1,out2,out3,out4仅仅在data_in一种情况下赋值,当data_in在非条件下,就没有对该信号赋值。
1. if-else
2.在所有条件下,对信号都进行赋值
http://s7/mw690/0033TwPDzy6Ka5qgdWS76&690
然后综合后查看RTL,可以发现:
http://s9/mw690/0033TwPDzy6Ka5tqzage8&690
可以看出out1没有产生latch。所以在信号不多的情况下,可以讲每个信号在所有条件下都进行赋值,这样就会消除latch的产生。
但是,在三段式状态机代码中,特别是状态机多,信号特别多的情况下,在每个条件下都给每个信号赋值,这样就会导致代码很冗长,此时可以给每个信号一个初值。修改方法为:
http://s10/bmiddle/0033TwPDzy6Ka6atKPLb9&690
这样就是在选择语句之前给信号赋一个初值,这样就不需要在所有条件都给信号赋值,减少代码的重复和代码量。上图代码综合后的RTL图为:
http://s8/mw690/0033TwPDzy6Ka7eb2qXb7&690
可以发现这种方法也是可行的。
所以总结为:
关于第二条,估计会产生一些迷惑,例如在前面代码中data_in为1,out2赋值为0还是赋值为1呢?
这里就涉及到阻塞赋值和非阻塞赋值的区别。在上面代码中一般都是阻塞赋值,也就是上面一句赋值都完成了,才进行第二条语句的赋值。在上面的代码中,就是先给out2赋值为0,然后再赋值为1。这个不同于非阻塞赋值,如果是非阻塞赋值的话,就会导致同时给out2赋值两个值,导致亚稳态。
最后需要注意的是:在组合逻辑中,always@()的括号里面,使用*代替敏感变量,这是在verilog2001中的代码风格,这样可以避免敏感变量不全的情况,建议在写组合逻辑中这样书写代码。