数字系统设计与Verilog HDL (复习)
EDA(Electronic Design Automation)
就是以计算机为工作平台,以EDA软件工具为开发环境,以PLD器件或者ASIC专用集成电路为目标器件设计实现电路系统的一种技术。 1.电子CAD(Computer Aided Design)
2.电子CAE(Computer Aided Engineering) 3.EDA(Electronic Design Automation) EDA技术及其发展 p2
EDA技术的应用范畴
1.3 数字系统设计的流程
基于FPGA/CPLD
的数字系统设计流程
1. 原理图输入(Schematic diagrams ) 2、硬件描述语言 (HDL文本输入) 设计输入
硬件描述语言与软件编程语言有本质的区别
综合(Synthesis)
将较高层次的设计描述自动转化为较低层次描述的过程
◆行为综合:从算法表示、行为描述转换到寄存器传输级(RTL) ◆逻辑综合:RTL级描述转换到逻辑门级(包括触发器) ◆版图综合或结构综合:从逻辑门表示转换到版图表示,或转换到PLD器件的配置网表表示
综合器是能自动实现上述转换的软件工具,是能将原理图或HDL语言描述的电路功能转化为具体电路网表的工具
适 配
适配器也称为结构综合器,它的功能是将由综合器产生的网表文件配置于指定的目标器件中,并产生最终的可下载文件
对CPLD器件而言,产生熔丝图文件,即JEDEC文件;对FPGA器件则产生Bitstream位流数据文件 p8
仿真(Simulation)
功能仿真(Function Simulation) 时序仿真(Timing Simulation) 仿真是对所设计电路的功能的验证 p9
编程(Program)
把适配后生成的编程文件装入到PLD器件中的过程,或称为下载。
通常将对基于EEPROM工艺的非易失结构PLD器件的下载称为编程(Program),将基于SRAM工艺结构的PLD器件的下载称为配置(Configure)。
习 题
1.1 现代EDA技术的特点有哪些? 1.2 什么是Top-down设计方式?
1.3 数字系统的实现方式有哪些?各有什么优缺点?
1.4 什么是IP复用技术?IP核对EDA技术的应用和发展有什么意义? 1.5 用硬件描述语言设计数字电路有什么优势?
1.6 基于FPGA/CPLD的数字系统设计流程包括哪些步骤? 1.7 什么是综合?常用的综合工具有哪些?
1.8 功能仿真与时序仿真有什么区别? 第2章 FPGA/CPLD器件
2.1 PLD的分类 PLD的发展历程
PLD的集成度分类
可编程逻辑器件(PLD) 简单PLD 复杂PLD PROM PLA PAL GAL CPLD FPGA
一般将GAL22V10(500门~750门 )作为简单PLD和高密度PLD的分水岭
PLD器件按照可以编程的次数可以分为两类:
(1) 一次性编程器件(OTP,One Time Programmable) (2) 可多次编程器件
OTP类器件的特点是:只允许对器件编程一次,不能修改,而可多次编程器件则允许对器件多次编程,适合于在科研开发中使用。 按编程特点分类 p15
(1)熔丝(Fuse)
(2)反熔丝(Antifuse)编程元件
(3)紫外线擦除、电可编程,如EPROM。
(4)电擦除、电可编程方式,(EEPROM、快闪存储器(Flash Memory)),如多数CPLD (5)静态存储器(SRAM)结构,如多数FPGA 按编程元件和编程工艺分类
PLD器件的原理结构图 2.2 PLD的基本原理与结构
PLD电路符号表示
与门、或门的表示
PLD连接表示法
PLD的输入缓冲电路
简单阵列的表示
p20 PROM
PROM表达的PLD阵列图
p21 PROM
用PROM完成半加器逻辑阵列
F0?A0A1?A0A1F1?A1A0
p22
2.5 FPGA的原理与结构 查找表结构
4输入LUT及内部结构图 p23
习 题
2.1 PLA和PAL在结构上有什么区别?
2.2 说明GAL的OLMC有什么特点,它怎样实现可编程组合电路和时序电路? 2.3 简述基于乘积项的可编程逻辑器件的结构特点? 2.4 基于查找表的可编程逻辑结构的原理是什么? 2.5 基于乘积项和基于查找表的结构各有什么优缺点?
2.6 CPLD和FPGA在结构上有什么明显的区别,各有什么特点? 2.7 FPGA器件中的存储器块有何作用? p24
第3章 Quartus II集成开发工具
基于Quartus II进行EDA设计开发的流程 p26
设计一个半加器
p27
设计一个全加器
连接好的全加器原理图f_adder.bdf
习 题
3-1 基于Quartus II软件,用D触发器设计一个2分频电路,并做波形仿真,在此基础上,设计一个4分频和8分频电路,做波形仿真。 。 3-2 基于Quartus II软件,用7490设计一个能计时(12小时)、计分(60分)和计秒(60秒)的简单数字钟电路。设计过程如下:
(1)先用Quartus II的原理图输入方式,用7490连接成包含进位输出的模60的计数器,并进行仿真,如果功能正确,则将其生成一个部件;
(2)将7490连接成模12的计数器,进行仿真,如果功能正确,也将其生成一个部件; (3)将以上两个部件连接成为简单的数字钟电路,能计时、计分和计秒,计满12小时后系统清0重新开始计时。
(4)在实现上述功能的基础上可以进一步增加其它功能,比如校时功能,能随意调整小时、分钟信号,增加整点报时功能等。
第4章 基于宏功能模块的设计
8位有符号乘法器电路 功能仿真波形 p31
模24方向可控计数器电路
lpm_counter计数器功能仿真波形
锁相环电路
功能仿真波形 习 题
4.1 采用Quartus II软件的宏功能模块lpm_counter设计一个模为60的加法计数器,进行编译和仿真,查看仿真结果。
4.2 采用Quartus II软件的宏功能模块lpm_rom,用查表的方式设计一个实现两个8位无符号数加法的电路,并进行编译和仿真。
4.3 先利用LPM_ROM设计4位×4位和8位×8位乘法器各一个,然后用Verilog语言分别设计4位×4位和8位×8位乘法器,比较两类乘法器的运行速度和资源耗用情况。
4.4 用数字锁相环实现分频,假定输入时钟频率为10MHz,想要得到6MHz的时钟信号,试用altpll宏功能模块实现该电路。
第5章 Verilog HDL设计初步
5.2 Verilog设计举例
【例1】4位全加器
module adder4(cout,sum,ina,inb,cin); output[3:0] sum; output cout;
input[3:0] ina,inb; input cin;
assign {cout,sum}=ina+inb+cin; endmodule p36
Verilog程序的特点
(1)Verilog程序是由模块构成的。每个模块的内容都嵌在module和endmodule两个关键字之间;每个模块实现特定的功能;模块是可以进行层次嵌套的。
(2)每个模块首先要进行端口定义,并说明输入和输出口(input、output或inout),然后对模块功能进行描述。
(3)Verilog程序书写格式自由,一行可以写几个语句,一个语句也可以分多行写。 (4)除了endmodule等少数语句外,每个语句的最后必须有分号。
(5)可以用 /*??*/ 和 //?? 对Verilog程序作注释。好的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。 p37
Verilog 模块的模板
module <顶层模块名> (<输入输出端口列表>); output 输出端口列表; //输出端口声明 input 输入端口列表; //输入端口声明 /*定义数据,信号的类型,函数声明*/ reg 信号名; //逻辑功能定义
assign <结果信号名>=<表达式>; //使用assign语句定义逻辑功能 //用always块描述逻辑功能 always @ (<敏感信号表达式>) begin
//过程赋值
//if-else,case语句
//while,repeat,for循环语句 //task,function调用 end
//调用其他模块
<调用模块名module_name > <例化模块名> (<端口列表port_list >); //门元件例化
门元件关键字 <例化门元件名> (<端口列表port_list>); endmodule p38
习 题
5.1 用Verilog设计一个8位加法器,并进行综合和仿真,查看综合结果和仿真结果。 5.2 用Verilog设计一个8位计数器,并进行综合和仿真,查看综合结果和仿真结果。
第6章 Verilog HDL语法与要素
标识符(Identifiers) 标识符(Identifiers)
Verilog中的标识符可以是任意一组字母、数字以及符号“$”和“_”(下划线)的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。 Examples: count
COUNT //COUNT与count是不同的 _A1_d2 //以下划线开头 R56_68 FIVE p41 ◆ 整数 ◆ 实数 ◆ 字符串 6.2 常量
程序运行中,值不能被改变的量称为常量(constants),Verilog中的常量主要有如下3种类型: p42
整数按如下方式书写: +/-
即 +/-<位宽>'<进制><数字>
size 为对应二进制数的宽度;base为进制;value是基于进制的数字序列。 进制有如下4种表示形式: ◆ 二进制(b或B)
◆ 十进制(d或D或缺省) ◆ 十六进制(h或H) ◆ 八进制(o或O) 整数(integer) p43
Examples:
8'b11000101 //位宽为八位的二进制数11000101 8'hd5 //位宽为八位的十六进制数d5; 5'O27 //5位八进制数 4'D2 //4位十进制数2 4'B1x_01 //4位二进制数1x01 5'Hx //5位x(扩展的x),即xxxxx 4'hZ //4位z,即zzzz
8□'h□2A /*在位宽和'之间,以及进制和数值之间允许出现空格,但'和进制之间,数值间是不允许出现空格的,比如8'□h2A、8'h2□A等形式都是不合法的写法 */ 整数(integer) p44
实数(Real)有下面两种表示法。
◆ 十进制表示法。例如: 2.0
0.1 //以上2例是合法的实数表示形式 2. //非法:小数点两侧都必须有数字 ◆ 科学计数法。例如:
43_5.1e2 //其值为43510.0
9.6E2 //960.0 (e与E相同) 5E-4 //0.0005 实数(Real) p45
6.3 数据类型
Verilog有下面四种基本的逻辑状态。 ◆ 0:低电平、逻辑0或逻辑非 ◆ 1:高电平、逻辑1或“真” ◆ x或X:不确定或未知的逻辑状态 ◆ z或Z:高阻态
Verilog中的所有数据类型都在上述4类逻辑状态中取值,其中x和z都不区分大小写,也就是说,值0x1z与值0X1Z是等同的。
数据类型(Data Type)是用来表示数字电路中的物理连线、数据存储和传输单元等物理量的。 p46 net型
Net型数据相当于硬件电路中的各种物理连接,其特点是输出的值紧跟输入值的变化而变化。对连线型有两种驱动方式,一种方式是在结构描述中将其连接到一个门元件或模块的输出端;另一种方式是用持续赋值语句assign对其进行赋值。 wire是最常用的Net型变量。 wire型变量的定义格式如下:
wire 数据名1,数据名2,??数据名n;
例如: wire a,b; //定义了两个wire型变量a和b Examples:
wire[7:0] databus; //databus的宽度是8位 wire[19:0] addrbus; //addrbus的宽度是20位 p47
Variable型
variable型变量必须放在过程语句(如initial、always)中,通过过程赋值语句赋值;在always、initial等过程块内被赋值的信号也必须定义成variable型。
注意:variable型变量并不意味着一定对应着硬件上的一个触发器或寄存器等存储元件,在综合器进行综合时,variable型变量会根据具体情况来确定是映射成连线还是映射为触发器或寄存器。
reg型变量是最常用的一种variable型变量。定义格式如下: reg 数据名1,数据名2,??数据名n;
例如:reg a,b; //定义了两个reg型变量a,b Examples:
reg[7:0] qout; //定义qout为8位宽的reg型向量 reg[8:1] qout; p48
6.4 参数(parameter) 在Verilog语言中,用参数parameter来定义符号常量,即用parameter来定义一个标志符代表一个常量。参数常用来定义时延和变量的宽度。 其定义格式如下:
parameter 参数名1=表达式1,参数名2=表达式2,参数名3=表达式3, ?? ; 例如:
parameter sel=8,code=8'ha3;
//分别定义参数sel代表常数8(10进制),参数code代表常量a3(16进制) p49
6.5 向量 1.标量与向量
宽度为1位的变量称为标量,如果在变量声明中没有指定位宽,则默认为标量(1位)。举例如下:
wire a; //a为标量
reg clk; //clk为标量reg型变量
线宽大于1位的变量(包括net型和variable型)称为向量(vector)。向量的宽度用下面的形式定义: [msb : lsb] 比如:
wire[3:0] bus; //4位的总线 p50
6.6 运算符(Operators)
1.算术运算符(Arithmetic operators) 常用的算术运算符包括: + 加 - 减 * 乘 / 除 % 求模 p51
2.逻辑运算符(Logical operators) && 逻辑与 || 逻辑或 ! 逻辑非 p52
3.位运算符(Bitwise operators)
位运算,即将两个操作数按对应位分别进行逻辑运算。 ~ 按位取反 & 按位与 | 按位或 ^ 按位异或
^~,~^ 按位同或(符号^~与~^是等价的) p53
4.关系运算符(Relational operators) < 小于 <= 小于或等于 > 大于 >= 大于或等于 p54
5.等式运算符(Equality Operators) == 等于 != 不等于 === 全等
!== 不全等
6.缩位运算符(Reduction operators) & 与 ~& 与非 | 或 ~| 或非 ^ 异或 ^~,~^ 同或
7.移位运算符(shift operators) >> 右移 << 左移 p57
8.条件运算符(conditional operators) ?:
三目运算符,其定义方式如下:
signal=condition?true_expression:false_expression; 即:信号=条件?表达式1:表达式2;
当条件成立时,信号取表达式1的值,反之取表达式2的值。 p58
9.位拼接运算符(concatenation operators) { }
该运算符将两个或多个信号的某些位拼接起来。使用如下: {信号1的某几位,信号2的某几位,??,信号n的某几位} p59
习 题
6.1 下列标识符哪些是合法的,哪些是错误的?
Cout, 8sum, \\a*b, _data, \\wait, initial, $latch
6.2 下列数字的表示是否正确?
6'd18, 'Bx0, 5'b0x110, 'da30, 10'd2, 'hzF 6.3 定义如下的变量和常量: (1)定义一个名为count的整数;
(2)定义一个名为ABUS的8位wire总线;
(3)定义一个名为address的16位reg型变量,并将该变量的值赋为十进制数128; (4)定义参数Delay_time, 参数值为8; (5)定义一个名为DELAY的时间变量; (6)定义一个32位的寄存器MYREG;
(7)定义一个容量为128,字长为32位的存储器MYMEM; 第7章 Verilog行为语句 p61
Verilog HDL行为语句
类别 块语句
赋值语句
循环语句
编译向导语句 p62
7.1 过程语句 initial always
在一个模块(module)中,使用initial和always语句的次数是不受限制的。initial语句常用于仿真中的初始化,initial过程块中的语句仅执行一次;always块内的语句则是不断重复执行的。 p63
initial always
语句
串行块begin-end 并行块fork-join 持续赋值assign 过程赋值=、<= if-else case for repeat while forever `define `include
`ifdef, `else, `endif
可综合性
√ √
√ √ √ √ √
√ √ √
always过程语句使用模板
always @(<敏感信号表达式event-expression>) begin
//过程赋值
//if-else,case,casex,casez选择语句 //while,repeat,for循环 //task,function调用 end
“always”过程语句通常是带有触发条件的,触发条件写在敏感信号表达式中,只有当触发条件满足时,其后的“begin-end”块语句才能被执行。 p64
7.2 块语句
块语句是由块标志符begin-end或fork-join界定的一组语句,当块语句只包含一条语句时,块标志符可以缺省。
begin-end串行块中的语句按串行方式顺序执行。比如: begin
regb=rega; regc=regb; end
由于begin-end块内的语句顺序执行,在最后,将regb、regc 的值都更新为rega的值,该begin-end块执行完后,regb、regc 的值是相同的。 p65
7.3 赋值语句
持续赋值语句(Continuous Assignments)
assign为持续赋值语句,主要用于对wire型变量的赋值。 比如:assign c=a&b;
在上面的赋值中,a、b、c三个变量皆为wire型变量,a和b信号的任何变化,都将随时反映到c上来。 p66
7.4 条件语句 ( if-else语句)
if-else语句使用方法有以下3种: (1)if(表达式) 语句1; (2)if(表达式) 语句1; else 语句2;
(3)if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; ??
else if(表达式n) 语句n; else 语句n+1; p67
case语句的使用格式如下。
case (敏感表达式)
值1: 语句1; //case分支项 值2: 语句2; ??
值n: 语句n;
default:语句n+1; endcase case语句 p68
7.5 循环语句 repeat loop initial begin
for(i=0;i<4;i=i+1) out = out +1; end initial begin
repeat(5)
out = out +1; end initial begin i=0;
while(i<0) i=i+1; end for loop while loop
在Verilog中存在四种类型的循环语句,用来控制语句的执行次数。这四种语句分别为: (1)forever:连续地执行语句;多用在“initial”块中,以生成时钟等周期性波形。 (2)repeat:连续执行一条语句n次。
(3)while:执行一条语句直到某个条件不满足。 (4)for:有条件的循环语句。 p69
for语句
for语句的使用格式如下(同C语言):
for(表达式1;表达式2;表达式3)语句;
即:for(循环变量赋初值;循环结束条件;循环变量增值)执行语句; p70
7.6 编译指示语句
Verilog允许在程序中使用特殊的编译向导(Compiler Directives)语句,在编译时,通常先对这些向导语句进行“预处理”,然后再将预处理的结果和源程序一起进行编译。
向导语句以符号“`”开头,以区别于其它语句。Verilog提供了十几条编译向导语句,如:`define、`ifdef、`else、`endif、`restall等。比较常用的有`define,`include和`ifdef、`else、`endif等。 p71
宏替换`define
`define语句用于将一个简单的名字或标志符(或称为宏名)来代替一个复杂的名字或字符串,其使用格式为:
`define 宏名(标志符) 字符串 如:`define sum ina+inb+inc+ind
在上面的语句中,用简单的宏名sum来代替了一个复杂的表达式ina+inb+inc+ind,采用了这样的定义形式后,在后面的程序中,就可以直接用sum来代表表达式ina+inb+inc+ind了。 p72
文件包含`include
`include是文件包含语句,它可将一个文件全部包含到另一个文件中。其格式为: `include “文件名”
使用`include语句时应注意以下几点:
(1)一个`include语句只能指定一个被包含的文件。
(2)`include语句可以出现在源程序的任何地方。被包含的文件若与包含文件不在同一个子目录下,必须指明其路径名。
(3)文件包含允许多重包含,比如文件1包含文件2,文件2又包含文件3等。 p73
7.7 任务与函数 任务(task) 任务定义格式:
task <任务名>; //注意无端口列表 端口及数据类型声明语句; 其它语句; endtask 任务调用的格式为:
<任务名>(端口1,端口2,??);
需要注意的是:任务调用时和定义时的端口变量应是一一对应的。 p74
函数的目的是返回一个值,以用于表达式计算 函数的定义格式:
function <返回值位宽或类型说明> 函数名; 端口声明; 局部变量定义; 其它语句; endfunction
<返回值位宽或类型说明>是一个可选项,如果缺省,则返回值为1位寄存器类型的数据。 函数(function) p75
任务与函数的比较
p76
思考与练习
7.1 试编写求补码的Verilog程序,输入是带符号的8位二进制数。 7.2 试编写两个四位二进制数相减的Verilog程序。
7.3 有一个比较电路,当输入的一位8421BCD码大于4时,输出为1,否则为0。试编写出Verilog程序。
7.4 试编写一个实现3输入与非门的Verilog源程序。 p77
思考与练习
7.5 用Verilog语言设计一个类似74138的译码器电路,用Synplify软件对设计文件进行综合,观察RTL级综合视图和门级综合视图。
7.6 用Verilog语言设计一个功能类似74161的电路,用Synplify软件对设计文件进行综合,观察RTL级综合视图和门级综合视图。
7.7 用Verilog设计一个8位加法器,用Quartus II软件进行综合和仿真。 7.8 用Verilog设计一个8位计数器,用Quartus II软件进行综合和仿真。
第8章 数字设计的层次与风格 p79
Verilog设计的描述风格 结构(Structural)描述 行为(Behavioural)描述 数据流(Data Flow)描述 p80
在Verilog程序中可通过如下方式描述电路的结构 ◆ 调用Verilog内置门元件(门级结构描述) ◆ 调用开关级元件(晶体管级结构描述) ◆ 用户自定义元件UDP(也在门级) 8.2 结构(Structural)描述 p81
门级结构描述的2选1MUX
module MUX1(out, a, b, sel); output out;
input a, b, sel; not (sel_, sel); and (a1, a, sel_), (a2, b, sel); or (out, a1, a2); endmodule
p82
8.3 行为描述
就是对设计实体的数学模型的描述,其抽象程度远高于结构描述方式。行为描述类似于高级编程语言,当描述一个设计实体的行为时,无需知道具体电路的结构,只需要描述清楚输入与输出信号的行为,而不需要花费更多的精力关注设计功能的门级实现。 p83
行为描述的2选1MUX
module mux2(out, a, b, sel); output out;
input a, b, sel; reg out;
always @(a or b or sel) begin
if(sel) out = b; else out = a; end
endmodule
p84
8.4 数据流描述
数据流描述方式主要使用持续赋值语句,多用于描述组合逻辑电路,其格式为:
assign LHS_net=RHS_expression;
右边表达式中的操作数无论何时发生变化,都会引起表达式值的重新计算, 并将重新计算后的值赋予左边表达式的net型变量。 p85
数据流描述的2选1MUX
module MUX3(out, a, b, sel); output out;
input a, b, sel;
assign out = sel ? b : a; endmodule
p86
`include \
module add4_1(sum, cout, a, b, cin); output [3:0] sum; output cout;
input [3:0] a, b; input cin;
full_add1 f0(a[0],b[0],cin,sum[0],cin1); full_add1 f1(a[1],b[1],cin1,sum[1],cin2); full_add1 f2(a[2],b[2],cin2,sum[2],cin3); full_add1 f3(a[3],b[3],cin3,sum[3],cout); endmodule
结构描述的4位级连全加器 p87
module add4_2(cout,sum,a,b,cin); output[3:0] sum; output cout; input[3:0] a,b; input cin;
assign {cout,sum}=a+b+cin; endmodule
数据流描述的4位加法器 p88 习 题
8.1 Verilog支持哪几种描述方式,各有什么特点?
8.2 分别用结构描述和行为描述方式设计一个基本的D触发器,并进行综合。 8.3 分别用结构描述和行为描述方式设计一个JK触发器,并进行综合。 8.4 试编写同步模5计数器程序,有进位输出和异步复位端。 8.5 编写4位串/并转换程序。 8.6 编写4位并/串转换程序。 8.7 编写4位除法电路程序。