马上注册,看完整文章,学更多FPGA知识。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
大家好,近期我们会连载《FPGA至简设计原理与应用》一书,有兴趣的同学可以学习,也希望大家可以对我们的书提出宝贵的意见和建议。
《FPGA至简设计原理与应用》书籍连载索引目录
http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=989
读过的朋友可积极在贴后留言,书籍正式出版时,我们会从留言者中挑选20位幸运读者,幸运读者可获潘老师亲笔签名书籍一本。
注:手机浏览可能格式会乱,建议用电脑端进行浏览。
本文档编号:001500000030
1. 本章主要介绍硬件描述语言Verilog的发展历史、语法结构、接口定义等,旨在设计人员对从最复杂的芯片到完整的电子系统进行描述。
2. ALTERA和VIVADO文档
6.4 时序逻辑代码和硬件
先来分析一下下面这段代码: | always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin q <= 0; end else begin q <= a + d; end end |
仍然从语法上分析该段代码的功能。该段代码总是在“时钟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,其电路示意图如下图所示:
可知c是a+d的结果,因此其自然是通过一个加法器实现,画出上面代码所对应的电路结构图,可以看出在D触发器的基础上增加了一个加法器。
很容易分析出上面电路的功能:信号a和信号b相加得到c,c连到D触发器的输入端。当clk出现上升沿时,将c的值传给q。这与代码功能是一致的。 下面是代码和硬件所对应的波形图。
先看信号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不会立刻发生改变。
下面具体分析每个时钟下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描述出来:
该电路对应的电路可以写成: | always @(*)begin c = a + d; end |
也可以写成: 上面的两段代码,都是描述同一加法器硬件电路。接着用Verilog对触发器进行描述。
其代码的写法如下: | always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin q <= 0; end else begin q <= c; end end |
最后可以看到,两段代码都有信号c,说明这两段代码是相连的,利用硬件连接起来可以变成如下图所示的电路。
由此可见,下面两段代码所对应的硬件电路是一模一样的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin q <= 0; end else begin q <= c; end end
always @(*)begin
c = a + d; end |
| always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin q <= 0; end else begin q <= a + d; end end |
有的读者也许会问:这两种代码哪一种比较好呢?答案是这两段代码并无区别,因为两者的硬件是相同的。由此也可以得知评估verilog代码好坏的最基本标准,即不是看代码行数而是看硬件。
|