Verilog HDL常用基本语法.docx
- 文档编号:6701835
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:18
- 大小:2.67MB
Verilog HDL常用基本语法.docx
《Verilog HDL常用基本语法.docx》由会员分享,可在线阅读,更多相关《Verilog HDL常用基本语法.docx(18页珍藏版)》请在冰点文库上搜索。
VerilogHDL常用基本语法
VerilogHDL常用基本语法V1.0
1.前言
VerilogHDL语法较多,但是常用的语法较少,本文总结使用较为频繁的VerilogHDL语法,帮助初学者入门。
由于整理时间仓促以及作者能力有限,文中难免有纰漏之处或者不严谨的内容,请大家批评指正。
2.VerilogHDL基本结构
我们首先看下面的代码:
moduleAND4(a,b,out);
output[3:
0]out;//4位输出
input[3:
0]a,b;//4位输入a和b
assignout=a&b;//按位与运算
endmodule
这段代码中定义了一个模块AND4,由模块的声明开始,最开始的关键词是module,这个模块的名字叫AND4,这个模块的最后是endmodule
我们还可以使用另外一种写法,直接在参数列表里面将参数名列出:
moduleAND4(input[3:
0]a,input[3:
0]b,outputout);
assignout=a&b;
endmodule
通过RTL分析,得到以下结果
下面我们看一个分频模块
moduleFenPin(inputclk_in,outputclk_out);
regc_out=0;
assignclk_out=c_out;
always@(posedgeclk_in)
begin
c_out=~c_out;//取反
end
endmodule
其中,posedge表示上升沿,clk_in表示时钟,绿色部分是always块,一般用来描述时序逻辑电路。
RTL分析结果如下:
图中D触发器处于上升沿触发,c_out的初始值为0,每经过时钟clk_in的上升沿翻转一次,其仿真结果如下:
经过上面的分析,我们可以总结出VerilogHDL的基本结构
1.VerilogHDL程序由模块构成,每个模块在module和endmodule声明语句中
2.每个VerilogHDL源文件中只有一个顶层模块,其他为子模块。
可以每一个模块写一个文件
3.每个模块中要对端口定义,并说明输入输出端口,然后对模块的功能进行逻辑描述。
4.模块中的时序逻辑部分在always块的内部,在always块中只能对寄存器变量赋值。
5.模块中对端口或其他wire型变量的赋值,必须在always块的外部使用assign语句,通常是将寄存器的值送出。
6.程序书写格式自由,一行可以写几个语句,一个语句也可以分多行写。
7.除了endmodule语句、begin_end语句和fork_join语句外,每个语句和数据定义的最后必须有分号。
8.可用/*…*/和//…对程序的任何部分作注释。
加上必要的注释,可以增强程序的可读性和可维护性
2.数据类型及变量、常量
1.逻辑值
2.数值表达方式
3.线网(net)型变量
线网(net)型变量最常用的就是wire。
可以将wire直接的理解为连线。
例如一个D触发器reg1的输出是Q,这个Q连接到端口out1上,那么out1的值始终跟随着reg1的值的变化而变化。
例如:
wireclk_out;
assignclk_out=c_out;
例:
wire[7:
0]a,b,c;//a,b,c都是位宽为8位的wire
wired;//d是1位的wire
4.寄存器(reg)型变量
reg型也称为寄存器型。
数字电路中的触发器只在时钟有效边沿到来的时候,保存的值才能够发生改变。
例:
wireclk_out;
regc_out;
assignclk_out=c_out;
always@(posedgeclk_in)
begin
c_out=~c_out;
end
5.常量
如果用关键词parameter来定义一个标识符,代表一个常量,这个常量就被称为符号常量。
例如:
parameterwidth=3;//符号常量width的值是3,如果未进行重新定义,当在程序中出现width时就用3代替。
parameteridle=1,one=2,two=3,stop=4;//定义了4个符号常量。
如果未进行重新定义,当代码中出现idle就用1代替,出现one就用2代替,出现tow就用3代替,出现stop就用4代替。
需要注意的是使用parameter定义的常量,仍然可以重定义。
6.存储器
存储器实际上一个寄存器数组。
存储器使用如下方式定义:
reg[msb:
lsb]memory1[upper1:
lower1]
从高到低或从低到高定义均可(msb是最高有效位,lsb是最低有效位)。
例如:
reg[3:
0]mymem1[63:
0]//mymem1为64个4位寄存器的数组
regdog[1:
5]//dog为5个1位寄存器的数组
dog[4]=1;//合法赋值语句,对其中一个1位寄存器赋值
dog[1:
5]=0;//合法赋值语句,对存储器大范围赋值
3.运算符
1.算数运算符
在进行整数的除法运算时,结果要略去小数部分,只取整数部分;
在进行取模运算(%,也叫取余运算)时结果的符号位采用模运算符中第一个操作数的符号;
例如:
-10%3结果为-1,11%-3的结果为2;
在进行算术运算时,如果某一个操作数有不确定的值x,则整个结果也为不确定值x。
2.逻辑运算符
逻辑运算只区真假,而不管是什么数值,逻辑运算的输入4’ha2和4’h01没有区别,都是逻辑真,而0为逻辑假。
一般来说,逻辑运算的结果要么为真
(1)要么为假(0)
如果有一个输入为X,则结果也为X。
对于逻辑非:
输入为非0时结果为0
对于逻辑或:
只要输入有非0,结果就为1
对于逻辑与:
输入中有0则输出为0,输入全非0输出才为1
3.按位运算符
通常使用按位运算符完成基本的与、或、非、异或及同或逻辑运算。
使用这些位运算符进行组合,很容易完成其他的逻辑运算。
按位运算要求对两个操作数的相应位逐位进行运算
例如:
0101&1100=0100,0101|1100=1101
4.关系运算符
关系运算符和逻辑运算符一般用于条件判断语句。
关系运算符结果为1位的逻辑值1(真)或0(假),但也可能是x(未知)。
关系运算符根据关系运算的结果是真还是假,用于条件判断。
关系运算时,若关系为真,则返回值为1;若声明的关系为假,则返回值为0;
若某些操作数为不定值x,则返回值也一定为x。
5.等式运算符
6.其他特殊运算符
7.运算符优先级
为了提高程序的可读性,建议使用括号控制运算符的优先级!
4.赋值语句
1.连续赋值语句assign
assign语句用于对wire型变量赋值,是描述组合逻辑最常用的方法之一
例如assignc=a&b;//a,b可以是wire型变量或者寄存器变量,c必须是wire型变量或其他线网型变量
2.过程赋值语句
3.always语句
4.阻塞与非阻塞
阻塞概念:
在一个块语句中,如果有多条阻塞赋值语句,在前面的赋值语句没有完成之前,后面的语句就不能执行,就像被阻塞了一样,因此被称为阻塞赋值方式。
非阻塞的概念:
多条非阻塞赋值在过程块内同时完成赋值操作,多条语句相当于同时执行!
非阻塞的赋值方式:
赋值符号为<=,如b<=a;
阻塞的赋值方式:
赋值符号为=,如b=a;
非阻塞和阻塞是截然不同的!
5.条件语句
条件语句用于always或Initial过程块内部,主要包含if-else语句和case语句。
1.if-else语句
if-else语句用于判定所给条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。
if-else语句有3种形式。
2.case语句
case语句是一种多分支选择语句,if只有两个分支可以选择,但是case可以直接处理多分支语句,这样程序看起来更直观简洁。
case语句所有表达式的值的位宽必须相等。
在case语句中,分支表达式每一项都是确定的(或者为0,或者为1)
在casez语句中,若分支表达式某些位的值为高阻值Z,则不考虑对这些位的比较;
在casex语句中,若分支表达式某些位的值为z或不定值X,则不考虑这些位的比较。
也就是说,在casez中和z比较的结果都是1,在casex中,与z和x比较的结果都是1.
6.循环语句forever
forever语句是连续执行的语句。
格式:
foreverbegin语句块end
forever常用于仿真代码中
例:
forever
begin
#10clk=1;//#10表示延迟10个时间单位
#10clk=0;
end
上面的这段代码等价于:
always#10clk=~clk;都是产生20个时间单位的方波,占空比为50%。
仿真的时间单位,可以在系统中设置,也可以在仿真文件的开始加上:
timescale1ns/1ps//时间单位1ns,精度1ps
循环语句repeat
循环语句while
循环语句for
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Verilog HDL常用基本语法 HDL 常用 基本 语法