小舍YZ
发表于 2017-4-1 11:03:37
本帖最后由 小舍YZ 于 2017-4-5 12:04 编辑
第2章 Verilog HDL语言基础
本章主要介绍Verilog语言的基本语法和典型的应用实例。
第1节 Verilog HDL语言简介
Verilog HDL语言简介
Verilog HDL和VHDL是目前世界上最流行的两种硬件描述语言(HDL:Hardware Description Language),均为IEEE标准,被广泛地应用于基于可编程逻辑器件的项目开发。二者都是在20世纪80年代中期开发出来的,前者由Gateway Design Automation公司(该公司于1989年被Cadence公司收购)开发,后者由美国军方研发。
HDL语言以文本形式来描述数字系统硬件结构和行为,是一种用形式化方法来描述数字电路和系统的语言,可以从上层到下层来逐层描述自己的设计思想。即用一系列分层次的模块来表示复杂的数字系统,并逐层进行验证仿真,再把具体的模块组合由综合工具转化成门级网表,接下去再利用布局布线工具把网表转化为具体电路结构的实现。目前,这种自顶向下的方法已被广泛使用。概括地讲,HDL语言包含以下主要特征:
• HDL语言既包含一些高级程序设计语言的结构形式,同时也兼顾描述硬件线路连接的具体结构。
• 通过使用结构级行为描述,可以在不同的抽象层次描述设计。HDL语言采用自顶向下的数字电路设计方法,主要包括3个领域5个抽象层次。
• HDL语言是并行处理的,具有同一时刻执行多任务的能力。这和一般高级设计语言(例如C语言等)串行执行的特征是不同的。
• HDL语言具有时序的概念。一般的高级编程语言是没有时序概念的,但在硬件电路中从输入到输出总是有延时存在的,为了描述这一特征,需要引入时延的概念。HDL语言不仅可以描述硬件电路的功能,还可以描述电路的时序。
2.1.1 Verilog HDL语言的历史
1983年,Gateway Design Automation(GDA)硬件描述语言公司的Philip Moorby首创了Verilog HDL。后来Moorby成为Verilog HDL-XL的主要设计者和Cadence公司的第一合伙人。1984至1986年,Moorby设计出第一个关于Verilog HDL的仿真器,并提出了用于快速门级仿真的XL算法,使Verilog HDL语言得到迅速发展。1987年Synonsys公司开始使用Verilog HDL行为语言作为综合工具的输入。1989年Cadence公司收购了Gateway公司,Verilog HDL成为Cadence公司的私有财产。1990年初,Cadence公司把Verilog HDL和Verilog HDL-XL分开,并公开发布了Verilog HDL。随后成立的OVI(Open Verilog HDL International)组织负责Verilog HDL的发展并制定有关标准,OVI由Verilog HDL的使用者和CAE供应商组成。1993年,几乎所有ASIC厂商都开始支持Verilog HDL,并且认为Verilog HDL-XL是最好的仿真器。同时,OVI推出2.0版本的Verilong HDL规范,IEEE则将OVI的Verilog HDL2.0作为IEEE标准的提案。1995年12月,IEEE制定了Verilog HDL的标准IEEE1364-1995。目前,最新的Verilog语言版本是2000年IEEE公布的Verilog 2001标准,其大幅度地提高了系统级和可综合性能。
2.1.2 Verilog HDL的主要能力
Verilog HDL既是一种行为描述语言,也是一种结构描述语言。如果按照一定的规则和风格编写代码,就可以将功能行为模块通过工具自动转化为门级互连的结构模块。这意味着利用Verilog语言所提供的功能,就可以构造一个模块间的清晰结构来描述复杂的大型设计,并对所需的逻辑电路进行严格的设计。
下面列出的是Verilog语言的主要功能:
• 可描述顺序执行或并行执行的程序结构;
• 用延迟表示式或事件表达式来明确地控制过程的启动时间;
• 通过命名的事件来触发其他过程里的激活行为或停止行为;
• 提供了条件和循环等程序结构;
• 提供了可带参数且非零延续时间的任务程序结构;
• 提供了可定义新的操作符的函数结构;
• 提供了用于建立表达式的算术运算符、逻辑运算符和位运算符;
• 提供了一套完整的表示组合逻辑基本元件的原语;
• 提供了双向通路和电阻器件的描述;
• 可建立MOS器件的电荷分享和衰减模型;
• 可以通过构造性语句精确地建立信号模型;
表2-1给出Verilog HDL的表述能力。
表2-1 Verilog HDL语言能力总结
zxopen08
发表于 2017-4-5 11:14:27
FPGA开发 实用内容
小舍YZ
发表于 2017-4-5 12:04:52
此外,Verilog HDL语言还有一个重要特征就是:和C语言风格有很多的相似之处,学习起来比较容易。
小舍YZ
发表于 2017-4-5 12:05:37
2.1.3 Verilog HDL和VHDL的区别
Verilog HDL和VHDL都是用于逻辑设计的硬件描述语言。VHDL在1987年成为IEEE标准,Verilog HDL则在1995年才成为IEEE标准,这是因为前者是美国军方组织开发的,而后者则是从民间公司转化而来,要成为国际标准就必须放弃专利。相比而言,Verilog HDL具有更强的生命力。
Verilog HDL和VHDL的相同点在于:都能形式化地抽象表示电路的行为和结构;支持逻辑设计中层次与范围的描述;可以简化电路行为的描述;具有电路仿真和验证机制;支持电路描述由高层到低层的综合转换;与实现工艺无关;便于管理和设计重用。
但Verilog HDL和VHDL又有各自的特点,由于Verilog HDL推出较早,因而拥有更广泛的客户群体、更丰富的资源。Verilog HDL还有一个优点就是容易掌握,如果具有C语言学习的基础,很快就能够掌握。而VHDL需要Ada编程语言基础,一般需要半年以上的专业培训才能够掌握。传统观点认为Verilog HDL在系统级抽象方面较弱,不太适合特大型的系统。但经过Verilog 2001标准的补充之后,系统级表述性能和可综合性能有了大幅度提高。当然,这两种语言也仍处于不断完善的过程中,都在朝着更高级描述语言的方向前进。
小舍YZ
发表于 2017-4-5 12:05:54
2.1.4 Verilog HDL设计方法
1. 自下而上的设计方法
自下而上的设计是传统的设计方法,是从基本单元出发,对设计进行逐层划分的过程。这种设计方法与用电子元件在模拟实现板上建立一个系统的步骤有密切的关系。优、缺点分别如下:
• 优点
设计人员对这种设计方法比较熟悉;实现各个子模块所需的时间较短。
• 缺点
对系统的整体功能把握不足;由于必须先对多个子模块进行设计,因此实现整个系统的功能所需的时间长;另外,对设计人员之间相互协作也有较高的要求。
2.自上而下的设计方法
自上而下的设计是从系统级开始,把系统划分为基本单元,然后再把基本单元划分为下一层次的基本单元,直到可用EDA元件实现为止。这种方法的优、缺点如下。
• 优点
在设计周期开始就做好了系统分析;由于设计的主要仿真和调试过程是在高层完成的,所以能够早期发现结构设计上的错误,避免了设计工作的浪费,方便了系统的划分和整个项目的管理,可减少设计人员劳动,避免了重复设计。
• 缺点
得到的最小单元不标准,且制造成本高。
3.混合的设计方法
复杂数字逻辑电路和系统设计过程,通常是以上两种设计方法的结合。设计时需要考虑多个目标的综合平衡。在高层系统用自上而下的设计方法实现,而使用自下而上的方法从库元件或以往设计库中调用已有的设计单元。混合设计方法兼有以上两种方法的优点,并且可使用先进的矢量测试方法。
小舍YZ
发表于 2017-4-5 12:06:53
第2节 Verilog HDL基本程序结构
Verilog HDL基本程序结构
用Verilog HDL描述的电路设计就是该电路的Verilog HDL模型,也称为模块,是Verilog的基本描述单位。模块描述某个设计的功能或结构以及与其他模块通信的外部接口,一般来说一个文件就是一个模块,但并不绝对如此。模块是并行运行的,通常需要一个高层模块通过调用其他模块的实例来定义一个封闭的系统,包括测试数据和硬件描述。一个模块的基本架构如下:
module module_name (port_list)
//声明各种变量、信号
reg //寄存器
wire//线网
parameter//参数
input//输入信号
output/输出信号
inout//输入输出信号
function//函数
task//任务
……
//程序代码
initial assignment
always assignment
module assignment
gate assignment
UDP assignment
continous assignment
endmodule
说明部分用于定义不同的项,例如模块描述中使用的寄存器和参数。语句用于定义设计的功能和结构。说明部分可以分散于模块的任何地方,但是变量、寄存器、线网和参数等的说明必须在使用前出现。一般的模块结构如下:
module <模块名> (<端口列表>)
<定义>
<模块条目>
endmodule
其中,<定义>用来指定数据对象为寄存器型、存储器型、线型以及过程块。<模块条目>可以是initial结构、always结构、连续赋值或模块实例。
下面给出一个简单的Verilog模块,实现了一个二选一选择器。
小舍YZ
发表于 2017-4-5 12:07:43
例2-1 二选一选择器(见图2-1)的Verilog实现
图2-1 例2-1所示的二选一电路
小舍YZ
发表于 2017-4-5 12:07:57
module muxtwo(out, a, b, s1);
input a, b, s1;
output out;
reg out;
always @ (s1 or a or b)
if (!s1) out = a;
else out = b;
endmodule
模块的名字是muxtwo,模块有4个端口:三个输入端口a、b和s1,一个输出端口out。由于没有定义端口的位数,所有端口大小都默认为1位;由于没有定义端口a, b, s1的数据类型,这3个端口都默认为线网型数据类型。输出端口out定义为reg类型。如果没有明确的说明,则端口都是线网型的,且输入端口只能是线网型的。
小舍YZ
发表于 2017-4-5 12:09:25
第3节 VerilogHDL语言的数据类型和运算符
2.3.1 标志符
标志符可以是一组字母、数字、_下划线和$符号的组合,且标志符的第一个字符必须是字母或者下划线。另外,标志符是区别大小写的。下面给出标志符的几个例子:
Clk_100MHz
diag_state
_ce
P_o1_02
需要注意的是,Verilog HDL定义了一系列保留字,叫作关键字,具体资料可查阅相关标准。只有小写的关键字才是保留字,因此在实际开发中,建议将不确定是否是保留字的标志符首字母大写。例如:标志符if(关键字)与标志符IF是不同的。
2.3.2 数据类型
数据类型用来表示数字电路硬件中的数据存储和传送元素。Verilog HDL中总共有19种数据类型,本书只介绍4个常用的数据类型:wire型、reg型、memory型和parameter型,其他类型将在后续章节中逐步介绍。
1.wire型
wire型数据常用来表示以assign关键字指定的组合逻辑信号。Verilog程序模块中输入、输出信号类型默认为wire型。wire型信号可以用做方程式的输入,也可以用做“assign”语句或者实例元件的输出。
wire型信号的定义格式如下:
wire 数据名1,数据名2,……数据名N;
这里,总共定义了N条线,每条线的位宽为n。下面给出几个例子:
wire a, b, c; // a, b, c都是位宽为10的wire型信号
wire d;
2.reg型
reg是寄存器数据类型的关键字。寄存器是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值,其作用相当于改变触发器存储器的值。reg型数据常用来表示always模块内的指定信号,代表触发器。通常在设计中要由always模块通过使用行为描述语句来表达逻辑关系。在always块内被赋值的每一个信号都必须定义为reg型,即赋值操作符的右端变量必须是reg型。
reg型信号的定义格式如下:
reg 数据名1,数据名2,……数据名N;
这里,总共定义了N个寄存器变量,每条线的位宽为n。下面给出几个例子:
reg a, b, c; // a, b, c都是位宽为10的寄存器
reg d;
reg型数据的缺省值是未知的。reg型数据可以为正值或负值。但当一个reg型数据是一个表达式中的操作数时,它的值被当作无符号值,即正值。如果一个4位的reg型数据被写入-1,在表达式中运算时,其值被认为是+15。
reg型和wire型的区别在于:reg型保持最后一次的赋值,而wire型则需要持续的驱动。
3.memory型
Verilog通过对reg型变量建立数组来对存储器建模,可以描述RAM、ROM存储器和寄存器数组。数组中的每一个单元通过一个整数索引进行寻址。memory型通过扩展reg 型数据的地址范围来达到二维数组的效果,其定义的格式如下:
reg 存储器名 ;
其中,reg 定义了存储器中每一个存储单元的大小,即该存储器单元是一个n位位宽的寄存器;存储器后面的则定义了存储器的大小,即该存储器中有多少个这样的寄存器。例如:
reg ROMA ;
这个例子定义了一个存储位宽为16位,存储深度为8的一个存储器。该存储器的地址范围是0到8。
需要注意的是:对存储器进行地址索引的表达式必须是常数表达式。
尽管memory型和reg型数据的定义比较接近,但二者还是有很大区别的。例如,一个由n个1位寄存器构成的存储器是不同于一个n位寄存器的。
reg rega; // 一个n位的寄存器
reg memb ; // 一个由n个1位寄存器构成的存储器组
一个n位的寄存器可以在一条赋值语句中直接进行赋值,而一个完整的存储器则不行。
rega = 0; // 合法赋值
memb = 0; // 非法赋值
如果要对memory型存储单元进行读写必须要指定地址。例如:
memb = 1; // 将memeb中的第0个单元赋值为1。
reg Xrom ;
Xrom = 4’h0;
Xrom = 4’ha;
Xrom = 4’h9;
Xrom = 4’hf;
4.parameter型
在Verilog HDL中用parameter来定义常量,即用parameter来定义一个标志符表示一个常数。采用该类型可以提高程序的可读性和可维护性。
parameter型信号的定义格式如下:
parameter 参数名1 = 数据名1;
下面给出几个例子:
parameter s1 = 1;
parameter S0=4'h0,
S1=4'h1,
S2=4'h2,
S3=4'h3,
S4=4'h4;
小舍YZ
发表于 2017-4-5 12:10:13
2.3.3 模块端口
模块端口是指模块与外界交互信息的接口,包括3种类型:
• input: 模块从外界读取数据的接口,在模块内不可写。
• output:模块往外界送出数据的接口,在模块内不可读。
• inout:可读取数据也可以送出数据,数据可双向流动。
2.3.4 常量集合
Verilog HDL有下列4种基本的数值:
0:逻辑0或“假”
1:逻辑1或“真”
x:未知
z:高阻
其中x、z是不区分大小写的。Verilog HDL中的数字由这四类基本数值表示。
Verilog HDL中的常量分为3类:整数型、实数型以及字符串型。下划线符号“_”可以随意用在整数和实数中,没有实际意义,只是为了提高可读性。例如:56等效于5_6。
1.整数
整数型可以按如下两种方式书写:简单的十进制数格式以及基数格式。
(1)简单的十进制格式
简单的十进制数格式的整数定义为带有一个“+”或“-”操作符的数字序列。下面是这种简易十进制形式整数的例子。
45 十进制数45
-46 十进制数-46
简单的十进制数格式的整数值代表一个有符号的数,其中负数可使用两种补码形式表示。例如,32在6位二进制形式中表示为100000,在7位二进制形式中为0100000,这里最高位0表示符号位;-15在5位二进制中的形式为10001,最高位1表示符号位,在6位二进制中为110001,最高位1为符号扩展位。
(2)基数表示格式
基数格式的整数格式为:
[长度] '基数 数值
长度是常量的位长,基数可以是二进制、十进制、十六进制之一。数值是基于基数的数字序列,且数值不能为负数。下面是一些具体实例:
6'b9 6位二进制数
5'o9 5位八进制数
9'd6 9位十进制数
2.实数
实数可以用下列两种形式定义:
(1)十进制计数法,例如:
2.0
16539.236
(2)科学计数法
这种形式的实数举例如下,其中e与E相同。
235.12e2 其值为23512
5e-4 其值为0.0005
根据Verilog语言的定义,实数通过四舍五入隐式地转换为最相近的整数。
3.字符串
字符串是双引号内的字符序列。字符串不能分成多行书写。例如:
“counter”
用8位ASCII值表示的字符可看作是无符号整数,因此字符串是8位ASCII值的序列。为存储字符串“counter”,变量需要 位。
reg Char;
Char = ''counter'';
页:
1
2
3
4
[5]
6
7
8
9
10
11
12