明德扬肖老师 发表于 2020-9-17 15:23:02

【FPGA至简设计原理与应用】第一篇第三章硬件描述语言Verilog第6节时序逻辑代码和硬件


大家好,近期我们会连载《FPGA至简设计原理与应用》一书,有兴趣的同学可以学习,也希望大家可以对我们的书提出宝贵的意见和建议。


《FPGA至简设计原理与应用》书籍连载索引目录
http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=989


读过的朋友可积极在贴后留言,书籍正式出版时,我们会从留言者中挑选20位幸运读者,幸运读者可获潘老师亲笔签名书籍一本。

注:手机浏览可能格式会乱,建议用电脑端进行浏览。



本文档编号:001500000030
1. 本章主要介绍硬件描述语言Verilog的发展历史、语法结构、接口定义等,旨在设计人员对从最复杂的芯片到完整的电子系统进行描述。
2. ALTERA和VIVADO文档

6.4 时序逻辑代码和硬件

先来分析一下下面这段代码:
12345678always@(posedge clk or negedge rst_n)begin    if(rst_n==1'b0)begin      q <= 0;    end    else begin      q <= a + d;    endend
仍然从语法上分析该段代码的功能。该段代码总是在“时钟clk上升沿或者复位rst_n下降沿”的时候执行一次。
具体执行方法如下:1.      如果复位rst_n=0,则q的值为0;2.      如果复位rst_n=1,则将(a+d)的结果赋给q(注意,前提条件是时钟上升沿的时候)。
假设用信号c表示a+d的结果,则第2点可改为:如果复位rst_n=1,则将c的值赋给q(注意,前提条件是时钟上升沿的时刻)。很明显这是一个D触发器,输入信号为d,输出为q,时钟为clk,复位为rst_n,其电路示意图如下图所示:

http://www.fpgabbs.cn/data/attachment/forum/202005/14/104708ukn48l7yfwf98ksl.jpg可知c是a+d的结果,因此其自然是通过一个加法器实现,画出上面代码所对应的电路结构图,可以看出在D触发器的基础上增加了一个加法器。
http://www.fpgabbs.cn/data/attachment/forum/202005/14/105450vznbnk4uo0kx5d7r.jpg很容易分析出上面电路的功能:信号a和信号b相加得到c,c连到D触发器的输入端。当clk出现上升沿时,将c的值传给q。这与代码功能是一致的。下面是代码和硬件所对应的波形图。

http://www.fpgabbs.cn/data/attachment/forum/202005/14/105532l9x6zdxurvvdd9nl.jpg先看信号c的波形:c的产生只有与a和d有关,与rst_n和clk无关。c是a+d的结果,按照二进制加法:0+0=0,0+1=1,1+1=0可以画出c的波形。在第1个时钟期间,a=0,d=0,所以c=0+0=0;在第2个时钟期间,a=1,d=0,所以c=1+0=1;在第3个时钟期间,a=1,d=1,所以c=1+1=0;在第4个时钟期间,a=0,d=1,所以c=0+1=1;在第5到第6个时钟期间,a=0,d=0,所以c=0+0=0;在第7个时钟期间,a=1,d=1,所以c=1+1=0;在第8个时钟期间,a=0,d=1,所以c=0+1=1;在第9个时钟期间,a=0,d=0,所以c=0+0=0;在第10个时钟期间,a=0,d=1,所以c=0+1=1。
再看信号q的波形:q是D触发器的输出,其只在rst_n的下降沿或者clk的上升沿才变化,其他时刻不变化,即a、d、c发生变化时,q不会立刻发生改变。
http://www.fpgabbs.cn/data/attachment/forum/202005/14/105612c8rcas4cqrcyfycc.jpg下面具体分析每个时钟下q信号的情况:在rst_n由1变0时,q立刻变成0。在第2个时钟上升沿,看到rst_n为0。按代码功能,q仍然为0。在第3个时钟上升沿,看到rst_n为0。按代码功能,q仍然为0。在第4个时钟上升沿,看到rst_n为1,c值为0,q值为0。按代码功能,q变成0;在第5个时钟上升沿,看到rst_n为1,c值为1,q值为0。按代码功能,q变成1;在第6个时钟上升沿,看到rst_n为1,c值为0,q值为1。按代码功能,q变成0;在第7个时钟上升沿,看到rst_n为1,c值为0,q值为0。按代码功能,q变成0;在第8个时钟上升沿,看到rst_n为1,c值为0,q值为0。按代码功能,q变成0;在第9个时钟上升沿,看到rst_n为1,c值为1,q值为0。按代码功能,q变成1;在第10个时钟上升沿,看到rst_n为1,c值为0,q值为1。按代码功能,q变成0;在第11个时钟上升沿,看到rst_n为1,c值为1,q值为0。按代码功能,q变成1。
在讨论时序逻辑的加法器时,笔者对加法器的输出c和D触发器的输出q分开进行讨论,就像两块独立的电路。同样的道理,在设计Verilog代码时也可以将其分开来进行编写。先将下面的硬件电路用Verilog描述出来:
http://www.fpgabbs.cn/data/attachment/forum/202005/14/105704kzmrukirouxivduf.jpg该电路对应的电路可以写成:
123always@(*)begin    c = a + d;end
也可以写成:
1assign c = a + d;
上面的两段代码,都是描述同一加法器硬件电路。接着用Verilog对触发器进行描述。
http://www.fpgabbs.cn/data/attachment/forum/202005/14/105731u0u8gresdc900s6o.jpg其代码的写法如下:
12345678always@(posedge clk or negedge rst_n)begin    if(rst_n==1'b0)begin      q <= 0;    end    else begin      q <= c;    endend
最后可以看到,两段代码都有信号c,说明这两段代码是相连的,利用硬件连接起来可以变成如下图所示的电路。
http://www.fpgabbs.cn/data/attachment/forum/202005/14/105802jhjes1nlj4l5e26l.jpg由此可见,下面两段代码所对应的硬件电路是一模一样的。
1234567891011121314always@(posedge clk or negedge rst_n)begin    if(rst_n==1'b0)begin      q <= 0;    end    else begin      q <= c;    endend


always@(*)begin
    c = a + d;end


12345678always@(posedge clk or negedge rst_n)begin    if(rst_n==1'b0)begin      q <= 0;    end    else begin      q <= a + d;    endend
有的读者也许会问:这两种代码哪一种比较好呢?答案是这两段代码并无区别,因为两者的硬件是相同的。由此也可以得知评估verilog代码好坏的最基本标准,即不是看代码行数而是看硬件。



页: [1]
查看完整版本: 【FPGA至简设计原理与应用】第一篇第三章硬件描述语言Verilog第6节时序逻辑代码和硬件