实验室学长让我重新把verilog书看看,拿起以前的课本就看了起来。有些新的东西在这记下了。
关于阻塞和非阻塞赋值,记住八大原则:
1、时序电路建模时,用非阻塞赋值;
2、锁存器电路建模时,用非阻塞赋值;
3、用always块建立组合逻辑电路时,用阻塞赋值;
4、在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值;
5、在同一个always块中不要既用非阻塞赋值又用阻塞赋值;
6、不要在一个以上的always块中为同一个变量赋值。这个问题我出现过,编译会不通过。原因在于各个always块实际上先后顺序随机,容易造成竞争冒险。不过在always块中为同一个变量多次赋值是允许的,结果是最后一次赋值对变量有用。另外在always块中变量既是输入又是输出也是允许的;
7、用$strobe系统任务来显示用非阻塞赋值的变量值;
8、在赋值时不要使用#0延迟。
关于verilog的层次化事件队列,可以理解为调度仿真的机制。有以下层次:
1、动态事件队列:
(1)阻塞赋值;
(2)计算非阻塞赋值语句右边的表达式;
(3)连续赋值;
(4)执行$display命令;
(5)计算原语的输入输出变化;
2、停止运行的时间队列:#0延时阻塞赋值;
3、非阻塞事件队列:更新非阻塞赋值语句LHS的值;
4、监控事件队列:
(1)$monitor
(2)$strobe
其中动态事件的优先级最高,最先排队。而其他队列必须激活后排入动态事件队列,等待执行。
这个模型能解释一些现象:(只是个人观点)
1、比如阻塞赋值,计算和赋值全部完成后再完成下面的指令,因为它优先级高。
2、为什么非阻塞能实现时序电路的那种效果。因为寄存器变量赋的什么值已经先计算好了,优先级高。而这个值更新到变量上优先级低。所以才有”在always块结束后,非阻塞才真正赋值完毕“的说法。因此,即使是连续赋值的形式,它也不是连续的赋值,因为上一条只是算好,并没有赋值,因此就不会把赋值影响到下面几条指令。这么说的话,这个并行的概念其实就不这么难理解了,感觉这个并行只是一种假象。
3、为什么对变量多次赋值,只看最后那个。如果把并行理解成假象,那么按顺序下来,肯定是最后一个赋值更新的指令有用。
......
读了书上的一些程序,发现:
1、状态机必须熟练掌握。而且状态编码多用独热码。
2、若每个状态需要的操作过多,写task调用。task里面可以再写case嵌入从状态机。
3、输出大部分有缓冲器,并最后用assign输出,有时候还有控制线配合assign。
4、多模块文件用顶层文件管理。注意测试文件和顶层文件是两个概念。测试文件还是可以有input口的,但是顶层文件没有。
待补充......
原文地址:http://blog.csdn.net/hunterlew/article/details/41870767