第一章 Verilog基础知识
包括 空格符(\b)、制表符(\t) 、换行符和换页符。
在编译和综合时,空白符会被忽略。
例如:
wire [1:0] results ;assign results = (a == 1'b0) ? 2'b01 : (b==1'b0) ? 2'b10 : 2'b11 ;
//相当于
wire [1:0] results ;
assign results = (a == 1'b0) ? 2'b01 :
(b==1'b0) ? 2'b10 :
2'b11 ;
(1)单行注释:以" //
"开始,Verilog HDL忽略从此处到行尾的内容。
(2)多行注释:多行注释以“/*
"开始,到“*/
'结束,Verilog HDL忽略其中的注释内容。
例如:
wire [1:0] ip; //定义一个线网类型
reg[5-1:0] op; //定义一个寄存器类型
/*
result数据宽为2
op数据宽为5
*/
在Verilog中标识符(Identifier)被用来命名信号名、模块名、参数名等,它可以是任意一组字母、数字、“$”符号和 '_'
(下划线)符号的组合。应该注意的是标识符的字母区分大小写,并且第一个字符必须是字母或者下划线。
(2)关键字是 Verilog 中预留的用于定义语言结构的特殊标识符。Verilog 中关键字全部为小写。
例如:
//合法标识符 //非法标识符
count 30count //标识符不允许以数字开头
COUNT//与count不同 out* //标识符中不允许包含字符*
CC G5 a+b-c //标识符中不允许包含字符+和一
B25 78 n@238 //标识符中不允许包含字符@
SIX
关键字是 Verilog 语言内部的专用词,是事先定义好的确认符,用来组织语言结构,这些关键字用户不能随便使用。需注意的是,所有关键字都是小写的
。
例如,ALWAYS不是关键字,它只是标识符,与always(关键字)是不同的。
关键字 | 含义 |
---|---|
module | 模块开始 |
input | 输入端口定义 |
output | 输出端口定义 |
inout | 双向端口定义 |
parameter | 参数定义 |
wire | 线网信号定义 |
reg | 寄存器信号定义 |
always | 产生reg信号语句的关键字 |
assign | 产生wire信号语句的关键字 |
begin | 语句的开始标志 |
end | 语句的结束标志 |
posedge/negedge | 时序电路的标志 |
case | case语句开始标志 |
default | case语句默认分支标志 |
endcase | case语句结束标志 |
if | 判断语句开始标志 |
else | 判断语句标志 |
for | 循环语句标志 |
endmodule | 模块结束标志 |
表格待补充...
Verilog规定了转义标识符(Escaped Identifier)。采用转义标识符可以在一条标识符中包含任何可打印字符,转义标识符以"\
"(反斜线)符号开头,以空白结尾(空白可以是一个空格、一个制表字符或换行符)。
例如:
\a+b=c
\7400
\~Q
\{******}
转义字符 | 显示字符 |
---|---|
\n | 换行 |
\t | 制表符 |
%% | % |
\ | | |
" | " |
\ooo | 1到3个8进制数字字符 |
状态 | 含义 |
---|---|
0 | 低电平、逻辑0或“假" |
1 | 高电平、逻辑1或“真" |
x或X | 不确定或未知的逻辑状态 |
z或Z | 高阻态 |
+/-'
数制 | 基数符号 | 合法表示符 |
---|---|---|
二进制 | b或B | 0、1、x、X、z、Z、?、_ |
八进制 | o或O | 0~7、 x、 X、z、Z、?、_ |
十进制 | d或D | 0 ~ 9、_ |
十六进制 | h或H | 0 ~ 9、 a ~ f、A ~ F、x、X、 z、Z、? 、_ |
例如:
//正确表示:
8'b10001101 //位宽为8位的二进制数10001101
8'ha6 //位宽为8位的十六进制数a6
4'd6 //4位十进制数6
4'blx_01 //4位二进制数1x01
//错误表示:
4'd-4 //数值不能为负,有负号应放最左边
3' b001 //'和基数b之间不允许出现空格
(4+4)'b11 //位宽不能是表达式形式
3.
就是错误扯的表达方式,因为小数点两侧都必须要有数字。2.7 //十进制计数法
5.2e8 //科学计数法
3.5E-6 //科学计数法可用e或E表示,其结果相同
5_4582.2158_5896 //使用下划线提高可读性
6. //非法表示
.3e5 //非法表示
标记符 | 名称 | 类型 | 强弱程度 |
---|---|---|---|
supply | 电源级驱动 | 驱动 | 最强 |
strong | 强驱动 | 驱动 | |
pull | 上拉级驱动 | 驱动 | |
large | 大容性 | 存储 | |
weak | 弱驱动 | 驱动 | |
medium | 中性驱动 | 存储 | |
small | 小容性 | 存储 | |
highz | 高容性 | 高阻 | 最弱 |
注:由上到下逐渐减弱。
连线型数据类型 | 功能说明 |
---|---|
wire,tri | 标准连线(缺省时为该类型) |
wor,trior | 多重驱动时,具有线或特性的连线型 |
wand,trand | 多重驱动时,具有线与特性的连线型 |
trireg | 具有电荷保持特性的连线型数据(特例) |
tri1 | 上拉电阻 |
tri() | 下拉电阻 |
supply1 | 电源线,用于对电源建模,为高电平1 |
supply() | 电源线,用于对“地"建模,为低电平0 |
reg a; //定义一个一位的名为a的reg变量
reg [3:0] b; //定义一个4位的名为b的reg型变量
reg[8:1]c,d,e; //定义了=个名称分别为c、d、e的8位的reg型变量
reg型变量一般为无符号数,若将一个负数赋给reg型变量,则自动转换成其二进制补码形式。例如:
reg signed[3:0] rega;
rega=-2 //rega的值为1110(14),是2的补码.
[list_of_variables];
`net_declaration`:包括wire、trim、tri0、tri1、wand、triand、trior、wor中的任意一种。
`drive_strength`:表示连线变量的驱动强度。
`range`:用来指定数据类型为标量或矢量。若该项默认,表示数据类型为1位的标量,超过一位则为矢量类型。
`delay`:指定仿真延迟时间。
`list_of_variables`:变量名称,一次可定义多个名称,之间用逗号分开。
reg
;
`range`:为可选项,它指定了reg型变量的位宽,缺省时为1位。
``:为变量名称列表,一次可以定义多个名称,之间用逗号分开。
例如:物理类型数据声明:
reg rega //定义一个1位的寄存器型变量
reg [7:0] regb; //定义一个8位的寄存器型变量
tri [7:0] tribus; //定义一个8位的三态总线
tri0 [15:0] busa; //定义一个16位的连线型,处于三态时为上拉电阻
tril [31:0] busb; //定义一个32位的连线型,处于三态时为下拉电阻
reg scalared[l1:4] b; //定义一个4位的标量型寄存器矢量
wire(pull1 ,strong0)c=a+b; //定义一个1和0的驱动强度不同的1位连线型变量c
trireg(large) storeline; //定义一个具有大强度的电荷存储功能的存储线
reg[7:0] meml [255:0];//定义了一个有256个8位寄存器的存储器meml
//地址范围是0到255
reg [15:0] mem2[127:0],regl,reg2; //定义了一个具有128个16位寄存器的存储器mem2
//和两个16位的寄存器regl和reg2
reg[n-1:0] a; //表示一个n位的寄存器a
reg mem1[n-1:0]; //表示一个由n个1位寄存器构成的存储器mem1
integer index; //简单的32位有符号整数
integer i[31:0]; //定义了整型数组,有32个元素
time a,b; //定义了两个64位的时间型变量
real Stime; //定义了一个实数型数据
parameter length = 32 ,weight = 16;
parameter PI = 3.14 , LOAD = 4'b1101;
parameter DELAY = (BYTE + BIT) / 2;
Verilog运算符 | 功能 | 运算符的优先级别 |
---|---|---|
! , ~ | 反逻辑、位反相 | 高优先级 |
* , / , % | 乘、除、取模 | |
+ , - | 加、减 | |
<< , >> | 左移、右移 | |
< , <= , => , > , >= | 小于、小于等于、大于、大于等于 | |
== , != , === , !== | 等、不等、全等、非全等 | |
& | 按位与 | |
^ , ^~ | 按位逻辑异或和同或 | |
| | 按位逻辑或 | |
& | 逻辑与 | |
|| | 逻辑或 | |
?: | 条件运算符,唯一的三目运算,等同于if-else | 低优先级 |
注:由上到下优先级由高到低。
(1)算术操作结果的位宽
算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操作左端目标长度决定。
例如:
reg[3:O] A,B,C;
reg[5:O] D;
A=B+C; //4位
D=B+C; //6位
(2)有符号数和无符号数的使用
例如:
module oper;
reg [3:0] a;
reg [2:0] b;
initial
begin
a=4'b1111; //15
b=3'b011; //3
$display("%b",a*b); //乘法,结果为:4'b1101,高位被舍去
$display("%b",a/b); //除法,结果为:4'b0101
$display("%b",a+b); //加法,结果为:4'b0010
$display("%b",a-b); //减法,结果为:4'b1100
$display("%b",a%b); //取模,结果为:4'b0000
end
endmodule
module oper;
reg[3:0]a,b,c,d;
initial
begin
a=3; b=6; c=1; d=4'hx;
$display(a<b); //1
$display(a>b); //0
$display(a<=b); //0
$display(d<=a); // 未知数x
end
endmodule
寄存器变量a,b的初值分别为4'b1110和4'b0000,则:!a=0,!b=l,a&&b=0; allb=1。
a的初值为4'b1100,b的初值为4'b01X0,则!a=0,!b=x, a&&b=x, a||b=x。操作数中存在不定态x,则逻辑运算的
结果也是不定态。
模块名(连接端口1信号名,连接端口2信号名,...)
模块名(.端口1名(连接信号1名), .端口2名(连接信号2名)...);