新書推薦:
《
复原力
》
售價:NT$
345.0
《
近代中国思维方式的演变(王中江著作系列)
》
售價:NT$
950.0
《
我可以近乎孤独地度过一生
》
售價:NT$
440.0
《
二十四节气生活美学
》
售價:NT$
340.0
《
古文观止(上+下)(2册)高中生初中生阅读 国学经典丛书原文+注释+译文古诗词大全集名家精译青少年启蒙经典读本无障碍阅读精装中国古代著名文学书籍国学经典
》
售價:NT$
440.0
《
问物:可触摸的意义
》
售價:NT$
375.0
《
宠物革命:动物与现代英国生活的形成
》
售價:NT$
360.0
《
世界杂货店:罗伯特·谢克里科幻小说集(新版)
》
售價:NT$
340.0
|
編輯推薦: |
本教材严格参照教育部高等学校电子电气基础课程教学指导分委员会制订的《电子电气基础课程教学基本要求》编写。全书注重激发学生的学习兴趣,突出模块化编程思想并详细介绍了IP设计、封装和调用方法;对于常用逻辑模块及逻辑系统案例的选取,采取由浅入深的方式,设计过程和例程尽量详细,可以直接动手实验。全书融合了东南大学电子科学与工程学院 数字系统课程的丰富教学经验,吸收了东南大学多年参与PLD竞赛的经验,并充分考虑产业界对电子信息类专业人才培养的具体需求,是一本真正意义上产学深度合作的教材。教学资源:1 教学课件 配书教案(PPT)可到清华大学出版社网站本书页面下载。2 设计平台 采用科研和教学中应用*广泛的Xilinx Artix-7器件和Vivado工具。3 程序代码 配书源程序在Github开源,并保持更新。4 教学视频 配书教学视频及实验操作视频可到OpenHW网站获取。
|
內容簡介: |
本书系统论述了数字电路与逻辑设计的理论、方法与实践技术。全书基于Verilog HDL与Vivado开发环境,共18章,详尽介绍了如下内容: 逻辑设计与Vivado基础、布尔代数与Verilog HDL基础、组合逻辑电路设计基础、时序逻辑电路设计基础、有限状态机设计基础、逻辑设计工程技术基础、Vivado数字积木流程、串行通信接口控制器、RAM接口控制器、字符点阵显示模块接口控制器、VGA接口控制器、数字图像采集、数字逻辑系统设计案例、单周期CPU设计案例、数字信号处理设计案例(FIR)、数字图像处理设计案例、大学生FPGA设计案例以及Xilinx资源导读。 为便于教师和广大读者学习与动手实践,本书配套提供了教学课件、教学视频及程序代码等教学资源。 本书适合作为普通高等院校电子信息类、电气信息类、自动化类专业的本科生教材,也可作为相关专业研究生参考教材,并适合作为电子与电气工程技术领域的科研工程技术人员的参考用书。
|
關於作者: |
汤勇明 教授,东南大学电子科学与工程学院副院长,先后参与完成了国家重点基础研究发展(973)计划项目、国家高技术发展(863)计划项目、国防科研项目、江苏省成果转化基金项目、国内外企业合作项目等大量科研项目与课题。参与电子系统设计等多门课程的教学工作,所指导的本科生、研究生多次参加各类竞赛并获奖。主持和参与校教学改革项目多项,先后获江苏省教学成果奖一等奖和二等奖各1次,江苏省科技进步一等奖1次。发表国际杂志、国际会议论文多篇,先后被SCI、EI、ISTP等收录,出版著作1部,累计已获授权国家发明专利超过10项。张圣清 博士,任教于东南大学信息科学与工程学院,负责通信系统综合课设计,数字图像处理等多门FPGA设计技术相关课程,具有丰富的学生创新创业与竞赛指导经验,所指导的学生团队曾多次夺得全国大学生电子设计竞赛一等奖。陆佳华 Xilinx学术合作亚太区经理,于2006年加入Xilinx公司,主要负责Xilinx公司在亚太区学术圈的教学与科研合作。在可编程逻辑器件领域有超过10年的研发及市场经验。曾参与了多个Xilinx技术应用指导项目的开发,同时也编著了全球第一本NetFPGA开发指导图书以及第一本Zynq开发指导图书。
|
目錄:
|
目录
第一部分逻辑设计基础
第1章逻辑设计概述及Vivado基础
1.1逻辑设计概况
1.2Verilog HDL语言基础
1.2.1硬件描述语言概述
1.2.2Verilog HDL语言要素和设计流程
1.3PLD器件基础
1.3.1可编程逻辑器件技术发展历程
1.3.2FPGA和CPLD简介
1.3.3Xilinx FPGA介绍
1.3.4FPGA选型应该考虑的问题
1.4Vivado开发环境及设计流程
1.4.1Vivado功能介绍
1.4.2Vivado用户界面介绍和菜单操作
1.4.3Vivado开发流程
第2章布尔代数和Verilog HDL基础
2.1布尔代数
2.1.1三种基本逻辑门
2.1.2四种常用逻辑门
2.2布尔定律
2.2.1单变量布尔定律
2.2.2双变量和三变量的布尔定律
2.3布尔代数化简
2.3.1公式法化简
2.3.2卡诺图化简
2.4Verilog HDL语言基础
2.4.1Verilog HDL模块及端口
2.4.2Verilog HDL数据类型声明
2.4.3Verilog HDL运算操作
第3章组合逻辑电路设计基础
3.1组合电路中的always块
3.1.1基本语法格式
3.1.2过程赋值
3.1.3变量的数据类型
3.1.4简单实例
3.2条件语句
3.2.1ifelse语句
3.2.2case语句
3.3循环语句
3.3.1for语句
3.3.2repeat语句
3.3.3while语句
3.3.4forever语句
3.4always块的一般编码原则
3.4.1组合电路代码中常见的错误
3.4.2组合电路中always块的使用原则
3.5常数和参数
3.5.1常数
3.5.2参数
3.6设计实例
3.6.1多路选择器
3.6.2比较器
3.6.3译码器和编码器
3.6.4十六进制数七段LED显示译码器
3.6.5二进制BCD码转换器
3.7练习题
第4章时序电路设计基础
4.1触发器和锁存器
4.1.1基本D触发器
4.1.2含异步复位的D触发器
4.1.3含异步复位和同步使能的D触发器
4.1.4基本锁存器
4.1.5含清0控制的锁存器
4.2寄存器
4.2.11位寄存器
4.2.2N位寄存器
4.2.3寄存器组
4.3移位寄存器
4.3.1具有同步预置功能的8位移位寄存器
4.3.28位通用移位寄存器
4.4计数器
4.4.1简单的二进制计数器
4.4.2通用二进制计数器
4.4.3模m计数器
4.5设计实例
4.5.1数码管扫描显示电路
4.5.2秒表
4.6练习题
第5章有限状态机设计基础
5.1引言
5.1.1有限状态机的特点
5.1.2Mealy状态机和Moore状态机
5.1.3有限状态机的表示方法
5.2有限状态机代码实现
5.3设计实例
5.3.1序列检测器设计
5.3.2ADC采样控制电路设计
5.3.3按键消抖电路设计
5.4课程练习
第6章逻辑设计工程技术基础
6.1数字电路稳定性
6.2组合逻辑与毛刺
6.2.1组合逻辑设计中的毛刺现象
6.2.2组合逻辑设计中毛刺的处理
6.3异步设计与毛刺
6.3.1异步时序电路中的毛刺现象
6.3.2异步时序电路中毛刺的处理
6.4Verilog HDL设计中的编程风格
6.4.1强调代码编写风格的必要性
6.4.2强调编写规范的宗旨
6.4.3变量及信号命名规范
6.4.4编码格式规范
6.5Xilinx开发环境中的其他逻辑设计辅助工具
第二部分常用逻辑设计模块
第7章Vivado数字积木流程
7.1IP基础
7.2打包属于自己的IP
7.3IP设计示例二进制转格雷码
7.4练习题
第8章串行通信接口控制器
8.1UART串口通信协议及控制器设计
8.1.1UART协议介绍
8.1.2UART协议实例
8.2PS2协议及实例设计
8.2.1PS2协议介绍
8.2.2PS2设计实例
8.3SPI同步串行总线协议及控制器设计
8.3.1SPI协议介绍
8.3.2SPI控制器模块实例
8.4I2C两线式串行总线协议及控制器设计
8.4.1I2C协议介绍
8.4.2I2C模块设计实例
8.5练习题
第9章RAM接口控制器
9.1内部存储器
9.1.1FIFO
9.1.2单端口RAM设计
9.1.3双端口RAM设计
9.2外部存储器
9.2.1DRAM介绍
9.2.2DDR SDRAM原理
9.2.3DDR SDRAM控制器原理
9.3练习题
第10章字符点阵显示模块接口控制器
10.1字符型液晶控制器设计
10.1.1LCD原理
10.1.2字符型LCD1602模块
10.1.3字符型液晶模块显示实例
10.2点阵OLED控制器设计
10.2.1OLED原理
10.2.2OLED驱动原理
10.2.3OLED显示实例
10.3练习题
第11章VGA接口控制器
11.1CRT显示器原理
11.2VGA控制器设计
11.2.1VGA视频接口的概念
11.2.2VGA的接口信号
11.2.3行同步和场同步
11.3VGA接口设计实例
11.3.1VGA显示条纹和棋盘格图像
11.3.2VGA图像显示实例文字图片显示或者数码相框
11.3.3VGA IP的使用
11.4练习题
第12章数字图像采集
12.1数字图像采集概述
12.2系统设计原理
12.2.1系统架构
12.2.2OV7725芯片介绍
12.2.3OV7725 SCCB协议
12.2.4OV7725配置寄存器
12.2.5OV7725图像采集
12.2.6Block RAM存储单元
12.2.7VGA显示的实现
12.3模块搭建与综合实现
12.4系统调试及板级验证
12.4.1引脚分配
12.4.2模块连接
12.5练习题
第三部分逻辑系统设计案例
第13章数字逻辑系统设计案例: 数字钟
13.1数字钟设计案例
13.1.1实验原理
13.1.2实验设计流程
13.2基于集成逻辑分析仪的调试
13.3约束设计
13.3.1物理约束
13.3.2时序约束
13.4练习题
第14章单周期处理器设计实例
14.1单周期处理器体系架构简介
14.1.1单周期处理器指令集简介
14.1.2单周期处理器系统结构
14.2设计流程
14.2.1实验原理
14.2.2设计与验证
第15章数字信号处理实例: FIR滤波器
15.1FIR滤波器简介
15.2基于HLS的FIR滤波器实现流程
15.3工程测试
15.4生成IP
15.5练习题
第16章数字图像处理设计案例
16.1项目概述
16.2硬件介绍
16.3模块介绍
16.3.1RGB转HSV模块
16.3.2Color Detect色彩检测及坐标计算
16.4舵机控制模块
16.5实例实现过程
16.6板级验证
16.7练习题
第17章大学生FPGA设计案例
17.1逻辑控制
17.2图像处理
17.2.1VGA控制颜色
17.2.2视力表
17.2.3手部运动检测系统
17.3仪表仪器
17.3.1数字示波器
17.3.2逻辑分析仪
17.3.3波形发生器
17.4其他
第18章Xilinx资源导读
18.1获取本书参考例程
18.1.1Github介绍及使用
18.1.2OpenHW介绍
18.1.3Xilinx各类比赛
18.2Xilinx网站
18.2.1FPGA应用与解决方案
18.2.2文档资料查找
18.2.3Vivado工具和License的下载以及更新
18.2.4问题的查找
18.2.5Xilinx社区
18.3视频教程
18.4Vivado学习参考文档
参考文献
|
內容試閱:
|
前言 这是一本正规教材吗?看书名有点像儿童读物。这是一本设计开发手册吗?这里面怎么还有思考习题啊。其实,编者们也为这本书的名字费了不少神,这是本书的第一个书名建议,之后也揣摩了好几个,但到了最后还是觉得这第一次取的名字最好,因为它最符合编者们当下对基于FPGA芯片的逻辑系统设计的核心理念。如果说对于国内的高校和企业来讲,20世纪90年代,PLD还是新兴技术,仅在高端产品和产品设计初期有所应用外,如今PLD产品已经成为业内绝大多数的逻辑系统设计的核心,也是大多数工程师的基本设计能力。这些年来,逻辑系统设计和FPGA编程类的新教材不断涌现。应该说,这些方面国内并不缺乏好的专业教材或工具书,但是作为编者的这几个人在分别经历多年相关课程教学、工程师培训、新技术推广等不同的工作后,总觉得教材可以编写得更像工具书一点,工具书可以再多点基础知识介绍。于是,几个人就凑在了一起,相互鼓励、相互督促做了一件他们最想做但其实又最不愿意做的事: 编写一本教材。以下是本书的编者们围绕逻辑系统设计和FPGA编程学习的几点认识,也是编写这本书的一些粗浅想法:1 传统逻辑设计教学的内容和体系与当前行业的需求和实际产生了偏差随着可编程逻辑器件(programmable logic device,PLD,包括现在的CPLD和FPGA)为主的新技术及其行业的快速发展,直接改变了基于数字系统核心的消费电子产品、工业系统、医疗仪器设备乃至专用逻辑芯片本身的设计,重点表现在逻辑系统的门电路规模门槛快速提升和设计方法的巨大变革。相比之下,成熟的传统逻辑设计教学体系与行业界的实际产生了偏差,例如: 在传统逻辑设计教学中常用的真值表和卡诺图等在实际行业设计中难觅踪影; 传统逻辑设计实验教学中常用的74系列或4000系列中规模单元芯片采购困难且价格高,使得教学实验项目难以为继; 传统逻辑设计中当作理论讲解的竞争与冒险变成逻辑设计工程师时时刻刻面对的实际问题; 实际工程应用中急需的模块化设计理念和团队合作能力在传统逻辑教学中基本缺失。2 逻辑设计教学从传统的基础理论课程更多转向为实践类课程传统的逻辑设计或数字电路课程都是各大电子信息专业的基础核心课程,在布尔代数基本理论基础上重点讲解组合逻辑系统的分析和设计、时序逻辑系统的分析和设计,再补充一些计算机结构中的基本单元作为其应用案例。这些内容也积累了大量考试题库,但大量题库都是限于四个逻辑变量及以下、JK触发器容易命题但实际远不如D触发器实用、竞争冒险作为理论概念难以在习题中体现、状态机是综合类应用内容且入选习题的工作状态数不宜过多等,与此对应的实际情况是基于FPGA开展实际逻辑系统设计,几十万门的逻辑系统需求很平常,状态机已经成为大多数逻辑系统设计的基本单元,产品设计不断追求高性能使得毛刺问题在每一个设计中均需要认真处理等。因此,很多理论分析工作在当前设计中不再适用,大量设计能力需要通过不断实践经验积累。3 逻辑设计门槛的降低和逻辑系统复杂度的提升对模块化设计提出更高要求FPGA设计培训并不困难,越来越多的工程师通过自学就掌握了FPGA设计的基本能力,但随着FPGA芯片规模的快速提升和芯片价格的持续下降,大量复杂逻辑系统均已在单芯片内实现,且产品设计的时间周期越来越短,大量的逻辑系统设计都需要工程师团队分工合作完成,同时大量基本逻辑单元和功能模块会重复利用,因此,模块化编程思想和设计团队的标准逻辑模块设计积累都十分重要。把产品设计比作搭积木,谁的逻辑模块积木多以及谁的专有逻辑模块积木多会左右一个产品的市场成败。基于上述理念,本书希望建设成能满足目前从逻辑设计入门到具备基本逻辑设计工程师能力的学习道路上的教材或参考书。在组织规划过程中贯穿了以下几点思路:1 以目前主流且实用的FPGA和Verilog HDL为基础更新逻辑设计理论基础教学主线;2 将Vivado集成设计开发环境在第1章中就呈现给读者,让读者从一开始就能利用该开发工具学习具体逻辑设计;3 淡化以往卡诺图、真值表这类效率低且目前实用性不强的设计方法,强化基于硬件表述语言的硬件编程设计思想,区分软件编程常规的指令语句单步运行思维模式;4 突出模块化编程思想并详细介绍IP设计封装和调用办法;5 常用逻辑模块及逻辑系统案例选取由浅入深,设计过程和例程尽量详细,替代一般实验指导书。综上,本书具体分成三大部分: 第一部分逻辑设计基础(共六章); 第二部分常用逻辑设计模块(共五章); 第三部分逻辑系统设计案例(共六章)。将常用逻辑模块突显出来,主要是希望更多反映模块化编程思想和逻辑系统设计团队分工合作的趋势。本书的编辑整理工作得到东南大学教务处的立项支持,并在Xilinx大学计划的支持下进行,相关章节内容邀请了Xilinx大学计划的应用工程师团哲恒、实习生崔宏宇,以及东南大学电子科学与工程学院电路与系统方向的研究生参与整理,在此一并感谢。本书编辑整理均在编者的日常教学和大学计划工作之余进行,并分工合作完成,系统性和文字风格一致性可能会有所差异,并难免一些错漏,有待读者不断指出并修改。编者们也会持续补充设计案例并整理教学应用相关的教学资料,也希望大家能不断反馈相关意见,使本书能得到良好的修编,改进目标和方向。编著者2017年3月
第3章CHAPTER 3
组合逻辑电路设计基础
本章学习导言组合逻辑电路在任一时刻的输出状态只取决于该时刻的输入状态的组合,而与电路以前的状态无关。即电路只是由门电路组成,没有记忆单元,也没有反馈电路。第2章介绍的简单逻辑运算符可用于描述基本逻辑单元构成的门级设计,实际已经是基本的组合逻辑电路设计内容。本章主要介绍由中等规模组件构成组合逻辑电路的HDL描述,例如加法器、比较器和多路复用器等。本章首先结合实例对Verilog HDL行为描述的常用语法进行介绍,包括always块、if语句、case语句、参数和常数等,并通过一些常见组合逻辑电路实例来展示常用组合电路设计。本章的目的是给出组合逻辑电路基本概念,在介绍Verilog HDL用于组合逻辑设计的条件语句和循环语句等基本要素后,分别给出比较器、多路选择器等常见组合逻辑电路单元的介绍及其Verilog HDL实现。这些常用组合逻辑电路单元在逻辑系统中出现频率高,算得上搭建逻辑系统的最基本积木,熟练掌握这些单元对于复杂逻辑系统设计以及逻辑系统设计优化均有重要作用。
3.1组合电路中的always块在进行较为复杂的逻辑电路设计时,为了提高设计效率,通常采用较为抽象的行为描述,Verilog HDL使用一些顺序执行的过程语句来进行行为描述。这些语句封装在一个always块或initial块中,initial块仅在仿真开始的时候执行一次,而always块能够进行综合,生成能够执行逻辑运算或控制的电路模块。在本部分中重点讨论always块。always块可以看成一个包含内部过程描述语句的黑盒子,过程语句包含多种结构,但是很多都没有对应的硬件,编码不佳的always块通常会导致不必要的复杂实施或者根本无法综合。本部分主要关注可综合的组合逻辑电路设计,讨论内容限制为三种类型的语句: 块程序赋值、条件语句和循环语句。3.1.1基本语法格式带敏感信号列表的always块的简化使用格式如下:
always@敏感信号列表
begin可选的模块名
可选的本地变量声明;
顺序执行语句;
顺序执行语句;
end
敏感信号列表是always块响应的信号和事件列表,对于组合电路,应该包含所有的输入信号。当有两个或者两个以上的信号时,在Verilog HDL 1995中,它们之间可以用关键字or来连接,例如:
always@a or b or c
Verilog HDL 2001规范中,可以使用,来区分,例如:
always@a , b , c
在本书中,使用Verilog HDL 2001规范。@(敏感信号列表)项实际上是一个时序控制结构,它是可综合always块中的唯一时序控制结构。模块体可包含任意数目的过程语句,当模块体只有一条语句时,定界符begin和end可以省略。敏感信号可分为两种类型: 一种是电平敏感型; 一种是边缘敏感型。每个always过程一般只由一种类型的敏感信号来触发,而不能混合使用。对于组合电路,一般采用电平触发; 对于时序电路,一般由时钟边沿触发。Verilog HDL提供了posedge和negedge两个关键词来分别描述上升沿和下降沿。always块可以看作一个复杂的电路部分,可以被中止和激活。当敏感列表中的信号发生变化或某一事件发生时,该部分被激活并执行内部过程语句,由于没有其他时序控制结构,执行过程会一直持续到end模块才会终止,因此,always块实际上是个永远循环过程,每次的循环由敏感信号列表触发。3.1.2过程赋值过程赋值只能用在always块或initial块中,有两种赋值方式: 阻塞赋值和非阻塞赋值。其基本语法格式如下:
阻塞赋值: 变量名 = 表达式;
非阻塞赋值: 变量名 1;
end
end
endmodule
3.3.3while语句1. 语法
while语句的使用格式如下:
while表达式
begin
顺序执行语句;
顺序执行语句;
...
end
当顺序执行语句只有一条时,定界符begin和end可以省略。while语句在执行时,首先判断表达式是否为真,如果为真,则执行后面的语句或语句块,然后再回头判断表达式是否为真,若为真,再执行一遍后面的语句,如此不断,直到表达式为假。因此,在执行语句中,必须有一条改变表达式值的语句。2. 实例用while循环实现两个8位二进制数的乘法操作,实现代码见例3.11。例3.11两个8位二进制数相乘的while语句HDL描述
module mult_while
input[8:1]op0,
input[8:1] op1,
output reg [16:1]result
;
interger i=1;
always@*
begin
result = 0;
whileib为真时,若eq没有赋值,则会保持之前的值,从而会综合出相应的锁存器。有两种方法来解决不完整分支和不完整输出赋值错误,第一种是加上else分支并明确给所有输出变量赋值,代码变成:
always @*
ifa b
begin
gt= 1''b1;
eq= 1''b0;
end
else ifa ==b
begin
gt= 1''b0;
eq= 1''b1;
end
else
begin
gt= 1''b0;
eq= 1''b0;
end
另一种方法是在always块的起始部分,给每个变量赋默认值,以包含所有未指定的分支和未赋值的变量,代码则变成:
always @*
begin
gt = 1''b0;gt的默认赋值
eq = 1''b0;eq的默认赋值
if a b
gt = 1''b1;
else if a == b
eq = 1''b1;
end
如果gt和eq之后未赋值,则默认是0。如果case语句表达式的某些值未被分项表达式包含即不是fullcase语句,case语句也会产生相同的错误,例如以下代码:
reg[1:0] s;
case s
2''b00: y = 1''b1;
2''b10: y = 1''b0;
2''b11: y = 1''b1;
endcase
没有任何分支包含2''b01,如果s出现这种组合时,y会保持之前的值,这会综合出意外的锁存器。为了解决这种问题,必须保证任何时候y都被赋值,一种方法是在末尾采用关键字default以包含所有未指定值,例如可以用以下代码替代最后一条分支项表达式:
case s
2''b00: y = 1''b1;
2''b10: y = 1''b0;
default: y = 1''b1;
endcase
或者用无关值增加一条项目表达式:
case s
2''b00: y = 1''b1;
2''b10: y = 1''b0;
2''b11: y = 1''b1;
default: y = 1''bx;
endcase
另外,也可以在always块的开始部分赋给一个默认值:
y= 1''b0;
case s
2''b00: y = 1''b1;
2''b10: y = 1''b0;
2''b11: y = 1''b1;
endcase
3.4.2组合电路中always块的使用原则always块是一种灵活强大的语言结构,但必须谨慎使用,设计正确高效的电路并避免任何综合和仿真的差异性。以下是描述组合电路的编码原则:1 只在一个always模块中对变量赋值;2 组合电路采用阻塞赋值;3 在敏感列表中使用@*自动包含所有输入信号;4 确保包含ifelse和case语句的所有分支;5 确保所有分支的输出都被赋值;6 一种同时满足4和5原则的方法是在always块开始时给输出赋默认值;7 用代码描述full case和parallel case,而不用软件指令和属性;8 了解不同控制结构综合出电路的类型;9 思考生成的硬件电路。3.5常数和参数3.5.1常数
HDL代码经常在表达式和数组边界中使用常数值,这些值在模块内是固定不变的。好的设计是用符号常量代替固定文本,这使得代码清晰并有助于以后的维护和修改。在Verilog HDL中,可以用关键词localparam局部参数声明常量,例如,声明数据总线的位宽和范围如下:
localparamDATA_WIDTH = 8 ,
DATA_RANGE = 2**DATA_WIDTH - 1;
或定义符号端口名称:
localparamUART_PORT = 4''b0001,
LCD_PORT = 4''b0010,
MOUSE_PORT = 4''b0100;
声明中的表达式如2**DATA_WIDTH-1,在处理前已经执行,因此不会综合出其他物理电路,在本书中,用大写字母表示常数。以下例子可以很好地说明常数的使用,考虑带有进位的加法器,一种方法是手工扩展输入1位,执行常规加法,截取和的最高位作为进位,代码见例3.12。例3.12固定位宽的加法器HDL描述
module adder_carry_hard_lit
input wire [3:0] a, b,
output wire [3:0] sum,
output wire cout 进位
;
wire[4:0] sum_ext ;
assign sum_ext = {1''b0, a}{1''b0, b};
assign sum = sum_ext [3:0];
assign cout= sum_ext [4] ;
endmodule
代码描述的是4位加法器,其中固定文本如用来表示数据范围的3和4,例如wire[4:0]、sum_ext[3:0]及最高位sum_ext[4]。如果想改成8位加法器,这些字都要手工修改,如果代码很复杂而且这些文字出现在很多地方,将是一个繁琐而且容易出错的过程。为了增强可读性,可以采用符号常数N来表示加法器的位数,修改后代码见例3.13。常数使代码更容易理解和维护。例3.13使用常数的加法器HDL描述
module adder_carry_local_par
input[3:0] a, b,
output[3:0] sum,
output cout
;
常数声明
localparam N= 4 ,
N1 = N-1;
wire[N:0]sum_ext;
assign sum_ext = {1''b0, a}{1''b0, b};
assign sum= sum_ext [N1:0];
assign cout= sum_ext [N] ;
endmudule
3.5.2参数Verilog模块可以实例化为组件并成为更大设计模块的一部分。Verilog提供一种结构称为parameter,向模块传递信息,这种机制使得模块多功能化并能重复使用。参数在模块内不能改变,因此功能与常数类似。在Verilog HDL 2001中,参数声明部分可以在模块的开头即端口声明之前。其简单语法如下:
module 模块名
#
parameter参数名 = 默认值,
参数名 = 默认值;
...
;
例如,上述的加法器可以改成采用参数的加法器,见例3.14。例3.14使用参数的加法器HDL描述
module adder_carry_para
#parameter N=4
input[N-1:0] a, b,
output[N-1:0] sum,
output cout
;
常数声明
localparam N1= N-1;
wire[N:0] sum_ext;
assignsum_ext = {1''b0, a}{1''b0, b};
assignsum= sum_ext [N1:0];
assigncout= sum_ext [N] ;
endmudule
参数N被声明为默认值4,当N被声明之后,就可以像常数一样在端口声明和模块体中使用。如果之后加法器在其他代码中作为组件使用,那么就可以在组件实例化中给参数指定所需的值并将原来的默认值覆盖。如果省略了参数赋值,则采用默认参数,组件实例化的用法见例3.15。例3.15加法器实例化的例子
module adder_insta
input[3:0] a4, b4,
output[3:0] sum4,
outputc4,
input[7:0] a8, b8,
output[7:0] sum8,
outputc8
;
实例化8位加法器
Adder_carry_para #.N8 unit1
. aa8, . bb8, . sumsum8, . cout c8 ;
实例化4位加法器
Adder_carry_para unit2
.aa4, .bb4,.sumsum4,.coutc4;
endmodule
参数提供了一种创建可扩展代码机制,可调整电路的位宽以适应特定的需求,这使代码移植性更好,有利于设计重用。3.6设计实例本节给出一些常用的组合电路的设计实例,包括多路选择器、比较器、译码器、编码器和编码转换器等。3.6.1多路选择器多路选择器multiplexer是一个多输入、单输出的组合逻辑电路,一个n输入的多路选择器就是一个n路的数字开关,可以根据通道选择控制信号的不同,从n个输入中选取一个输出到公共的输出端。这里以一个4选1多路选择器为例,介绍多路选择器的Verilog HDL描述。4选1多路选择器的电路模型和真值表如图3.2所示。其中in0、in1、in2和in3是4个输入端口,s1和s0是通道选择控制信号端口,out是输出端口。当s1和s0取值分别为00、01、10和11时,输出端out将分别输出in0、in1、in2和in3的数据。例3.16和例3.17分别是4选1多路选择器的ifelse语句描述和case语句描述。4选1多路选择器的仿真波形如图3.3所示。
图3.24选1多路选择器的电路模型和真值表
例3.164选1多路选择器的ifelse语句描述
module mux41_if
input in0,in1,in2,in3,
input s0,s1,
output reg outout声明为reg类型
;
always@*
begin
if {s1,s0} == 2''b00out = in0;
else if{s1,s01} == 2''b01out = in1;
else if{s1,s01} == 2''b10out = in2;
elseout = in3;
end
endmodule
例3.174选1多路选择器的case语句描述
module mux41_case
input in0,in1,in2,in3,
input s0,s1,
output reg outout声明为reg类型
;
always@*
begin
case{s1,s0}
2''b00:out = in0;
2''b01:out = in1;
2''b10:out = in2;
default: out = in0;
endcase
end
endmodule
图3.34选1多路选择器的仿真波形图
3.6.2比较器数值大小比较在计算逻辑中是常用的一种方法,比较器就是用来完成这种数值大小比较逻辑的组合电路。1位二进制数比较器是它的基础,其电路真值表如表3.3所示。其中,in0和in1是1位输入比较信号,lt、eq和gt分别是两个输入信号大小的比较结果。例3.18是其Verilog HDL描述。注意: 在例3.18的程序清单中,在always块内的if语句之前,对gt、eq和lt都赋值为0。这样做是为了保证每个输出都被分配一个值。如果没有这样做,Verilog会认为你不想让它们的值改变,系统将会自动生成一个锁存器,那么得到的电路就不再是一个组合电路了。其仿真波形如图3.4所示。
表3.31位二进制比较器的真值表
in0in1gtin0in1eqin0=in1ltin0in1
gt = 1;
ifin0==in1
eq = 1;
ifin0in1
gt = 1;
ifin0==in1
eq = 1;
ifin04 如果个位大于4
x[11:8] = x[11:8] 3;加3
ifx[15:12]4 如果十位大于4
x[15:12] = x[15:12] 3;加3
x[17:1] = x[16:0]; 左移1位
end
bcd = x[17:8]; BCD
end
endmodule
图3.108位二进制数转BCD码的仿真波形图
3.7练习题1. 格雷码转换
格雷码循环二进制单位距离码是任意两个相邻数的代码只有一位二进制数不同的编码,它与奇偶校验码同属可靠性编码。从对应的n位二进制码字中直接得到n位格雷码码字,需要先对n位二进制的码字,从右到左,以0到n-1编号。如果二进制码字的第i位和i 1位相同,则对应的格雷码的第i位为0,否则为1当i 1=n时,二进制码字的第n位被认为是0,即第n-1位不变。公式表示为
Gi=BiBi 1n-1i0
G: 格雷码; B: 二进制码(1) 设计一个4位的二进制格雷码转换电路。(2) 编写代码并且进行仿真。(3) 利用FPGA进行实验验证。2. 双优先编码器双优先编码器返回最高优先级和次最高优先级请求代码,输入是16位req请求信号和2位最高优先级编码信号,输出是两组4位二进制代码,分别是4位最高优先级代码请求和4位次最高优先级代码请求。(1) 列出双优先编码器的真值表。(2) 设计电路并编写代码。(3) 仿真验证代码的正确性。(4) 设计测试电路并在原型板上用七段LED数码管显示两个输出信号,并编写代码。(5) 综合电路,编程FPGA并验证。3. BCD增量器二十进制BCD码用4位二进制表示1个十进制数,例如25910用BCD码表示为0010 0101 1001。BCD增量器用BCD码格式加1,例如加1后,0010 0101 100125910变为0010 0110 0000即26010。(1) 设计一个三位十进制数的12位增量器电路并编写代码。(2) 推导测试平台并采用仿真验证代码的操作。(3) 用七段LED数码管显示三位数,并编写代码。(4) 综合电路,编程FPGA并进行实验验证。4. 比较电路在本章设计实例中的比较电路是基于ifelse语句描述的,请思考如何用case语句写出比较电路。(1) 列出一个2位较大数判断电路的真值表。(2) 用case语句编写判断电路。(3) 用Vivado查看电路的RTL,思考RTL结果。(4) 仿真并且下载到板上验证。
|
|