1、Verilog的基础知识

Verilog的基础知识

目录

Verilog的基础知识

1.1、Verilog模块的定义与构成

1.2、基本语言要素

1.2.1、词法约定

1.2.2、数据类型

1.2.3、操作符及其表达式


1.1、Verilog模块的定义与构成

模块是Verilog层次化设计的基本构件,代表一个基本的功能单元。

每个模块由几个部分组成,包括模块名称、端口列表、数据类型说明、内部变量定义和电路功能描述等几个部分。

e.g.:

module module_name(port_list);

    port_type declarations;

    data type declarations;

    circuit functionality;

    timing specification;

endmodule

    模块的第一个要素是模块名称,定义的模块名称将唯一标识这个模块。模块名的定义和使用一般遵循以下原则:

  • 大小写敏感;
  • 避免使用Verilog的关键字;
  • 一般定义的名字含义与模块功能相关,便于使用、记忆;
  • 一般一个Verilog模块只保存为一个文件,保存该模块的文件名(文件扩展名为.v)常与模块名相同。这种做法并不是必须的,但便于设计结构的清晰,便于模块使用和管理。

    模块的端口是模块与外界环境交互的接口。在模块的定义中,包含一个可选的端口列表,端口列表紧跟在模块名后面,e.g.:module mult_acc(out,ina,inb,clk,clr);

端口的声明形式为:[msb:lsb];其中[msb:lsb]为端口的位宽,缺省时端口为标量,port_name为端口名。

 

1.2、基本语言要素

1.2.1、词法约定

(1)  标识符

    标识符是模块、变量、端口、实例、函数、任务、有名块等对象的名称,用于唯一地标识该对象;由字母、数字、下划线_ 和$等排列而成。

    定义标识符需遵循以下命名规则

  • 首字母必须为字母或下划线,不能为数字或$;
  • 可以使一串字母、数字、美元符号$或下划线的排列;
  • 标识符长度一般<1024bit;
  • 对字母大小写敏感;
  • 系统任务和系统函数必须在标识符前加上$;
  • 避免使用Verilog HDL中的关键字。

    定义各类标识符时建议使用以下的命名习惯

  • 常数名、参数名大写且有确定意义;
  • 信号名、变量名、端口名小写;
  • 时钟名以clk、clock开头;
  • 低电平有效信号名为:信号名_n;
  • 模块名应有意义。

(2)字符串

    字符串是由双引号括起来的一个字符序列,必须在一行中书写完,不能包含回车符。

(3)  空白符和转义符

    空白符由空格符(\b)、制表符(\t)和换行符(\n)组成。

(4)  注释

    单行注释使用“//”开始,并在本行结束。多行注释分别使用“/*”“*/”作为开始和结束,可包含回车符,跨越多行,多行注释不允许嵌套。

(5)常量

    ①整数

    整数有四种进制表示:二进制(b或B)、八进制(o或O)、十进制(d或D)、十六进制(h或H),使用时在前面加上半角单引号’。

    整数数字声明有以下几种:

  • 指明位宽和进制:<位宽><’进制><数字>;
  • 不指明位宽:<’进制><数字>,数字的位宽采用缺省位宽,至少为32位;
  • 不指明位宽和进制: <数字>,缺省为十进制整数。

    对于负数,只需在位宽表达式前加一个减号。

    ②x和z值

    用x和z分别表示数字电路中的不确定值和高阻值。在十六进制为基数的数中,x或z代表4位,在八进制中代表3为,在二进制中代表1位。

    约定:如果数的最高位为0、x或z,则分别使用0、x或z对这个数进行扩展,填满余下的更高位。

    ③下划线和问号

    下划线常用在数字中作分隔符,作用只是提高可读性,在编译阶段被忽略。

    在常数表示中,问号“?”是高阻z的另一个表示,在casex和casez语句中表示不关心的情况,在用户自定义原语UDP中代表0、1、x。

    ④实数

    遵循IEEE std754-1985中关于双精度浮点数的定义,采用十进制或科学计数法。

    ⑤字符串

    8位的ASCII码值的序列。

 

1.2.2、数据类型

(1)线网型(Net型)

    线网型变量可以理解为实际电路中的导线、连线,通常表示结构实体之间的物理连接,需要被持续的驱动。

    wire或tri类型变量不存储值;必须受到驱动才有效;在没有驱动源对其进行驱动时,其默认取值为高阻态(z)。

    定义wire/tri类型的语法格式:

    wire [msb:lsb] net1[,net2,…,netn];

    tri [msb:lsb] net1[,net2,…,netn];

    其中[msb:lsb]定义变量的位宽,缺省时表示位宽为1,[,net2,…,netn]可选,表示一次可定义位宽一直的变量,个变量之间用逗号隔开。

    e.g.:wire [15:0] sum,a; //定义了3个16位的wire型数据sum、a。

 

(2)寄存器型(Register型)

    不能认为寄存器型变量就一定是实际电路中的寄存器,但它会占用仿真环境的物理内存。寄存器型变量仅仅意味着保存数值的变量,数值可以通过赋值语句来改写。其中:

  • reg 可定义的无符号整数变量,可以是标量(1位)或向量,是最常用的寄存器类型;
  • interger 32位有符号整型变量,算术操作产生二进制补码形式的结果,通常用作不会   由硬件实现的数据处理;
  • real 双精度的带符号浮点变量,用法与interger相同,缺省值为0;
  • time 64位无符号整数变量,用于仿真时间的保存与处理;
  • realtime 与real内容一致,但可以用作实数仿真时间的保存于处理。

    ①reg

reg寄存器型变量没被赋值时,其默认值为x。

声明语法格式为:reg [msb:lsb] reg1,reg2,…,regn;

reg型变量通常用来表示always、initial等过程语句块内被赋值的信号。

reg类型的数组通常用于描述存储器,通过对reg型寄存器变量建立数组对存储器建模,对应实际电路中的RAM、Rom或寄存器文件。

定义格式:reg[n-1:0] 存储器名[m-1:0];

e.g.:reg [15:0]MEM [0:1023]; //1K x 16bit的存储器

②integer

存放32为有符号整数值,可以使用整数常量对其赋值。

整数变量定义形式如下:

Integer integer1,…,integerN[msb,lsb];

e.g.:integer m,n,k,HIK[3:6]

 

③time型

64位无符号整数变量,用于存储和处理仿真时间

语法申明:

Time time_id1,time_id2,…,time_idN[msb,lsb];

e.g.:time event[31:0];

      time currtime;

 

(3)参数型

语法申明格式:

Parameter 参数名1 = 表达式1,参数名2 = 表达式2,…,参数名n = 表达式n;

e.g.:parameter bitwidth = 16

parameter byte_size = 8,byte_msb = byte_size-1;

    注意:模块中参数的定义是局部的,只在当前模块中有效。

 

1.2.3、操作符及其表达式

运算符类型

操作数

符号

说明

位运算符

单目

取反

拼接及复制操作符

单目

||   |||

 

逻辑运算符

单目

|

逻辑非

算术运算符

单目

+   -

二进制补码

算术运算符

双目

+  /  %  +  -

乘、除、取模、加、减

移位运算符

双目

<<  >>

 

关系运算符

双目

> <  >=  <=

比较操作

相等运算符

双目

==  !=

相等、不等

位运算符

双目

& ~ &^ ^~ | ~|

 

归约运算符

单目

& ~ &^ ^~ | ~|

 

逻辑运算符

双目

&&  ||

逻辑与、逻辑或

条件运算符

三目

?:

二选一

你可能感兴趣的:(Verilog语言)