Verilog HDL 语法学习笔记

您所在的位置:网站首页 verilog基本逻辑值 Verilog HDL 语法学习笔记

Verilog HDL 语法学习笔记

2024-07-03 15:00:52| 来源: 网络整理| 查看: 265

Verilog HDL 语法学习笔记

今天给大侠带来Verilog HDL 语法学习笔记,话不多说,上货。

关于详细的VHDL语法以及Verilog HDL语法可参见往期文章。

一、Verilog HDL 简介1.1 Verilog HDL 的历史

Verilog HDL 语 言 最 初 是 作为 Gateway Design Automation 公 司 ( Gateway DesignAutomation 公司后来被著名的 Cadence Design Systems 公司收购)模拟器产品开发的硬件建模语言。

开始 Verilog HDL 只是一种专用语言,随着 Gateway Design Automation 公司模拟、仿真器产品的广泛使用,Verilog HDL 便于使用、实用的语言逐渐为众多设计者所接受。1995年 Verilog HDL 正式成为 IEEE 标准,称为 IEEE Std 1364-1995。

1.2 Verilog HDL 的特点

Verilog HDL 语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。使用这种语言编写的模型可以方便地使用 Verilog 仿真器进行验证。Verilog HDL 从 C 语言中继承了多种操作符和结构。Verilog HDL 提供了扩展的建模能力和扩展模块。Verilog HDL 语言的核心子集非常易于学习和使用,这对大多数建模应用来说已经足够。

Verilog HDL 之所以成为和 VHDL 并驾齐驱的硬件描述语言,是因为它具有如下特点:

• 基本逻辑门和开关级基本结构模型都内置在语言中; • 可采用多种方式对设计建模,这些方式包括行为描述方式、数据流方式、结构化方式; • Verilog HDL 中有线网(Wire)数据类型和寄存器(Reg)数据类型两类数据类型,线网类型表示构件间的物理连线,而寄存器类型表示抽象的数据存储元件; • 能够描述层次设计,可使用模块实例结构描述任何层次; • 设计的规模可以是任意的,语言不对设计的规模大小施加任何限制; • Verilog HDL 不再是某些公司的专有语言而是 IEEE 标准; • Verilog HDL 语言的描述能力能够通过使用编程语言接口(Programme LanguageInterface,简称 PLI)机制进一步扩展,PLI 允许外部函数访问 Verilog 模块内信息、允许设计者与模拟器交互的例程集合; • 设计能够在多个层次上加以描述,从开关级、门级、寄存器传送级(RT L)到算法级,包括进程和队列级; • Verilog HDL 能够监控模拟验证的执行,即模拟验证执行过程中设计的值能够被监控和显示,这些值也能够用于与期望值比较,在不匹配的情况下打印报告消息。

二、Verilog HDL 程序基本结构

模块是 Verilog 的基本描述单位,描述某个设计的功能或结构及其与其他模块通信的外部端口。一个模块的基本语法如下:

module module_name//模块名称 (port_list);//输入输出信号列表 //说明 reg //寄存器 wire//线网 parameter//参数 input//输入信号 output//输出信号 inout//输入输出信号 function//函数 task//任务 . . .//语句 Initial statement Always statement Module instantiation// Gate instantiation// UDP instantiation// Continuous assignment// endmodule

说明部分用于定义不同的项,例如模块描述中使用的寄存器和参数、语句定义设计的功能和结构。说明部分和语句可以放置在模块中的任何地方,但是变量、寄存器、线网和参数等的说明部分必须在使用前出现。为了使模块描述清晰和具有良好的可读性, 最好将所有的说明部分放在语句前。

图1所示的是一个半加器。

这个半加器用 Verilog HDL 实现,代码如下:

module HalfAdder(A,B,Sum,Carry) ; input A,B; output Sum, Carry; assign #2 Sum = A ^ B; assign #5 Carry = A & B; endmodule

模块的名字是 HalfAdder。模块有 4 个端口:两个输入端口 A 和 B,两个输出端口 Sum 和Carry。由于没有定义端口的位数,所有端口大小都为 1 位;同时由于没有各端口的数据类型说明,这 4 个端口都是线网数据类型。模块包含两条描述半加器数据流行为的连续赋值语句。从这种意义上讲,这些语句在模块中出现的顺序无关紧要,因为这些语句是并发的。每条语句的执行顺序依赖于发生在变量 A 和 B 上的事件。

三、Verilog HDL 语言的数据类型和运算符

本篇介绍 Verilog HDL 语言的基本要素,包括标识符、注释、数值、编译程序指令、系统任务和系统函数、两种主要的数据类型。

3.1 标识符

Verilog HDL 中的标识符可以是任意一组字母、数字、$符号和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。以下是标识符的几个例子:

Piero PIERO / /与 Piero 不同。 _a1_b2 c00_68 ABC$ 3.2 数据类型

Verilog HDL 有两大类数据类型:

线网类型,表示 Verilog HDL 结构化元件间的物理连线,它的值由驱动元件的值决定,例如连续赋值或门的输出,线网的缺省值为 z(高阻态);寄存器类型,表示一个抽象的数据存储单元,它只能在 always 语句和 initial 语句中被赋值,并且它的值被保存下来,缺省值为 x(未知状态)。1)线网类型

线网数据类型包含下述不同种类的线网子类型:wire、tri、wor、trior、wand、triand、trireg、tri1、tri0、supply0、supply1。简单的线网类型说明语法为:

net_kind [msb:lsb] net1, net2, . . . , netN;

net_kind 是上述线网类型的一种。msb 和 lsb 是用于定义线网范围的常量表达式,范围定义是可选的;如果没有定义范围,缺省的线网类型为 1 位。下面是一个线网类型说明实例。

wire Rdy, Start; //2 个 1 位的连线。 wand [2:0] Addr; //Addr 是 3 位线与。 2)寄存器类型

有 5 种不同的寄存器类型:reg、integer、time、real 和 realtime。寄存器数据类型 reg是最常见的数据类型。reg 类型使用保留字 reg 加以说明,形式如下:

reg [msb: lsb] reg1, reg2, . . . regN;

msb 和 lsb 定义了范围,并且均为常数值表达式。范围定义是可选的,如果没有定义范围,缺省值为 1 位寄存器。例如:

reg [3:0] Sat; //Sat 为 4 位寄存器。 reg Cnt; //1 位寄存器。 reg [1:32] Kisp, Pisp, Lisp; 3.3 模块端口

模块端口是指模块与外界交流信息的接口,包括 3 种:

in:模块通过这个接口从外界环境读取数据,是不可写的;out:模块通过这个接口向外界环境输出数据,是不可读的;inout:模块可以通过这个接口从外界环境读取并输出数据,数据可以双向流通。3.4 值集合

Verilog HDL 有下列 4 种基本的值:

0:逻辑 0 或“假”;1:逻辑 1 或“真”;x:未知;z:高阻。

这4种值的解释都内置于语言中。如一个为 z 的值总是意味着高阻抗,一个为 0 的值通常是指逻辑 0。在门的输入或一个表达式中的为“z”的值通常解释成“x”。此外,x 值和 z 值都是不分大小写的。也就是说,值 0x1z 与值 0X1Z 相同。Verilog HDL 中的常量是由以上这四类基本值组成的。

Verilog HDL 中有 3 类常量:整型、实数型和字符串型。下划线符号(_)可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提高易读性;惟一的限制是下划线符号不能用作为首字符。

1)整型数

整型数可以按如下两种方式书写:简单的十进制数格式和基数格式。

简单的十进制形式的整数定义为带有一个可选的“+”(一元)或“-”(一元)操作符的数字序列。下面是这种简易十进制形式整数的例子:

32;// 十进制数 32 -15;// 十进制数-15

基数格式的格式为:

[size ] 'base value

size 定义以位计的常量的位长,base 为 o 或 O(表示八进制)、b 或 B(表示二进制)、d或 D(表示十进制)、h 或 H(表示十六进制),value 是基于 base 的值的数字序列。值 x 和 z以及十六进制中的 a 到 f 不区分大小写。下面是一些具体实例:

5'O37;// 5 位八进制数 4'D2;//4 位十进制数 4'B1x_01;// 4 位二进制数 7'Hx ;//7 位 x(扩展的 x),即 xxxxxxx 4'hZ;// 4 位 z(扩展的 z) , 即 zzzz 4'd-4;//非法,数值不能为负 8'h 2 A;//在位长和字符之间,以及基数和数值之间允许出现空格 3' b001;//非法: `和基数 b 之间不允许出现空格 (2+3)'b10;// 非法:位长不能够为表达式 2)实数

实数可以用下列两种形式定义:

十进制计数法,例如 2.0、5.678、1、1572.12;科学计数法,例如 23_5.1e2(其值为 23510.0,忽略下划线)、3.6E2(360.0)。3)字符串

字符串是双引号内的字符序列。字符串不能分成多行书写,例如:

"INTERNAL ERROR" " REACHED->HERE "

用 8 位 ASCII 值表示的字符可看作是无符号整数。因此字符串是 8 位 ASCII 值的序列。为存储字符串“INTERNAL ERROR”,变量需要 8 * 1 4 位。

reg [1 : 8*14] Message; . . . Message = "INTERNAL ERROR"

反斜线(\)用于对确定的特殊字符转义。

\n 换行符 \t 制表符 \\ 字符\本身 \" 字符" \206 八进制数 2 0 6 对应的字符 3.5 表达式

表达式是 Verilog HDL 语言中进行逻辑运算和表达最基本的元素。表达式由操作符和操作数按照一定的规则组合而成,下面进行详细介绍。

1)操作数

操作数的类型包括:常量、参数、线网、寄存器、存储器单元和函数调用等。

常量的使用规则在3.4 中进行说明,下面是一些实例:

256,7 //非定长的十进制数 4'b10_11, 8'h0A // 定长的整型常量 'b1, 'hFBA // 非定长的整数常量 90.00006 // 实数型常量 "BOND" // 串常量;每个字符作为 8 位 ASCII 值存储

表达式中的整数值可被解释为有符号数或无符号数。参数类似于常量,并且使用参数声明进行说明。下面是参数说明实例:

parameterLOAD = 4'd12, STORE = 4'd10;

LOAD 和 STORE 为参数的例子,值分别被声明为 12 和 10。

线网在表达式中可以分别按照标量和向量两种方式使用,下面是线网说明实例:

wire [0:3] Prt; //Prt 为 4 位向量线网 wire Bdq; //Bbq 是标量线网

线网中的值被解释为无符号数。例如在连续赋值语句中:

assign Prt = -3;

Prt 被赋于位向量 1101,实际上为十进制的 13,例如在下面的连续赋值中:

assign Prt = 4'HA;

Prt 被赋于位向量 1010,即为十进制的 10。

寄存器也是可以按照标量和向量两种方式使用。寄存器变量使用寄存器声明进行说明,例如:

integer TemA, TemB; reg [1:5] State; time Que [ 1:5 ] ;

整型寄存器中的值被解释为有符号的二进制补码数,而 reg 寄存器或时间寄存器中的值被解释为无符号数,实数和实数时间类型寄存器中的值被解释为有符号浮点数。例如下面的寄存器代码:

TemA = -10; //TemA 值为位向量 10110,是 10 的二进制补码 TemA = 'b1011; //TemA 值为十进制数 11 State = -10; //State 值为位向量 10110,即十进制数 22 State = 'b1011; // State 值为位向量 01011,是十进制值 11

在 Verilog HDL 语言中,对于向量形式的线网和寄存器,都可以采用部分选择的方式使用向量中需要的部分。在部分选择中,向量的连续序列被选择,形式如下:

net_or_reg_vector [msb_const_expr:1sb_const_expr]//部分选择的语法形式 State [1:4] //寄存器部分选择 Prt [1:3] // 线网部分选择

存储器单元的定义形式如下:

memory [word_address] //定义形式 reg [1:8] Ack, Dram [ 0 : 6 3 ] ;//例子 . . . Ack = Dram [60]; //存储器的第 6 0 个单元

不允许对存储器变量值部分选择或位选择。例如:

Dram [60] [2] //使用错误 Dram [60] [2:4]//使用错误

在存储器中读取一个位或部分选择一个字的方法如下:将存储器单元赋值给寄存器变量,然后对该寄存器变量采用部分选择或位选择操作。

2)操作符

Verilog HDL语言中的操作符包括:

算术操作符 +(加法)、-(减法)、×(乘法)、÷(除法)和%(取模)。关系操作符 >(大于)、

多路选择电路如果用结构化建模方式实现,代码如下:

module MUX4x1 (Z , D0 , D1 , D2 , D3 , S0 , S1) ; input D0 , D1 , D2 , D3 , S0 , S1; output Z; and (T0 , D0 , S01 , S11) , (T1 , D1 , S01, S1) , (T2 , D2 , S0 , S11) , (T3 , D3 , S0 , S1) , not (S01, S0) , (S11 , S1) ; or (Z , T0 , T1 , T2 , T3) ; endmodule 4.2 数据流建模方式

Verilog HDL 中的数据流建模方式一般用连续赋值语句来实现。Verilog HDL 中有两种形式的赋值方式:连续赋值和过程赋值。其中过程赋值用于顺序行为建模,而组合逻辑电路的行为最好使用连续赋值语句建模。

连续赋值语句将值赋给线网(连续赋值不能为寄存器赋值),它的格式如下:

assign LHS_target = RHS_expression;//定义格式 //例子 wire [3:0] Z, Preset, Clear; //线网说明 assign Z = Preset & Clear; //连续赋值语句

连续赋值的目标为 Z,表达式右端为“Preset & Clear”,连续赋值语句中的关键词为assign。只要在右端表达式的操作数上有事件(事件为值的变化)发生时,连续赋值语句即被计算,如果结果值有变化,新结果就赋给左边的线网。在上面的例子中,如果 Preset 或 Clear变化,就计算右边的整个表达式。如果结果变化,那么结果即赋值到线网 Z。

如图3所示的是主从触发器。

主从触发器用连续赋值语句实现的代码如下:

module MSDFF_DF (D, C, Q, Qbar) ; input D, C; output Q, Qbar; wire NotC, NotD, NotY, Y, D1, D2, Ybar, Y1, Y2 ; assign NotD = ~ D; assign NotC = ~ C; assign NotY = ~ Y; assign D1 = ~ (D & C) ; assign D2 = ~ (C & NotD) ; assign Y = ~ (D1 & Ybar ) ; assign Ybar = ~ (Y & D2) ; assign Y1 = ~ (Y & NotC ) ; assign Y2 = ~ (NotY & NotC) ; assign Q = ~ (Qbar & Y1) ; assign Qbar = ~ (Y2 & Q) ; endmodule 4.3 行为建模方式

行为建模方式是用过程赋值语句来实现的。下面对行为建模方式的各个部分进行详细介绍。

1)过程结构

Verilog HDL 中的主要行为通过两种语句来控制进行:

initial 语句。always 语句。

initial 语句在模拟开始时执行,即在 0 时刻开始执行。initial 语句只执行一次,它的语法如下:

initial [timing_control] procedural_statement

这里的时序控制可以是延时控制,即等待一个确定的时间;或事件控制,即等待确定的事件发生或某一特定的条件为真。initial 语句的各个进程语句仅执行一次。initial 语句根据进程语句中出现的时间控制在以后的某个时间完成执行。下面是一个 initial 语句实例:

parameter SIZE = 1024; reg [7:0] RAM [ 0:SIZE- 1 ] ; reg RibReg; initial begin: SEQ_BLK_A integer Index; RibReg = 0; for (Index = 0; Index < SIZE; Index = Index + 1) RAM[Index] = 0; End

与 initial 语句相反,always 语句可重复执行。与 initial 语句类似,always 语句语法如下:

always [timing_control]procedural_statement

下面是一个 always 语句的实例。

reg [0:5] InstrReg; reg [3:0] Accum; wire ExecuteCycle; always@ (EcecuteCycle) //发生在某个时钟沿 begin case(InstrReg[ 0 : 1 ] )//多路条件分支 2'b00: Store (Accum, InstrReg[2:5]) ;//存储 2'b11: Load (Accum, InstrReg[2:5]) ;//读取 2'b01: Jump (InstrReg[ 2 : 5 ] ) ;//跳转 2'b10: ; endcase end 2)时序控制

Verilog HDL 中进行时序控制分别通过下面两种方式进行:

延时控制;事件控制。

延时控制的语法如下:

#delay procedural_statement

延时控制定义为执行过程中首次遇到该语句与该语句的执行的时间间隔。延时控制表示在语句执行前的“等待时延”。下面是一个延时控制的例子:

initial begin #3 Wave = 'b0111;//3 个时间单位后执行 #6 Wave = 'b1100; //6 个时间单位后执行 #7 Wave = 'b0000; //7 个时间单位后执行 end

事件控制有两种方式:边沿触发事件控制和电平敏感事件控制。边沿触发事件是指指定信号的边沿发生跳变时发生指定的行为,下面是边沿触发事件控制的语法和实例:

@ event procedural_statement //实例 time RiseEdge, OnDelay; initial begin //等待,直到在时钟上发生正边沿: @ (posedge ClockA) ; RiseEdge = $time; //等待,直到在时钟上发生负边沿: @ (negedge ClockA) ; OnDelay = $time - RiseEdge; $display ("The on-period of clock is %t.", Delay) ; end

在电平敏感事件控制中,进程语句或进程中的过程语句一直延迟到条件变为真后才执行。下面是电平敏感事件控制的语法和实例:

wait (Condition) procedural_statement //实例 wait (Sum > 22) //直到 Sum 大于 22 时发生 Sum = 0; wait (DataReady) //直到 DataReady 为高时发生 Data = Bus; wait (Preset) ; //直到 Preset 为高时才能执行后面的语句 3)语句块

Verilog HDL 在执行语句时分为顺序和并行两种方式。在顺序语句块中,语句按给定次序顺序执行;在并行语句块中,语句并行执行。

顺序语句块的语法和实例如下:

begin [:block_id{declarations} ] procedural_statement(s) end //实例 //产生波形 begin #2 Stream = 1; #5 Stream = 0; #3 Stream = 1; #4 Stream = 0; #2 Stream = 1; #5 Stream = 0; end

并行语句块的语法和实例如下:

fork [:block_id{declarations} ] procedural_statement(s) ; join //实例 //生成波形,生成的波形和前面使用顺序语句块的例子一样 fork #2 Stream = 1; #7 Stream = 0; #10 Stream = 1; #14 Stream = 0; #16 Stream = 1; #21 Stream = 0; join 4)过程性赋值

过程性赋值是在 initial 语句或 always 语句内的赋值,它只能对寄存器数据类型的变量赋值。过程性赋值如下两类:

阻塞性过程赋值:赋值在其后所有语句执行前执行,即在下一语句执行前该赋值语句完成执行;非阻塞性过程赋值:对目标的赋值是非阻塞的(因为时延),但可预定在将来某个时间发生。

阻塞性过程赋值用操作符“=”完成,例如下面的实例:

always @ (A or B or Cin) begin: CARRY_OUT reg T1,T2 , T3; T1 = A & B; T2 = B & Ci n; T3 = A & Ci n; Cout = T1|T2|T3; end

T1 赋值首先发生,计算 T1;接着执行第二条语句,T2 被赋值;然后执行第三条语句, T3被赋值,依此类推直到最后。

非阻塞性过程赋值用操作符“



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭