Verilog study notes (1): Verilog basics

Chapter 1 Verilog Basics


1. Verilog syntax elements

1.1 Whitespace

空格符(\b)、制表符(\t) 、换行符和换页符。Whitespace is ignored during compilation and synthesis .
For example:

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. 2 Notes

(1) Single-line comment: //Starting with " ", Verilog HDL ignores the content from here to the end of the line.
(2) Multi-line comments: Multi-line comments /*start with " " and */end with " ', and Verilog HDL ignores the content of the comments.
For example:

wire [1:0]  ip; //定义一个线网类型
reg[5-1:0]  op; //定义一个寄存器类型
/*
result数据宽为2
op数据宽为5
*/

1.3 Identifiers

In Verilog, an identifier (Identifier) ​​is used to name a signal name, a module name, a parameter name, etc., and it can be a combination of any set 字母、数字、“$”符号和 '_' of (underscore) symbols. It should be noted that identifiers are case-sensitive and the first character must be a letter or an underscore.
(2) Keywords are special identifiers reserved in Verilog for defining language structures. Keywords in Verilog are all lowercase.
For example:

//合法标识符				//非法标识符
count					30count	//标识符不允许以数字开头
COUNT//与count不同		out*	//标识符中不允许包含字符*
CC G5					a+b-c	//标识符中不允许包含字符+和一
B25 78					n@238	//标识符中不允许包含字符@
SIX

1.4 Keywords

Keywords are special words inside the Verilog language. They are pre-defined confirmers and are used to organize the language structure. Users cannot use these keywords casually. It should be noted that 所有关键字都是小写的.
For example, ALWAYS is not a keyword, it is just an identifier, which is different from always (keyword).

keywords meaning
module module start
input Input port definition
output output port definition
inout bidirectional port definition
parameter parameter definition
wire Line net signal definition
reg Register Signal Definition
always keyword that produces a reg signal statement
assign keyword that generates a wire signal statement
begin start of statement
end end of statement
posedge/negedge Symbols of sequential circuits
case case statement start flag
default case statement default branch flag
endcase case statement end flag
if judgment statement start flag
else judgment statement flag
for loop statement flag
endmodule module end flag

表格待补充...

1.5 Escaping identifiers

Verilog specifies the escape identifier (Escaped Identifier). An escaped identifier can contain any printable character in an identifier. The escaped identifier \starts with the " " (backslash) symbol and ends with a blank (the blank can be a space, a tab character or a newline character) .
For example:

\a+b=c 
\7400
\~Q
\{******}
escape character display characters
\n new line
\t Tabs
%% %
\ |
" "
\ooo 1 to 3 octal numeric characters

1.6 Value

  • Verilog has four basic logical numerical states
state meaning
0 Low, logic 0, or "false"
1 HIGH, logic 1, or "true"
x or x indeterminate or unknown logical state
zor Z high resistance state
  • Integers and their representations
      +/-<Size>'<base format><number>
number system radix symbol legal indicator
binary b or B 0、1、x、X、z、Z、?、_
Octal oor O 0~7、 x、 X、z、Z、?、_
decimal d or D 0 ~ 9、_
hexadecimal h or h 0 ~ 9、 a ~ f、A ~ F、x、X、 z、Z、? 、_

For example:

//正确表示:
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 //位宽不能是表达式形式
  • 实数及其表示
    (1)十进制表示法,采用十进制格式,小数点两边必须都有数字,否则为非法的表示形式。例如:9.0,6.59,0.31415等等都是正确的,而3.就是错误扯的表达方式,因为小数点两侧都必须要有数字。
    (2)科学计数法。例如:3141.5e2的值为31415.0、3.6E-2的值为0.036。
    例如:
2.7 //十进制计数法
5.2e8 //科学计数法
3.5E-6 //科学计数法可用e或E表示,其结果相同
5_4582.2158_5896 //使用下划线提高可读性
6. //非法表示
.3e5 //非法表示

2,数据类型

  • 物理数据类型·连线型、寄存器型和存储器型数据类型;
    信号强度表示数字电路中不同强度的驱动源,用来解决不同驱动强度存在下的赋值冲突:
标记符 名称 类型 强弱程度
supply 电源级驱动 驱动 最强
strong 强驱动 驱动
pull 上拉级驱动 驱动
large 大容性 存储
weak 弱驱动 驱动
medium 中性驱动 存储
small 小容性 存储
highz 高容性 高阻 最弱

注:由上到下逐渐减弱。

2.1 物理数据类型

  • 连线型
连线型数据类型 功能说明
wire,tri 标准连线(缺省时为该类型)
wor,trior 多重驱动时,具有线或特性的连线型
wand,trand 多重驱动时,具有线与特性的连线型
trireg 具有电荷保持特性的连线型数据(特例)
tri1 上拉电阻
tri() 下拉电阻
supply1 电源线,用于对电源建模,为高电平1
supply() 电源线,用于对“地"建模,为低电平0
  • wire和tri
    在这里插入图片描述
  • wor和trior
    在这里插入图片描述
  • 寄存器型
    reg型是数据储存单元的抽象类型,其对应的硬件电路元件具有状态保持作用,能够存储数据,如触发器、锁存器等。
    reg型变量常用于行为级描述,由过程赋值语句对其进行赋值。
    reg型变量简单例子:
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的补码.

2.2 连线型和reg型数据类型的声明

  • 连线型数据类型的声明:

<net_declaration><drive_strength><range><delay>[list_of_variables];

 `net_declaration`:包括wire、trim、tri0、tri1、wand、triand、trior、wor中的任意一种。
 
 `drive_strength`:表示连线变量的驱动强度。
 
 `range`:用来指定数据类型为标量或矢量。若该项默认,表示数据类型为1位的标量,超过一位则为矢量类型。
 
 `delay`:指定仿真延迟时间。
 
 `list_of_variables`:变量名称,一次可定义多个名称,之间用逗号分开。
  • 寄存器型数据类型的声明:

reg<range><list_of_register_variables>;

`range`:为可选项,它指定了reg型变量的位宽,缺省时为1位。

`<list_of_register_variables>`:为变量名称列表,一次可以定义多个名称,之间用逗号分开。

例如:物理类型数据声明:

 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;	//定义一个具有大强度的电荷存储功能的存储线

2.3 存储器型

  • 存储器型变量可以描述RAM型、ROM型存储器以及reg文件。
  • 存储器变量的一般声明格式为: reg<range1><name_of_register>;
    range1和range2都是可选项,缺省都为1。
    <range1>:表示存储器当中寄存器的位宽,格式为[msb:lsb]
    <range2>:表示寄存器的个数,格式为[msb:lsb],即有msb-lsb+l个。
    <name_or_register>为变量名称列表,一次可以定义多个名称,之间用逗号分开。
  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

2.4 抽象数据类型

  • 抽象数据类型主要包括整型(integer)、时间型(time) 、实型(real)及参数型(parameter) 。
  • 整型:integer<list_of_register_variables>;
    例如:
 integer index; //简单的32位有符号整数
 integer i[31:0]; //定义了整型数组,有32个元素
  • 时间型
    时间型数据与整型数据相类似,只是它是64位的无符号数。时间型数据主要用于对模拟时间的存储与计算处理,常与系统函数$time—起使用。
    时间型数据的声明格式为:time<list_of_register_variables>;
    例如:
     time a,b; //定义了两个64位的时间型变量
  • 实型:实型数据在机器码表示法中是浮点型数值,可用于对延迟时间的计算。
    实型数据的声明格式:real<list_of_variables>;
    例如:
     real Stime; //定义了一个实数型数据 
  • 参数型(parameter):属于常量,在仿真开始之前就被赋值,在仿真过程中保持不变,以提高程序的可读性和维护性。
    参数类型的定义格式为:
    parameter 参数名1=表达式1,参数名2=表达式2,…,参数名n:表达式n;
    例如:
parameter length = 32 ,weight = 16;
parameter PI = 3.14  , LOAD = 4'b1101;
parameter DELAY = (BYTE + BIT) / 2;

3,运算符和表达式

Verilog运算符 功能 运算符的优先级别
! , ~ 反逻辑、位反相 高优先级
* , / , % 乘、除、取模
+ , - 加、减
<< , >> 左移、右移
< , <= , => , > , >= 小于、小于等于、大于、大于等于
== , != , === , !== 等、不等、全等、非全等
& 按位与
^ , ^~ 按位逻辑异或和同或
| 按位逻辑或
& 逻辑与
|| 逻辑或
?: 条件运算符,唯一的三目运算,等同于if-else 低优先级

注:由上到下优先级由高到低。

3.1 算术操作符

  • 加法(+),减法(-),乘法(*),除法(/),取模(%)。

(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

3.2 关系操作符

  • 大于(>),小于(<),大于等于(>=),小于等于(<=)
    例如:
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

3.3 相等关系操作符

  • 等于(==),不等于(!=),全等(===),非全等(!==)。
  • 比较结果有三种,即真,假和不定值。
    如下真值表:
    在这里插入图片描述
    在这里插入图片描述
    例如:
    在这里插入图片描述

3.4 逻辑运算符

  • 逻辑与运算符"&&“、逻辑或运算符”||“、逻辑非运算符”!"

在这里插入图片描述
例如:

寄存器变量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,则逻辑运算的
结果也是不定态。

3.5 按位运算符

  • 按位取反"~“、按位与”&“、按位或”|“、按位异或”^“、按位同或”^~"
    在这里插入图片描述
    在这里插入图片描述

3.6 归约运算符(缩位运算符)

  • 与"&“、或”|“、异或”^“、以及相应的非操作”&“、”~|“、”~^“、”^~"
    例如:
    在这里插入图片描述

3.7 移位操作符

  • 左移位运算符“<<“、右移位运算符”>>”.
  • 运算过程是将左边(右边)的操作数向左(右)移,所移动的位数由右边的操作数来决定,然后用0来填补移出的空位。在这里插入图片描述

3.8 条件运算符

  • 表达形式如下:
    <条件表达式>?<表达式1 >:<表达式2>
    条件表达式的计算结果有真“1"、假“0"和未知态x“三种,当条件表达式的结果为真时,执行表达式1,当条件表达式的结果为假时,执行表达式2。
    2选1数据选择器

在这里插入图片描述

3.9 连接和复制运算符

  • 连接运算符"{}“和复制运算符”{ {}}"
  • 连接操作符
    {信号1的某几位,信号2的某几位、… 、信号n的某几位}
  • 重复操作符{ {}}将一个表达式放入双重花括号中,复制因子放在第一层括号中。
    例如:
    在这里插入图片描述

4,模块的基本概念

4.1 模块的基本概念

  • 模块(module)是Verilog的基本单元,它代表一个基本的功能块,用于描述某个设计的功能或结构以及与其它模块通信的外部端口。
  • 模块结构组成图如下:
    在这里插入图片描述
  • 一个模块主要包括:模块的开始与结束、模块端口定义、模块数据类型说明和模块逻辑功能描述这几个基本部分。
    (1)模块的开始与结束:以关键词module开始,以关键词endmodule结束的一段程序,其中模块开始语句必须要以分号结束。
    (2)端口定义:用来定义端口列表里的变量哪些是输入(input)、输出(output)和双向端口(inout)以及位宽的说明。
    (3)数据类型说明:数据类型在语言上包括wire、reg、memory和parameter等类型,用来说明模块中所用到的内部信号、调用模块等的声明语句和功能定义语句。
    (4)逻辑功能描述:用来产生各种逻辑(主要是组合逻辑和时序逻辑)。主要包括以下部分:initial语句、always语句、其它子模块实例化语句、门实例化语句、用户自定义原语(UDP)实例化语句、连续赋值语句(assign)、函数(function)和任务(task) 。

在这里插入图片描述
在这里插入图片描述

4.2 端口

  • 端口的定义
    模块的端口可以是输入端口(input)、输出端口(output)或双向端口(inout) 。
  • 模块引用时端口的对应方式
    (1)在引用时,严格按照模块定义的端口顺序来连接,不用标明源模块定义时规定的端口名。格式如下:
    模块名(连接端口1信号名,连接端口2信号名,...)
    (2) 在引用时用“."标明源模块定义时规定的端口名。格式如下:
    模块名(.端口1名(连接信号1名), .端口2名(连接信号2名)...);
  • 这样表示的好处在于可以用端口名与被引用模块的端口对应,不必严格按端口顺序对应,提高了程序的可读性和可移植性。

来源:蔡觉平老师的Verilog课程

Guess you like

Origin blog.csdn.net/KIDS333/article/details/126928475