与上面的逻辑是一模一样的。大家观察综合出来的电路图就可以理解了。对于很复杂的逻辑运算,我更推荐第二种写法,这样将触发器的D,Q显式的表示成了两个信号,可控性更高。
然后是一个更加复杂点的逻辑,这里由于采用的是非阻塞赋值,所谓的非阻塞,就是不会阻塞啊!所以前后两句话是并行执行的,没有先后关系的!因此我们观察综合生成的电路。f的输入t为D触发器的输出,而不是a和b直接相与的结果。这一点非常重要,大家多看几遍这段代码和电路图。好好理解一下。也完全可以按照我上面的第二种写法,展开一下,便很容易懂了。
然后介绍了一下带复位的逻辑,这就是非常典型的always_ff写法了,大家可以记住这个模板。
然后介绍了一下嵌套逻辑。同样,这个逻辑是从里面向外面展开。最里面是if/else语句,如果op为1,则xxx,否则xxx。因此会生成一个二选一的MUX。此外该dataout是用在时序逻辑的,因此会由D触发器进行输出。这里引出一个重要的概念,存储。dataout的值存储在D触发器里,每个时钟上升沿会进行更新。此外该逻辑输出的值进而会影响参与输入运算的值,也就是所谓的反馈。这实际上就是隐式状态机了,通过后面的介绍可以知道,状态机实际上就是带反馈的时序逻辑。大家结合代码和电路图仔细看看,应该能够理解。
然后介绍了一下多个always块,仔细观察这两个always块,可以看到右边的z由y+1赋值得到,同时dataout由dataout+z得到,因此可以得到图所示的电路图。实际上只要明白,时序逻辑当中,这些赋值语句,都是由D触发器的右端引过来的输入,这样就很容易得到电路图了。比如z<=y+1。其中的y对应D触发器的Q端,和1相加进入另一个D触发器的D端,通过这样的分析相信大家也可以画出该电路图。(画出电路图以后,对应的信号变化,各个信号关系之间是怎么样的呢?留给大家一个作业,大家下去动手画一下)
然后介绍了一下assign与always_ff混合的情况(其实不能叫混合,仍然是分开的)。这就很简单了,assign只是一根线连接,因此该图应该更好理解。(大家多去思考电路和代码的对应关系,把上面这几幅图都搞懂。always_comb,always_ff以及assign便都可以理解了。实际上这三种语法,占据了我们设计代码的绝大部分)。
然后介绍了一下always_comb和always_ff混合使用的情况,有没有发现和上面的电路图一样?实际上就是一样的。assign和always_comb没有本质区别。
最后说明了一下状态机,状态机全称有限状态机。就是系统有多个状态,满足特定情况,则从其中一个状态到另一个状态,不同的状态做不同的事情!如下图所示,就是一个状态机,是不是很好理解。
状态机电路如图所示,可以分为三部分。一部分用于计算输出逻辑,一部分用于D触发器更新状态,一部分用于计算下一状态。可以看到state会反馈到计算下一状态,这种带反馈的时序逻辑,实际上就是状态机!很多时候代码没有显式的按照状态机代码模板写,实际上也会综合成这样,原因就是如此。包括写一堆if/else,很有可能也综合成了状态机,具体在于有没有反馈!
然后介绍了一下状态机代码写法,图里是两段式状态机写法,我个人更喜欢三段式写法,请参考这篇文章:带带大师兄:HDLBits: 在线学习Verilog(Problem 120-126)。有关两段式三段式详细区别,下节课再做介绍