《 E D A 技 术》 课 程 教 学 讲授:伍宗富 湖南文理学院电气与信息工程学院 2017年3月10日星期五.

Slides:



Advertisements
Similar presentations
计算机系统综合课程设计 Verilog HDL语言初步 主讲 杨全胜 东南大学计算机科学与工程学院 P.1.
Advertisements

2017年3月5日 单片机原理与应用 背景知识调查.
4.1 Verilog HDL入门 Verilog HDL程序模块结构 模块端口定义 模块内容 设 计 模 块 I/O说明
Introduction to Verilog
实验四 利用中规模芯片设计时序电路(二).
5.4 顺序脉冲发生器、 三态逻辑和微机总线接口 顺序脉冲发生器 顺序脉冲 计数型 分类 移位型.
Chapter 5 Sequential Logic Circuit
第10章 FPGA硬件设计 <EDA技术与应用> 课程讲义
Oracle数据库 Oracle 子程序.
Greatest Common Divisor ---最大公约数
数字系统设计 Digital System Design
时序电路 计数器分析及设计 刘鹏 浙江大学信息与电子工程学院 April 10, 2018 EE141
Chapter 5 Verilog 硬體描述語言
Chapter 5 Verilog硬體描述語言
计算机系统综合课程设计(2) Verilog HDL语言初步 主讲 杨全胜 东南大学计算机科学与工程学院 P.1.
Ch01-2 Verilog語法 資料流(DataFlow)設計 行為(Behavior)設計
第17章 Verilog中的高级结构 学习内容: 任务和函数的定义和调用 怎样使用命名块 怎样禁止命名块和任务 有限状态机(FSM)及建模.
EDA技术 廖义奎.
时序电路 计数器分析及设计 刘鹏 浙江大学信息与电子工程学院 March 31, 2016 EE141
嵌入式系统课程简介 宋健建 南京大学软件学院 2004/02/10.
第四阶段实验 ISP器件的设计与应用 一、实验目的 二、实验内容与要求 三、ISP器件的开发流程 四、EDA Pro2K实验系统介绍
欢迎参加VHDL培训 VHDL培训教程 浙江大学电子信息技术研究所 电子设计自动化(EDA)培训中心
走进编程 程序的顺序结构(二).
EDA 技术及应用 实验安排.
第四阶段实验 Verilog HDL简介 1 Verilog描述的一般结构 2 Verilog HDL基础知识 3 设计举例
 与非门参数测试与组合逻辑电路设计  集成触发器  计数、译码、显示电路
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
数字系统设计 Digital System Design
实验四 组合逻辑电路的设计与测试 一.实验目的 1.掌握组合逻辑电路的设计 方法 2.学会对组合逻辑电路的测 试方法.
语法进阶.
时序电路设计 刘鹏 浙江大学信息与电子工程系 Apr. 24, 2011 EE141
时序逻辑电路实验 一、 实验目的 1.熟悉集成计数器的功能和使用方法; 2.利用集成计数器设计任意进制计数器。 二、实验原理
第二章 Java语言基础.
逆向工程-汇编语言
CPU结构和功能.
精简指令集(RISC)CPU的构造原理和设计方法
第五章 VHDL主要描述语句.
移相正弦信号发生器设计 采用直接数字综合器DDS发生器的设计 原理:图1是此电路模型图
第4章 PHP流程控制语句.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言程序设计 主讲教师:陆幼利.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
数字电子技术 Digital Electronics Technology
第14章 对验证的支持 学习内容 理解Verilog文本输出 理解不同的读取仿真时间的系统函数 理解 Verilog文件I/O功能.
计算机学院 数字逻辑实验的要求.
计算机EDA设计 教 程 北航计算机学院 艾明晶.
设计描述 从16位乘法器的设计谈起.
C语言程序设计 第一章 数据类型, 运算符与表达式 第二章 顺序程序设计 第三章 选择结构程序设计 第四章 循环控制 第五章 数组.
设计示例一 用门级结构描述D触发器:.
第4章 Excel电子表格制作软件 4.4 函数(一).
组合逻辑电路 ——中规模组合逻辑集成电路.
实验三 16位算术逻辑运算实验 不带进位控制的算术运算 置AR=1: 设置开关CN 1 不带进位 0 带进位运算;
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
实验六 触发器逻辑功能测试 一、实验目的 二、实验仪器 1、熟悉并掌握RS、D、JK触发器的构成、工作原理和 功能测试方法。
长春理工大学 电工电子实验教学中心 数字电路实验 数字电路实验室.
实验二 带进位控制8位算术逻辑运算实验 带进位控制8位算术逻辑运算: ① 带进位运算 ② 保存运算后产生进位
《数字电子技术基础》(第五版)教学课件 清华大学 阎石 王红
实验五 MSI组合逻辑功 能部件的应用与测试
College of Computer Science & Technology
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
ASP.NET实用教程 清华大学出版社 第4章 C#编程语言 教学目标 教学重点 教学过程 2019年5月5日.
现代电子技术综合实验 陈学英.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
FPGA组合逻辑 王安然.
Verilog HDL 基本语法 STEP 2016/12/3.
按键处理部分 王安然.
工业机器人入门使用教程 ESTUN机器人 主讲人:李老师
编译原理实践 6.程序设计语言PL/0.
Presentation transcript:

《 E D A 技 术》 课 程 教 学 讲授:伍宗富 湖南文理学院电气与信息工程学院 2017年3月10日星期五

第十一讲 Verilog HDL基础知识 使用教材: Verilog HDL入门教程 教学目的:使学生会用Verilog HDL语言进行数字系统设计的方法。 教学重点:通过实例讲解Verilog HDL语言的应用方法。 教学难点:Verilog HDL语言设计数字系统基础。 教学方法:讲授法、计算机辅助法。 课时计划:6学时 使用教材: Verilog HDL入门教程 主要参考文献: [1] 刘洪涛.ARM嵌入式体系结构与接口技术[M].北京:人民邮电出版社 [2] 田耘等.无线通信FPGA设计[M].北京:电子工业出版社 [3] 孟宪元等.FPGA嵌入式系统设计教程[M].北京:电子工业出版社 [4] 徐光辉等.基于FPGA的嵌入式开发与应用[M].北京:电子工业出版社 [5] 沈文斌.嵌入式硬件系统设计与开发实例详解[M].北京:电子工业出版社 [6] 周立功等.SOPC嵌入式系统基础教程[M].北京:北京航空航天大学出版社 [7] 王彦等.基于FPGA的工程设计与应用[M].西安:西安电子工业出版社 [8] 周润景等.基于QuartusII的FPGA/CPLD数字系统设计实例[M].北京:电子工业出版社 [9] http://www.altera.com

课题: Verilog HDL基础知识 概述 Verilog HDL的基本结构 数据类型及常量、变量 运算符 语句 语句的顺序执行与并行执行

§11.1 概述 一、什么是Verilog HDL? Verilog HDL是一种应用广泛的硬件描述性语言,是硬件设计人员和电子设计自动化(EDA)工具之间的界面。 其主要目的是用来编写设计文件,建立电子系统行为级的仿真模型。即利用计算机的巨大能力对用Verilog HDL或VHDL建模的复杂数字逻辑进行仿真,然后再自动综合以生成符合要求且在电路结构上可以实现的数字逻辑网表(Netlist), 根据网表和某种工艺的器件自动生成具体电路,然后生成该工艺条件下这种具体电路的延时模型。仿真验证无误后用于制造ASIC芯片或写入EPLD和FPGA器件中。

二、Verilog HDL语言的主要特征 1、语法结构上,Verilog HDL语言与C语言有许多相似之处,并借鉴C语言的多种操作符和语法结构 2、Verilog HDL语言既包含一些高层程序设计语言的结构形式,同时也兼顾描述硬件线路连接的具体构件。 3、通过使用结构级或行为级描述可以在不同的抽象层次描述设计 包括三个领域和五个抽象层次,如下表7.1 所示

ALU、多路选择器、寄存器、总线微定序器、微存储器之间的物理连接方式 五个抽象层次 三个领域 行为领域 结构领域 物理领域 系统级 性能描述 部件及它们之间的逻辑连接方式 芯片模块电路板和物理划分的子系统 算法级 (芯片级) I/O应答算法级 硬件模块数据结构 部件之间的物理连接电路板底盘等 寄存器传输级 并行操作,寄存器传输,状态表 ALU、多路选择器、寄存器、总线微定序器、微存储器之间的物理连接方式 芯片、宏单元 逻辑级 布尔方程 门电路、触发器、锁存器 标准单元布图 电路级 微分方程 晶体管、电阻、电容等 晶体管布图

这两点显示: Verilog HDL语言与C语言的最大区别

三、为什么要用Verilog HDL? 电子设计规模越来越大(普通设计已达几百万门的数量级) ,复杂度越来越高。有必要用高级语言来表达其功能,隐藏其具体的细节实现。 提高逻辑设计的效率,降低设计成本,更重要的是缩短设计同期。 可读性强,易修改。 注意: 1、HDL追求对硬件的全面描述,而将HDL描述在目标器件上实现是由EDA工具软件的综合器完成。受限于目标器件,并不是所有Verilog HDL语句均可被综合。 2、结合EDA实验,我们选用ALTERA公司MAXPLUS II为工作平台,对MAXPLUS II不支持的语句不作详细介绍。

程序为模块结构,包含在module与endmodule之间 11.2 Verilog HDL的基本结构 输入、输出端口描述 --描述外部特性 模块名 端口列表 11.2.1 简单的Verilog HDL的例子 例9. 1 八位加法器的Verilog HDL源代码 准备实现的逻辑功能: module adder8 (cout, sum, ina,inb, cin); output[7:0] sum; output cout; input[7:0] ina,inb; input cin; assign {cout,sum}=ina+inb+cin; endmodule 程序为模块结构,包含在module与endmodule之间 ∑ 8 ci co cin cout ina inb sum 逻辑功能描述 --描述内部特性 问题:若要设计16位加法器,怎样修改?

例11.2 8位二进制加法计数器 逻辑功能: // 逻辑功能描述 单行注释符// 描述组合 语句块 并发语句 输入、输出端口描述 准备实现的 例11.2 8位二进制加法计数器 输入、输出端口描述 准备实现的 逻辑功能: module counter8 (out, cout, data, load, cin, clk); output [7:0] out; output cout; input load, cin, clk; input [7:0] data; reg [7:0] out; // 逻辑功能描述 always @(posedge clk) begin if (load) out= data;//置数 else out = out + cin; //计数或保持 end assign cout=&out&cin; // 进位 endmodule CTR8 M1 M2 G3 C4/2,3+ 8 3CT=255 1,4D load cin clk data out cout 数据类型定义:寄存器型 缺省:wire导线型 单行注释符// 时钟上沿执行下面语句块:时序 描述组合 并发语句 语句块

注意: 仿真: 在MAX+PLUSII开发软件仿真 置数 保持 注意: 在MAX+PLUSII系统,verilog HDL文件名的后缀必须为.v,且文件名必须与模块名相同。

11.2.2 Verilog HDL模块的结构 一.模块的概念 模块是描述某个设计的功能、结构和与其它模块通信的外部端口。 Verilog HDL中各个模块是并行运行。 模块可以调用其它模块的实例。 类似编程语言调用函数或子程序

二.模块的结构 双向端口 端口说明(input,output,inout) 参数定义(可选) module <模块名>(<端口列表>) 端口说明(input,output,inout) 参数定义(可选) 数据类型定义 //wire、reg、task、function 连续赋值语句(assign)//组合逻辑 过程块(always和initial) -行为描述语句 低层模块实例 //调用其它模块 任务和函数 延时说明块 endmodule

三、语句模块的描述方法 结构型描述 行为描述级 算法级 数据流描述 混合型描述 (一) 结构型描述 系统级 行为描述级 算法级 寄存器级 数据流描述 混合型描述 (一) 结构型描述 通过实例进行描述的方法,将预定义的基本元件实例嵌入到语言中,监控实例的输入,一旦其中任何一个发生变化便重新运算并输出。

1、在Verilog HDL中可使用如下结构部件: 用户自定义的模块。 用户自定义元件UDP。 内置门级元件。 内置开关级元件 这里讨论门级描述 2、例1 : 数据选择器的结构型描述(这里为门级描述) & ≥1 1 select A B OUT y2 y3 G1 G2 G3 G4 y1

and(与门) nand(与非门) or (或门) nor(或非门) xor(异或门) xnor(同门) (1)Verilog HDL常用门的关键字 多输入门 and(与门) nand(与非门) or (或门) nor(或非门) xor(异或门) xnor(同门) 多输出门 EN bufif1 bufif0 notif1 notif0 not(非门) buf(缓冲门 ) 三态门 bufif1,bufif0,notif1 ,notif0(三态门)

(2) 调用门原语的句法: 语法:门类型关键字 <例化的门名称>(端口列表) 其中端口列表为: 多输入门:(输出,输入1,输入2,……) 多输出门:(输出1,输出2,……输入) 三态门: (输出,输入,使能输入) 可以只有一个输出

(3)数据选择器的结构型描述程序清单 中间变量 非门实例 与门实例 实例名称 输出 输入 或门实例 & 1 select A B y2 y3 module mux2_1 (A, B, select, OUT); input A, B, select; //输入、输出列表 output OUT; wire y1,y2,y3; //变量定义 not G1(y1,select); //结构描述 and G2(y2,A,y1); and G3(y3,B,select); or G4(OUT,y2,y3); endmodule 中间变量 非门实例 与门实例 实例名称 输出 输入 或门实例 & ≥1 1 select A B OUT y2 y3 G1 G2 G3 G4 y1

3、例2 :边沿D触发器的结构型描述 module MS_ DFF (D , CLK , Q , not_Q) ; input D , CLK; output Q , not_Q ; not G9 (not_D , D) ,G10 (not_CLK , CLK) ,G11 (not_Y3 , Y3) ; nand G1 (Y1 , D , CLK ) , G2 (Y2 , not_D, CLK ) , G3 (Y3 , Y1 , Y4 ) , G4 (Y4 , Y2 , Y3 ) , G5 (Y5 , Y3 , not_CLK) ,G6 (Y6 , not_ Y3, not_CLK) , G7 (Q, Y5 , not_Q ) , G8 (not_Q , Y6 , Q) ; endmodule

(二) 数据流型描述 例 为数据选择器的数据流型描述。 module mux2x1_df (A, B, select, OUT); 是一种描述组合逻辑功能的方法,用assign连续赋值语句来实现 连续赋值语句完成如下的组合功能:等式右边的所有变量受持续监控,每当这些变量中有任何一个发生变化,整个表达式被重新赋值并送给等式左端 例 为数据选择器的数据流型描述。 module mux2x1_df (A, B, select, OUT); input A, B, select; output OUT; assign OUT = select ? B : A; endmodule 数据流型描述 条件运算符

(三) 行为级描述 是通过描述行为特性来实现,它的关键词是always, 其含义是一旦敏感变量发生变化,就重新一次进行赋值,有无限循环之意。这种描述方法常用来实现时序电路,也可用来描述组合功能。 例 为数据选择器的行为型描述。 module mux2x1_bh(A, B, select, OUT); input A, B, select; output OUT; reg OUT; //行为型描述, select、A 、 B为敏感变量 always @ (select or A or B) if (select = = 0) OUT = A; else OUT = B; endmodule

(四) 混合型描述 用户可以混合使用上述三描述方法。 但需特别说明: (四) 混合型描述 用户可以混合使用上述三描述方法。 但需特别说明: 模块中的门的实例、模块实例语句、assign语句和always语句是并发执行的,即执行顺序跟书写次序无关。

module tri_inout(tri_inout,out,data,en,clk); input en,clk; 例、双向三态端口的描述 module tri_inout(tri_inout,out,data,en,clk); input en,clk; input [7:0] data; output[7:0] out; inout [7:0] tri_inout; wire [7:0] tri_inout; reg [7:0] out; assign tri_inout= en?data:8'bz; always @(posedge clk) out=tri_inout; endmodule

仿真注意事项: 双向管脚在仿真图中拆分二个 管脚作输出用时,输入应设定为高阻

11.3 数据类型及常量、变量 常用词法: Verilog HDL区分大小写。 Verilog HDL的关键字(如:always、and、input等)都采用小写。关键字见书后附录B。 Verilog HDL的注释符为: 单行注释符:// 多行注释符:/* …… */

11.3.1 常量 对应二进制的宽度 一.数字 进制说明 十进制可缺省 语法:<位宽> ' <进制> <数值>. 四种进制表示方式: 二进制(b或B) 八进制(o或O) 十六进制(h或H) 十进制(d或D)

注意: 4种进制表示方式: 不允许用x和z 位宽小于相应数值的实际位数时,相应的高位部分被忽略 ,4'd61与4‘B1101相同。 61=(111101)2 4种进制表示方式: 不允许用x和z 数制 进制符号 值 例 二进制 b或B 0,1,x(不定值),z(高阻) 8'b11000101, 8'b1010zzzz, 8'b0101xxxx,7'b1010zzz 八进制 o或O 0~7,x,z 8'o305, 7'o12z 十进制 d或D 0~9 4'd61,45 十六进制 h或H 0~ f, x,z 8'hc5, 8'haz, 8‘hcx

二. 常量 语法: parameter 参数名1=表达式,参数名2=表达式,…… ; 例: parameter count_bits=8; 二. 常量 语法: parameter 参数名1=表达式,参数名2=表达式,…… ; 例: parameter count_bits=8; parameter sel=8,code=8’ha3; parameter datawidth=8;addrwidth= datawidth*2; 使用常量的目的:(1)便于阅读,(2)便于修改。 以n位计算器为例

常量:定义计数器的位数 n位计算器 修改常数值即可修改计数器的位数 module counter8 (out, cout, data, load, cin, clk); parameter count_bits=8; output [count_bits :1] out; output cout; input load, cin, clk; input [count_bits :1] data; reg [count_bits :1] out; always @(posedge clk) begin if (load) out= data; else out = out + cin; end assign cout=&out&cin; endmodule 常量 修改常数值即可修改计数器的位数

11.3.2 变量 一、分类: 指硬件电路中的各种连接, 输出始终根据输入的变化而更新其值的变化 网络型(nets type): 寄存器型(register type): 常指硬件电路中具有状态保持作用的器件,如触发器、寄存器等

MAXPLUS II只支持数wire ,tri (一)nets型 类型 功能 wire,tri 连线类型 wor,trior 多重驱动时,具有线或功能的连线型 wand,triand 多重驱动时,具有线与功能的连线型 tri1/tri0 上拉电阻/下拉电阻 supply1/supply0 电源(逻辑1)/地(逻辑0) MAXPLUS II只支持数wire ,tri 以下只介绍wire型变量

1、wire型变量: 最常用的nets型变量 常用来表示用assign语句赋值的组合逻辑信号 取值为:0,1,x(不定值),z(高阻) 注意: Verilog HDL模块中的输入/输出信号类型缺省时,自动定义为wire型变量

2、wire型变量的定义 语法: wire 数据1,数据2,……数据n; 例子: wire a,b,c wire[7:0] databus //定义了八位宽wire型向量数据总线 wire[20:1] addrbus //定义了20位宽wire型向量地址总线

MAXPLUS II只在for语句支持integer MAXPLUS II不支持数real、time (二)register型: 类 型 功能说明 reg 常用的寄存器型变量 如触发器、寄存器等 integer 32位带符号整数型变量 纯数学的抽象描述,不对应任何硬件电路。 real 64位带符号实数型变量 time 无符号时间变量 MAXPLUS II支持REG MAXPLUS II只在for语句支持integer MAXPLUS II不支持数real、time

reg型变量的定义 语法: 例子: 二维向量称为存储器变量 MAXPLUS II不支持存储器变量 reg 数据1,数据2,……数据n; reg a,b //定义了两个reg型变量a,b reg[8:1] data //定义了八位宽reg型向量 reg[7:0] mymem[1023:0] //定义1k字节(8bits)的存储器

操作数中的某一位为不定值x或高阻z,则结果为不定值x 11.4运算符 某一操作数有不确定,则结果也是不定值。 结果值要略去小数部分 = =与= = =区别: 例: a=5'b11x01, b= 5'b11x01则: (a= =b)=x; (a= = =b)=1 双目 = =(相等) != (不等) = = = (全等) != = (非全等) 等式运算符 <,<=,>,>= 关系运算符 若 A=5'b11001, B=5'b10101 ~A= 5'b00110 A&B= 5'b10001 A^B= 5'b01100 单目 ~(按位非) & (按位与) | (按位或) ^ (按位异或) ^ ~,~ ^ (按位同或) 位运算符 双目/单目 &&(与),!(非) ||(或) 逻辑运算符 17/3=5 9%4=1, + ,- ,* ,/, %(求模) 算术运算符 例子或说明 操作数个数 运算符 类别 操作数中的某一位为不定值x或高阻z,则结果为不定值x 将x或z看作是一种逻辑状态参与比较,结果只有0或1两种 。

与数字电路定义不同。(右移、左移互换) 运算符(续) 类别 运算符 操作数个数 例子或说明 缩减运算符 & (缩减与) | (缩减或) ~& (缩减与非) ~| (缩减或非) ^ (缩减异或) ^ ~,~ ^ (缩减同或) 单目 若:reg[3:0] a; 则:&a=a[0]&a[1]& a[2]&a[3] 移位运算符 >>(右移) <<(左移) 语法:A>>n或A<<n; 其中n为移位的位数,用0填补空位。 若 A=5'b11001,则A>>2为 5'b00110 条件运算符 ?: 三目 语法:signal=condition?true_expression:false_expression; 例,2选1的MUX: out=sel?in1:in0 连接运算符 {} {cout, sum} {a,b,c,d,e,f,g}

二、运算符的优先级: &,|,~&,~|, ^, ^~, ~^(缩减) ?: || && |, ^, ^~, ~^ 按位 &, &,|,~&,~|, ^, ^~, ~^(缩减) ?: || && |, ^, ^~, ~^ 按位 &, = =, !=, = = =, ! = = <, <=, >, >= <<, >> + ,- *, /, % 高优先级 低优先级 !,~ 优先级 运算符 逻辑 算术 书中有错

11.5 语句 一分类: 红色为:MAXPLUS II支持 赋值语句 条件语句 循环语句 结构说明语句 编译预处理语句 连续赋值语句 过程赋值语句 条件语句 if-else语句 case语句 循环语句 forever语句 repeat语句 while语句 for语句 结构说明语句 initial语句 always语句 task语句 function语句 编译预处理语句 `define语句 `include语句 `timescale语句 一分类: 红色为:MAXPLUS II支持

11.5.1 过程块 一、 always过程块 (1)always块语句模板: initial 过程块: 11.5.1 过程块 initial always 过程块: 当表达式的值改变时 ,就执行一遍块内语句 一、 always过程块 (1)always块语句模板: always @(<敏感信号表达式>) begin //过程赋值 //if语句 //case语句 //while,repert,for 语句 //task,functiony调用 end always过程块是不能嵌套使用。

(2)posedge与negedge关键字 上升沿 下降沿 (2)posedge与negedge关键字 例:同步时序电路的时钟为信号为clk,clear为异步清0信号。敏感信号可写为: //上升沿触发,高电平清0 有效 always @(posedge clk or posedge clear) //上升沿触发,低电平清0 有效 always @(posedge clk or negedge clear)

注意: 应改为: if(!clear) 异步控制时,块内逻辑描述要与敏感信号表达式一致 例:带异步清0的D触发器 in clk clear qout always @(posedge clk or negedge clear) begin if(clear) qout=0; else qout=in; end 矛盾? 应改为: if(!clear)

二 initial过程块 (3)说明: (1) initial 块语句模板: 主要面向功能模拟,通常不具有可综合性。 initial begin 语句1; 语句2; …… end 模拟0时刻开始执行,只执行一次。 同一模块内的多个initial过程块,模拟0时刻开始并行执行。 (2)例:对变量和存贮器初始化 initial过程块是不能嵌套使用。 initial begin reg1=0; for(addr=0;addr<size; addr= addr+1) memory[addr]=0; end

11.6 赋值语句 11.6.1 常用赋值语句 input a,b; output c assign c=a&b; 1. 连续赋值语句(assign ):常用于对wire型变量进行赋值 例: input a,b; output c assign c=a&b; & a b c a,b信号的任何变化,都将随时反映到c上来

2. 过程赋值语句:常用于对reg型变量进行赋值 一条非阻塞赋值语句的执行是不会阻塞下一条语句的执行,也就是说本条非阻塞赋值语句的执行完毕前,下一条语句也可开始执行。 (1)两种方式: 非阻塞赋值: 阻塞赋值: 非阻塞赋值语句在块结束时才完成赋值操作,在一块内非阻塞赋值语句并行执行。 赋值符号 <= 例:b <= a 该语句结束时就完成赋值操作,前面的语句没有完成前,后面的语句是不能执行。 在一块内非阻塞赋值语句顺序执行。 赋值符号 = 例:b = a

(2)阻塞赋值和非阻塞赋值的区别: 同时执行 例9.4 非阻塞赋值 a b module non_block (c, a,b,clk); 例9.4 非阻塞赋值 1D a b C1 c clk module non_block (c, a,b,clk); output c,b; input a,clk; reg c,b; always @(posedge clk) begin b<=a; c<=b; end endmodule 同时执行 b,c在clk上沿时同时进行状态变化 仿真:

顺序执行有 c= = b 例11.5阻塞赋值 module block (c, a,b,clk); output c,b; input a,clk; reg c,b; always @(posedge clk) begin b=a; c=b; end endmodule a b 1D c C1 clk 顺序执行有 c= = b 注意: 推荐初学者使用阻塞赋值,因为类似c语言的赋值方式。 仿真:

11.7 条件语句 11.7.1 if-else语句 1. 使用形式1 2. 使用形式2 3. 使用形式3:嵌套使用 条件表达式的值为1:按“真”处理,条件表达式的值为0:按“假”处理。 if (<条件表达式>)语句或语句块; 2. 使用形式2 if (<条件表达式>)语句或语句块1 ; else 语句或语句块2 ; 3. 使用形式3:嵌套使用 if (<条件表达式1>)语句或语句块1 ; else if (<条件表达式2>)语句或语句块2 ; …… else if (<条件表达式n>)语句或语句块n ; else 语句或语句块n+1;

例11.6 模为60的BCD码同步计数器 (2)功能 (1)输入、输出 (3) BCD码计数规则: 要求: 计数 (BCD) 1 保持 保持 同步置数 X 同步清0 功能 clk cin load reset reset load cin clk 8 data qout cout BCD码 进位:当状态qout=59且cin=1时,cout=1,否则cout=0. (3) BCD码计数规则: 状态=59,下一状态为0 状态≠59,个位=9时,下一状态:个位为0,十位加1 状态≠59,个位≠9 时,下一状态:个位加1,十位保持

(4)程序清单 计数 (BCD) 1 保持 同步置数 X 同步清0 功能 clk cin load reset 语句块 语句块 module count60(qout,cout,data,load,cin,reset,clk); output[7:0] qout; output cout; input[7:0] data; input load,cin,reset,clk; reg [7:0] qout; assign cout=(qout==8'h59)&cin;//进位 always @(posedge clk) begin if(reset) qout=0; //同步复位 else if (load) qout=data;//同步置数 else if(cin) //cin=1,计数cin=0,保持 if (qout==8'h59) qout=0 ; //qout=59,置0 else if (qout[3:0]==9) // 个位为9,个位置0,十位+1 begin qout[3:0]=0;qout[7:4]=qout[7:4]+1; end // 个位不为9,个位+1 ,十位不变 else qout[3:0]<=qout[3:0]+1; end endmodule 计数 (BCD) 1 保持 同步置数 X 同步清0 功能 clk cin load reset 语句块 语句块

(5)仿真: 置数 保持 (6) 程序的改进: 通过定义常量,增加程序的通用性。

改变MODULUS的值(<=99),即可改变模 module count60(qout,cout,data,load,cin,reset,clk); parameter MODULUS=8'h59; output[7:0] qout; output cout; input[7:0] data; input load,cin,reset,clk; reg [7:0] qout; assign cout=(qout==MODULUS)&cin;//进位 always @(posedge clk) begin if(reset) qout=0; else if(load) qout=data;//同步置数 else if(cin) //cin=1,计数cin=0,保持 if(qout==MODULUS) qout=0 ; else if (qout[3:0]==9) begin qout[3:0]=0;qout[7:4]=qout[7:4]+1; end else qout[3:0]<=qout[3:0]+1; end endmodule 改变MODULUS的值(<=99),即可改变模

11.7.2 case语句 1. case语句 语法: case (<敏感表达式>) 值1:语句或语句块1 ;//case分支项 值2:语句或语句块2 ; …… 值n:语句或语句块n ; default:语句或语句块n+1;//可省略 endcase 当敏感表达式的值为值1时,执行语句或语句块1 ;为值2时,执行语句或语句块2 ;依此类推。 当敏感表达式的值与所列出的值都不相等时, 条件表达式的值为0:按“假”处理。执行default后面的语句 default语句可省略。

所有输入中,任一变量变化,均执行:组合电路 在过程赋值,必须用reg,与是否组合无关 例11.7:BCD码-七段 译码器(共阴) module decode4_7(a,b,c,d,e,f,g,indec); output a,b,c,d,e,f,g; input[3:0] indec; reg a,b,c,d,e,f,g; always @(indec) begin case(indec) 4'd0 : {a,b,c,d,e,f,g}=7'b1111110; 4'd1 : {a,b,c,d,e,f,g}=7'b0110000; 4'd2 : {a,b,c,d,e,f,g}=7'b1101101; 4'd3 : {a,b,c,d,e,f,g}=7'b1111001; 4'd4 : {a,b,c,d,e,f,g}=7'b0110011; 4'd5 : {a,b,c,d,e,f,g}=7'b1011011; 4'd6 : {a,b,c,d,e,f,g}=7'b1011111; 4'd7 : {a,b,c,d,e,f,g}=7'b1110000; 4'd8 : {a,b,c,d,e,f,g}=7'b1111111; 4'd9 : {a,b,c,d,e,f,g}=7'b1111011; default : {a,b,c,d,e,f,g}=7'bx; endcase end endmodule 所有输入中,任一变量变化,均执行:组合电路 在过程赋值,必须用reg,与是否组合无关 a e c d b f g 4 bcd/7seg 类似真值表

例、有限状态机的设计实例 状态机通常可使用带有a l w a y s语句的c a s e语句建模。状态信息存储在寄存器中。c a s e语句的多个分支包含每个状态的行为。。 例 状态机的Verilog HDL的描述

module Moore_mdl (x, AB, CLK, RST); input x, CLK, RST; output [1:0] AB; reg [1:0] state; parameter S0 = 2’b00, S1 = 2’b01, S2 = 2’b10, S3 = 2’b11; always @ (posedge CLK or negedge RST) if (!RST) state = S0; else case (state) S0: if (!x) state = S1; else state = S0; S1: if (x) state = S2; else state = S3; S2: if (!x) state = S3; else state = S2; S3: if (!x) state = S0; else state = S3; endcase 图7.11状态机图 assign AB = state; endmodule 类似表状态

2.casez与casex语句 (1)语法与case语句相同 (2) casez、casex与case语句差别 casez在语句:对分支项的值中的高阻z位不予考虑,只关心其它位的比较结果。 casex在语句:对分支项的值中的高阻位(z)、不定值(x)均不予考虑,只关心其它位的比较结果。 ?:无关值,标识z、x另一种方法

例11.8 4线-2线高优先编码器 输入高电平有效 输出二进制原码 1 2 3 -要求: HPRI/BIN d0 d1 b0 d2 b1 例11.8 4线-2线高优先编码器 1 2 3 HPRI/BIN d3 d2 d1 d0 b1 b0 -要求: 输入高电平有效 输出二进制原码

-程序清单 default : b=2'b00; module decode4_2(d,b); output[1:0] b; input[3:0] d; reg[1:0] b; always @(d) begin casex (d) 4'b1zzx : b=2'b11; 4'b01xx : b=2'b10; 4'b001? : b=2'b01; 4'b0001 : b=2'b00; endcase end endmodule 1 2 3 HPRI/BIN d3 d2 d1 d0 b1 b0 应改为: default: b=2'b00; 书中: 未定义输入0000情况,所以此程序有问题 default : b=2'b00;

11.7.3使用条件语句注意事项 注意: 若没有列出所有条件分支,编译器认为条件不满足时,会引进触发器保持原值。 时序电路可利用上述特性来保持状态。 组合电路必须列出所有条件分支,否则会产生隐含触发器。

例11.9 隐含触发器举例:与门 隐含触发器 module buried_ff(c,b,a); output c; input a,b; 例11.9 隐含触发器举例:与门 隐含触发器 module buried_ff(c,b,a); output c; input a,b; reg c; always @(a or b) begin if ((b==1)&&(a==1)) c=1; end endmodule 只列出一种情况 & ≥1 a b c 改正错误,加上 else c=0;

无限循环,连续执行语句,多用initial块中,以生成周期性波形 11.8 循环语句 分类 无限循环,连续执行语句,多用initial块中,以生成周期性波形 forever语句: repeat语句: while语句: for语句: 连续执行语句或语句块n次 条件循环,执行语句或语句块,直到某个条件不满足 条件循环,,条件满足时,执行语句或语句块 MAX+PLUSII只支持for语句

11.8.1 for 语句 1.语法: for (<变量赋初值语句> ; <条件表达式> ; <变量增值语句>) 循环体语句或语句块; 2.执行过程: (1)执行“变量赋初值语句” (2)判断“条件表达式”, 真:执行“循环体语句或语句块”,继续执行第(3)步。 假:循环结束,退出。 (3)执行“变量增值语句”,转到(2)继续执行。

3 例子: 例11.10 7人投票表决器(多数表决) 中间变量 循环变量 for 语句 4~7时:sum[2]=1 例11.10 7人投票表决器(多数表决) module voter7 (pass,vote); output pass; input[6:0] vote; reg[2:0] sum; integer i; reg pass; always @(vote) begin sum=0; for (i=0;i<=6;i=i+1) if(vote[i]) sum=sum+1 ; if (sum[2]) pass=1; //(sum>=4)==(sum[2]) else pass=0; end endmodule 中间变量 循环变量 for 语句 4~7时:sum[2]=1 用此语句代替,更易懂。

例11.11 8位二进制乘法器 为0时:左移i-1位 for 语句 乘法方法: * 10010101 b 例11.11 8位二进制乘法器 为0时:左移i-1位 10110111 a * 10010101 b +10110111 a左移2位 + 10110111 a左移4位 + 10110111 a左移7位 乘法方法: module mult_for (outcome,a,b); parameter size=8 ; output[2*size:1] outcome; input[size:1] a,b; //乘数 reg[2*size:1] outcome; //积 integer i; always @(a or b) begin outcome=0; for (i=1;i<=size;i=i+1) if(b[i]) outcome=outcome+( a<<(i-1) ) ; end endmodule for 语句

repeat (<循环次数表达式> ) 循环体语句或语句块; 1. 语法: 2. 例9.11 用 repeat语句实现8位乘法器 module mult_repeat(outcome,a,b); parameter size=8 ; output[2*size:1] outcome; input[size:1] a,b; reg[2*size:1] outcome,temp_a; reg[size:1] temp_b; always @(a or b) begin outcome=0; temp_a=a; temp_b=b; repeat(size) if(temp_b[1]) outcome=outcome+temp_a ; temp_a=temp_a<< 1;// temp_b=temp_b>> 1;// end endmodule 注意: MAX+PLUSII不 支持repeat语句 循环体语句块;

11.8.3 while和forever语句 一、 while语句 二、 forever语句 语法: while (<条件表达式> ) 循环体语句或语句块; 二、 forever语句 语法: Forever 循环体语句或语句块; 注意: MAX+PLUSII不支持while语句和forever语句

11.9 task和function语句 一、任务( task) 1.定义格式: 2.调用格式: 端口与类型说明; 局部变量说明; 语句或语句块; endtask 2.调用格式: <任务名>( 端口1,端口2,…… ) 注意:MAX+PLUSII不支持task语句

1.定义格式: 2.调用格式: 隐含与函数同名的内部变量,通过函数名变量传递函数值。 二、函数(function) 可选,定义函数名变量的类型和位宽。缺省默认为,1位reg型。 隐含与函数同名的内部变量,通过函数名变量传递函数值。 1.定义格式: function <返回值位宽或类型> <函数名> 输入端口与类型说明; 局部变量说明; 语句或语句块; endfunction 两者一一对应,排序、类型必须一致。 2.调用格式: <函数名>( <输入表达式1>, <输入表达式2>,…… )

例:函数定义和调用:计算输入信号0的个数。 module function_example (in,out); input[7:0] in; output[2:0] out; reg[2:0] out; function[2:0] gefun; input[7:0] x; reg[2:0] count; integer i; begin count=0; for(i=0;i<=7;i=i+1) if (x[i]==1'b0) count=count+1 ; gefun=count; end endfunction always @(in) out=gefun(in); endmodule 一致 函数 定义 //输入端口说明 局部变量说明; 函数调用

11.10 编译预处理 2、说明 1、 Verilog HDL语言提供了十多条的编译指令,本节只介绍常用的三种 `define 11.10 编译预处理 1、 Verilog HDL语言提供了十多条的编译指令,本节只介绍常用的三种 `define `include `timescale 书中符号有误 2、说明 编译指令以`(反引号)开头。 编译指令非Verilog HDL的描述,因而始译指令结束不需要加分号。 编译指令不受模块与文件的限制。在进行Verilog HDL语言编译时,已定义的编译指令一直有效,直至有其它编译指令修改它或取消它。

一、宏编译指令 `define 1、`define指令用于文本替换,它很像C语言中的#define 指令,语法格式如下: 例`define wordsize 8 以上语句中,用易懂的宏名wordsize来代替抽象的数字8;要采用了这样的定义后,在编译过程,一旦遇到wordsize则用8来代替。

二、文件包含指令 `include 1、`include 编译器指令用于嵌入内嵌文件的内容。文件既可以用相对路径名定义,也可以用全路径名定义, 例如: ` include " . . / . . /primitives.v “ 2、编译时,这一行由文件“../ ../ primitives . v” 的内容替代。

`timescale <计时单位> / <精度单位> 时延都用单位时间表述的,且是一个相对的概念。 `timescale编译指令用于定义计时单位与精度单位。实际时间相关联。`timescale编译指令的格式为: `timescale <计时单位> / <精度单位> 时间度量有:s、ms、us、ns、ps(10-12s)和fs(10-15s), 计时单位和精度单位只能取1,10或100 计时单位必须大于精度单位。 例如: ` timescale 1ns / 100 ps//表示计时单位为1ns, 精度单位100ps。 ` timescale 1ps / 10 ps //非法定标。

11.11 语句的顺序执行与并行执行 一、assign语句之间:并行执行(同时执行) 二、过程块之间( always, initial ):并行执行 三、 assign语句与过程块之间:并行执行 非阻塞语句类似并行语句 四、 过程块( always, initial )内部 串行块(begin-end):顺序执行 并行块(fork-join ):并行执行 注意:MAX+PLUSII不支持fork-join语句

11.12 用Verilog HDL设计数字电路 主要内容: 11.12.2常用时序电路模块 11.12.1 常用组合电路的设计 门电路的描述 译码器、编码器 数据选择器 奇偶校验器 BCD码-七段 译码器 运算电路 11.12.2常用时序电路模块 D触发器 数据锁存器 数据寄存器 移位寄存器 各种计数器

11.12.1 常用组合电路的设计 11.12.1.1 简单门电路的描述 & A B C D F G1 G2 G3 1.基本门电路的描述 11.12.1 常用组合电路的设计 11.12.1.1 简单门电路的描述 & ≥1 A B C D F F1 F2 G1 G2 G3 1.基本门电路的描述 方法1:调用门原语 module gate1(F, A, B, C, D); input A, B, C, D; output F; wire F1,F2; nand G1 ( F1, A, B ); and G2 ( F2, B, C, D); or G3 ( F, F1, F2); endmodule 门的名称:可省略。 原语 结构描述 调用格式: 多输入门:原语名 < 例化名称> (输出,输入1,输入2……) 非门: 原语名 < 例化名称> (输出,输入)

assign F=~(A & B)|(B & C & D); endmodule ≥1 A B C D F F1 F2 module gate2(F,A,B,C,D); input A,B,C,D; output F; assign F=~(A & B)|(B & C & D); endmodule 逻辑表达式 方法3:用过程赋值语句描述 module gate3(F,A,B,C,D); input A,B,C,D; output F; reg F; always @(A or B or C or D) begin F=~(A & B) | (B & C & D); end endmodule 敏感信号表: 与同步时序电路差别?

module tristate(in, oe, out); input in, oe; output out; tri out; 2.三态门 EN out in oe b1 例11.12.2 用bufifl关键字描述的三态门 module tristate(in, oe, out); input in, oe; output out; tri out; //注意三态门端口的排列顺序 bufif1 b1(out, in, oe);//(输入,输出,使能) endmodule 与wire一样 EN Bufif1原语: 例11.12.3 用assign描述的三态门 module tri_1(out, in, en); output out; input in, en; assign out = en ? in : 1'bz; //若en = 1, out = in;若en = 0 ,out为高阻态 endmodule EN out in en

module bidir(tri_inout , out , in , en , b); inout tri_inout; 例11.12.4 用三态双向驱动器 双向端口 module bidir(tri_inout , out , in , en , b); inout tri_inout; output out; input in, en, b; assign tri_inout = en ? in : 1'bz;//三态门 assign out = tri_inout ^ b; endmodule EN in en =1 tri_inout out b

11.12.1.2译码器、编码器 1. 3线_8线译码器(输出低电平有效) out0 out7 1 2 in0 in1 in2 真值表 1. 3线_8线译码器(输出低电平有效) 01234567 out0 out7 BIN/OCT 1 2 in0 in1 in2 module edcoder_38(out, in); output[7:0] out; input[2:0] in; reg[7:0] out; always @(in) begin case(in) 3'd0: out = 8'b1111_1110; 3'd1: out = 8'b1111_1101; 3'd2: out = 8'b1111_1011; 3'd3: out = 8'b1111_0111; 3'd4: out = 8'b1110_1111; 3'd5: out = 8'b1101_1111; 3'd6: out = 8'b1011_1111; 3'd7: out = 8'b0111_1111; endcase end endmodule 分隔符,便于阅读 真值表

2. 8 线_ 3线高优先编码器 方法1:用if_else语句描述编码器 outcode1 outcode2 1 2 outcode0 2. 8 线_ 3线高优先编码器 方法1:用if_else语句描述编码器 module encoder8_3(none_on,outcode,a, b, c, d, e, f, g, h); output[2:0] outcode; output none_on; input a, b, c, d, e, f, g, h; reg[3:0] outtemp; assign {none_on, outcode} = outtemp; always @(a or b or c or d or e or f or g or h) begin if(h) outtemp = 4'b0_111; else if(g) outtemp = 4'b0_110; else if(f ) outtemp = 4'b0_101; else if(e) outtemp = 4'b0_100; else if(d) outtemp = 4'b0_011; else if(c) outtemp = 4'b0_010; else if(b) outtemp = 4'b0_001; else if(a) outtemp = 4'b0_000; else outtemp = 4'b1_000; end endmodule 引进变量,便于描述 01234567 BIN/OCT outcode1 outcode2 abcdefgh 1 2 outcode0 none_on (输入无效) outcode none_on

方法2:用case语句描述编码器 outcode1 outcode2 1 2 outcode0 none_on 真值表 module encoder_83(none_on,outcode,a, b, c, d, e, f, g, h); output[2:0] outcode; output none_on; input a, b, c, d, e, f, g, h; reg[3:0] outtemp; assign {none_on, outcode} = outtemp; always @(a or b or c or d or e or f or g or h) begin casex ({a, b, c, d, e, f, g, h}) 8'B????_???1 : outtemp=4'b0_111; 8'B????_??10 : outtemp=4'b0_110; 8'B????_?100 : outtemp=4'b0_101; 8'B????_1000 : outtemp=4'b0_100; 8'B???1_0000 : outtemp=4'b0_011; 8'B??10_0000 : outtemp=4'b0_010; 8'B?100_0000 : outtemp=4'b0_001; 8'B1000_0000 : outtemp=4'b0_000; 8'B0000_0000 : outtemp=4'b1_000; endcase end endmodule 01234567 BIN/OCT outcode1 outcode2 abcdefgh 1 2 outcode0 none_on (输入无效) 真值表

11.12.1.3 数据选择器 1. 用assign语句设计2选1 MUX module mux2_1(out , a , b , sel); output out; input a, b, sel; assign out = sel ? a : b; endmodule mux sel 1 b a out sel=1:out=a sel=0:out=b

module mux4_1(out , in0 , in1 , in2 , in3 , sel); output out ; 2. 用if-else语句描述4选1 MUX 共有8个4选1 MUX, 它们共用sel信号 module mux4_1(out , in0 , in1 , in2 , in3 , sel); output out ; input[7:0] in0 , in1 , in2 , in3 ; input[1:0] sel; reg[7:0] out ; always @(in0 or in1 or in2 or in3 or sel) begin if(sel== 2'b00) out = in0; else if(sel == 2'b01) out = in1; else if(sel == 2'b10) out = in2; else out = in3; end endmodule mux 1 out G 3 sel0 8 sel1 2 in0 in1 in2 in3 功能描述

module mux_4_1(out , in0 , in1 , in2 , in3 , sel); output[7:0] out ; 3. 用case语句描述4选1 MUX module mux_4_1(out , in0 , in1 , in2 , in3 , sel); output[7:0] out ; input[7:0] in0 , in1 , in2 , in3 ; input[1:0] sel; reg[7:0] out ; always @(in0 or in1 or in2 or in3 or sel) begin case(sel) 2'b00: out = in0; 2'b01: out = in1; 2'b10: out = in2; default: out = in3; endcase end endmodule 共有8个4选1 MUX, 它们共用sel信号 mux 1 out G 3 sel0 8 sel1 2 in0 in1 in2 in3 真值表

11.12.1.4 奇偶校验器 例11.10 奇偶位产生器 奇校验:输入数据“1”的个数为奇数。可用“异或”运算 11.12.1.4 奇偶校验器 例11.10 奇偶位产生器 奇校验:输入数据“1”的个数为奇数。可用“异或”运算 偶校验:输入数据“1”的个数为偶数。可用“同或”运算 module parity(even_bit ,odd_bit , input_bus); output even_bit ,odd_bit ; input[7:0] input_bus; assign odd_bit = ^ input_bus; //产生奇校验位 assign even_bit = ~odd_bit; //产生偶校验位 endmodule 仿真:

11. 12.1 .5 :BCD码-七段 译码器(共阴) 真值表 a e c d b f g bcd/7seg 1 2 4 8 module decode4_7(a,b,c,d,e,f,g,D); output a,b,c,d,e,f,g; input[3:0] D; reg a,b,c,d,e,f,g; always @(D) begin case(D) 4'd0 : {a,b,c,d,e,f,g}=7'b1111110; 4'd1 : {a,b,c,d,e,f,g}=7'b0110000; 4'd2 : {a,b,c,d,e,f,g}=7'b1101101; 4'd3 : {a,b,c,d,e,f,g}=7'b1111001; 4'd4 : {a,b,c,d,e,f,g}=7'b0110011; 4'd5 : {a,b,c,d,e,f,g}=7'b1011011; 4'd6 : {a,b,c,d,e,f,g}=7'b1011111; 4'd7 : {a,b,c,d,e,f,g}=7'b1110000; 4'd8 : {a,b,c,d,e,f,g}=7'b1111111; 4'd9 : {a,b,c,d,e,f,g}=7'b1111011; default : {a,b,c,d,e,f,g}=7'bx; endcase end endmodule 真值表 a e c d b f g bcd/7seg 1 2 4 8 D0 D1 D2 D3

11.12.1.6 运算电路 一、加法器: 逻辑图: 例:带进位的n位通用加法器 11.12.1.6 运算电路 一、加法器: 逻辑图: 例:带进位的n位通用加法器 module adder_n (cout, sum, ina,inb, cin); parameter n=16; output[n:1] sum; output cout; input[n:1] ina,inb; input cin; assign {cout,sum}=ina+inb+cin; endmodule ∑ n ci co cin cout ina inb sum

二、比较器 例:n位比较器 module compare_n (great, equal, Small,ina,inb); parameter n=16; output great, equal, Small; input[n:1] ina,inb; assign great=(ina>inb); assign equal=(ina==inb); assign Small=(ina<inb); endmodule comp n ina inb P Q P>Q P=Q P<Q great equa Small

module tri_inout(tri_inout,out,data,en,clk); input en,clk; 11.12.1.7、双向三态端口的描述 module tri_inout(tri_inout,out,data,en,clk); input en,clk; input [7:0] data; output[7:0] out; inout [7:0] tri_inout; wire [7:0] tri_inout; reg [7:0] out; assign tri_inout= en?data:8'bz; always @(posedge clk) out=tri_inout; endmodule

11.12.2 常用时序电路模块的设计 11.12.2.1 D触发器 C1 1D Q D CLK 1.最简单的D触发器 module DFF(Q , D , CLK); output Q; input D , CLK; reg Q; always@(posedge CLK) begin Q =D; end endmodule 不需要同步输入端D。与组合差别?

C1 1D R d clk reset q S set qn 2.带异步清0、异步置1的D触发器 module DFF1(q,qn,d,clk,set,reset); input d, clk, set, reset; output q, qn; reg q, qn; always @(posedge clk or negedge set or negedge reset) begin if (! reset) begin q =0; qn = 1; end //异步清0,低电平有效 else if (! set ) begin q=1; qn=0; end //异步置1,低电平有效 else begin q =d; qn = ~d; end end endmodule 不需要同步输入端D。与组合差别? 注意:与数字电路中的D有差别?set、reset可同时有效,但reset信号有优权。

3.带同步清0、同步置1的D触发器 C1 1D 1R d clk reset q 1S set qn module DFF2(q, qn, d, clk, set, reset); input d, clk, set, reset; output q, qn; reg q, qn; always @ (posedge clk) begin if(reset) begin q =0; qn =1; end //同步清0,高电平有效 else if (set) begin q =1;qn =0; end //同步置1,高电平有效 else begin q = d; qn = ~d; end end endmodule 注意:清0和置1,同步与异步差别?

11.12.2.2 数据锁存器(latch) C1 1D q d clk 1.电平敏感的一位数据锁存器(同步D) module latch_1(q, d, clk); output q; input d, clk; assign q =clk ? d : q; //时钟高电平时,将输入端数据锁存 endmodule q C1 1D 1R d clk reset 1S set 2.带置位和复位端的1位数据锁存器 module latch_2(q, d, clk, set, reset); output q; input d, clk, set, reset; assign q =reset ? 0 : (set ? 1 :(clk ? d : q) ); endmodule

3. 8位数据锁存器 module latch_8(qout, data, clk); output[7:0] qout; input[7:0] data; input clk; reg[7:0] qout; always @ (clk or data) begin if(clk) qout =data; end endmodule C1 1D qout data clk 8 clk高电平有效, 当clk=1时:输出、输入是透明。

11.12.2.3 数据寄存器 例. 8位数据寄存器 module reg8(out_data,in_data,clk,clr); 11.12.2.3 数据寄存器 例. 8位数据寄存器 module reg8(out_data,in_data,clk,clr); output[7:0] out_data; input clk,clr; input[7:0] in_data; reg[7:0] out_data; always @ (posedge clk or posedge clr) begin if(clr) out_data =0; else out_data = in_data; end endmodule C1 1D out_data in_data clk 8 clr R 数据锁存器与数据寄存器的差别? 电平触发 边沿触发

11.12.2.4 移位寄存器(单向) SRG8 1R C1/ 1D clr clk din dout1 dout8 11.12.2.4 移位寄存器(单向) SRG8 1R C1/ 1D clr clk din dout1 dout8 module shifter(din , clk , clr ,dout); parameter n=8; input din , clk , clr; output[8:1] dout ; reg[8:1] dout; always @(posedge clk) begin if (clr) dout = 0; // 同步清0,高电平有效 else dout = dout << 1;//输出信号左移一位 dout[1] = din; //输入信号补充到输出信号的最低位 end endmodule 注意:左移定义 Verilog HDL:低位移向高位 数字电路: 高位移向低位

一、可预置的n位二进制计数器(带异步清0) 11.12.2.5 计数器 一、可预置的n位二进制计数器(带异步清0) module counter_n (out, cout, data, load, cin ,clr, clk); parameter n=8; output [n:1] out; output cout; input load, cin, clr, clk; input [n:1] data; reg [n:1] out; always @(posedge clk or negedge clr) //异步清0 begin if(!clr) out=0; else if (load) out= data;//置数 else out = out + cin; //计数或保持 end assign cout=&out&cin; // 进位 endmodule CTR8 M1 M2 G3 C4/2,3+ 8 3CT=255 1,4D load cin clk data out cout clr R 计数器的位数

二、任意进制计数器(带异步清0) n:模;size:计数器位数 module n_counter (Q, CO, EN ,CLR, CLK); parameter n=30; parameter size=5; output [size:1] Q; output CO; input EN ,CLR, CLK; reg [size:1] Q; always @(posedge CLK or negedge CLR) //异步清0 begin if(!CLR) Q=0; else if(Q==(n-1)) Q=EN?0:Q; //计数或保持 else Q = Q + EN; //计数或保持 end assign CO=(Q==(n-1))&EN; // 进位 endmodule

三、可预置的加减计数器 例:11.12.20 module up_down_count(d,clk,clear,load,up_down,qd); parameter size=8; input[size:1] d; input clk,clear,load,up_down ; output[size:1] qd; reg[size:1] cnt; assign qd=cnt; always @(posedge clk) begin if(!clear) cnt=0;//低电平、同步复位 else if(load) cnt=d;//高电平、同步置数 else if(up_down) cnt=cnt+1;//加法计数 else cnt=cnt-1;//减法计数 end endmodule CTR8 M1 M2 M3(dn) C5/ 8 1,4D load up_down clk d qd clr M4(up) 1,4+;1,3- 5CT=0

四、控制器的设计实例 某控制器时序要求如下图: CLK2为系统时钟, 每当输入信号出CLK1从低电平变为高电平时启动一次工作,即输出如下图的RESET、OE、SEL三个信号

根据要求画出状态机图: Swait0 S0 Swait1 S1 reset=0 oe=0 sel=0 reset=1 oe=0 sel=sel+1 Swait1 S1 oe=1 clk1=0 clk1=1 clk=1 clk=0 Sel<7 sel=7

HDL代码: 注意:编码时将sel放在状态位中, f(clk2)>=10f(clk1) module fir_control (clk1,clk2,clrn,reset,oe,sel); input clk1,clk2,clrn; output [2:0] sel; output reset,oe; reg [1:0] state; reg [2:0] sel; reg reset,oe; parameter Swait0=2'b00, S0 =2'b01,S1 =2'b10, Swait1=2'b11;

default :begin state=Swait0;oe=0;sel=0;reset=0;end always @ (posedge clk2 or negedge clrn) if (!clrn) begin state = Swait0;oe=0;sel=0;reset=0;end else case (state) Swait0: if (!clk1) begin oe=0;sel=0;reset=0;end else begin state=S0;oe=0;reset=1;end S0: if (sel<7) begin sel=sel+1;reset=1;oe=0;end else begin state = S1;reset=1;oe=1;end S1: if (clk1) begin state=Swait1;oe=0 ; end else begin state = Swait0;oe=0;sel=0;reset=0;end Swait0: if (!clk1) begin state=Swait0;oe=0;sel=0;reset=0;end default :begin state=Swait0;oe=0;sel=0;reset=0;end endcase endmodule

课堂小结: Verilog HDL基础知识 概述 Verilog HDL的基本结构 数据类型及常量、变量 运算符 语句 语句的顺序执行与并行执行 课堂小结: Verilog HDL基础知识

课外作业: 上机调试