明德扬论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫一扫,快捷登录!

查看: 7281|回复: 0

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

[复制链接]
发表于 2020-9-17 15:23:02 | 显示全部楼层 |阅读模式

马上注册,看完整文章,学更多FPGA知识。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

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


FPGA至简设计原理与应用》书籍连载索引目录

http://www.fpgabbs.cn/forum.php?mod=viewthread&tid=989


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

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




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

6.4 时序逻辑代码和硬件

先来分析一下下面这段代码:
1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
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,其电路示意图如下图所示:


可知ca+d的结果,因此其自然是通过一个加法器实现,画出上面代码所对应的电路结构图,可以看出在D触发器的基础上增加了一个加法器。

很容易分析出上面电路的功能:信号a和信号b相加得到cc连到D触发器的输入端。当clk出现上升沿时,将c的值传给q。这与代码功能是一致的。
下面是代码和硬件所对应的波形图。


先看信号c的波形:c的产生只有与ad有关,与rst_nclk无关。ca+d的结果,按照二进制加法:0+0=00+1=11+1=0可以画出c的波形。
在第1个时钟期间,a=0d=0,所以c=0+0=0
在第2个时钟期间,a=1d=0,所以c=1+0=1
在第3个时钟期间,a=1d=1,所以c=1+1=0
在第4个时钟期间,a=0d=1,所以c=0+1=1
在第5到第6个时钟期间,a=0d=0,所以c=0+0=0
在第7个时钟期间,a=1d=1,所以c=1+1=0
在第8个时钟期间,a=0d=1,所以c=0+1=1
在第9个时钟期间,a=0d=0,所以c=0+0=0
在第10个时钟期间,a=0d=1,所以c=0+1=1

再看信号q的波形:qD触发器的输出,其只在rst_n的下降沿或者clk的上升沿才变化,其他时刻不变化,即adc发生变化时,q不会立刻发生改变。

下面具体分析每个时钟下q信号的情况:
rst_n10时,q立刻变成0
在第2个时钟上升沿,看到rst_n0。按代码功能,q仍然为0
在第3个时钟上升沿,看到rst_n0。按代码功能,q仍然为0
在第4个时钟上升沿,看到rst_n1c值为0q值为0。按代码功能,q变成0
在第5个时钟上升沿,看到rst_n1c值为1q值为0。按代码功能,q变成1
在第6个时钟上升沿,看到rst_n1c值为0q值为1。按代码功能,q变成0
在第7个时钟上升沿,看到rst_n1c值为0q值为0。按代码功能,q变成0
在第8个时钟上升沿,看到rst_n1c值为0q值为0。按代码功能,q变成0
在第9个时钟上升沿,看到rst_n1c值为1q值为0。按代码功能,q变成1
在第10个时钟上升沿,看到rst_n1c值为0q值为1。按代码功能,q变成0
在第11个时钟上升沿,看到rst_n1c值为1q值为0。按代码功能,q变成1

在讨论时序逻辑的加法器时,笔者对加法器的输出cD触发器的输出q分开进行讨论,就像两块独立的电路。同样的道理,在设计Verilog代码时也可以将其分开来进行编写。
先将下面的硬件电路用Verilog描述出来:

该电路对应的电路可以写成:
1
  
2
  
3
always  @(*)begin
  
    c = a + d;
  
end
也可以写成:
1
assign c = a + d;
上面的两段代码,都是描述同一加法器硬件电路。接着用Verilog对触发器进行描述。

其代码的写法如下:
1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
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

1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
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代码好坏的最基本标准,即不是看代码行数而是看硬件。




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|MDYBBS ( 粤ICP备16061416号 )

GMT+8, 2024-11-22 18:15 , Processed in 0.065826 second(s), 30 queries .

Powered by Discuz! X3.4

本论坛由广州健飞通信有限公司所有

© 2001-2019 Comsenz Inc.

快速回复 返回顶部 返回列表