verilog_基本概念

2016.9.2

目标:

     1.理解操作符、注释、空白符、数字、字符串、和标识符放入词法约定

     2.定义逻辑值集合和数据类型

     3.学习使用用于显示和监视信息、暂停和结束仿真的系统任务

     4.学习用于宏定义、文件包含的基本编译指令

1词法约定

1.1空白符

由空格()、制表符( )和换行符组成

1.2注释

单行注释(\)

多行注释(/**/)

1.3操作符

单目、双目、三目

a= ~ b;//单目
a=b && c;//双目
a=b ? c : d//三目

1.4数字声明

指明位数声明和不指明位数声明

指明位数声明格式:<size>'<base format><number>

<size>数字的为宽度

<base format>

'd或'D 

'h或'H 

'b或'B

 'o或'O

 不指明位数的数字

没指定基数,则默认为十进制数,

没指定位宽,则默认与仿真器和计算机有关(最小为32位)

X和Z值

X代表不确定值

Z代表高阻值

16进制中,X和Z代表4位;

8进制中,X和Z代表3位;

2进制中,X和Z代表1位。

负数

 在表示位宽的数字前面增加一个减号来表示它是一个负数。

而将减号放在基数和数字之间是非法的

2.数据类型

2.1值的类型

四值逻辑和八种信号对实际硬件进行建模

   四值电平逻辑                                                                                                                           

值的级别

硬件电路的条件

0

逻辑0,条件为假

1

逻辑1,条件为真

x

逻辑值不确定

y

高阻,浮动状态

   强度等级                                                                                                                               

强度等级 类型 程度
supply 驱动

最强

最弱

strong 驱动
pull 驱动
large 存储
weak 驱动
medium 存储
small 存储
highz 高阻

不同强度的信号驱动同一线网,则竞争结果为高强度信号的值;同等强度的信号驱动同一线网,则结果为不确定值

2.2线网

线网表示硬件单元之间的连接。

一般用wire进行声明

线网的默认值为z(trireg类型的线网例外,其默认值为x)

线网值由驱动源确定,如果没有,则线网的值为z

2.3寄存器

 寄存器用来表示存储器件,它保持原有数值,直到被改写。

关键字为reg,默认值为x。

reg reset;//声明能保持数值的变量reset
initial //这个结构以后讨论
begin
    reset = 1'b1;//把reset初始化为1,使数字电路复位
    #100 reset = 1'b0;//经过100个时间单位后,reset置逻辑0
end

也可以声明为带符号(signed)类型的变量,这样的寄存器就可以用于带符号的算术运算

reg signed [63:0] m;  //64位带符号的值
integer i ; //32位带符号的值

2.4向量

线网和寄存器类型的数据均可以声明为向量(位宽大于1)。若没指定,则默认为标量(1位)

wire a;/ /标量线网变量,默认
wire [7:0]  bus //8位的总线
wire[31:0] busA,busB,busC;//3条32位宽的总线
reg clock;//标量寄存器,默认
reg [0:40] virtual_addr;//向量寄存器,41位宽的虚拟地址(最高有效位是它的第0位)

 方括号中左边的数总是代表向量的最高有效位。

向量域选择

我们可以在向量中指定它的某一位或若干相邻位,但要注意高位依然要写在左侧

可变的向量域选择

可以通过for循环来动态地选取向量的各个域。

专用操作符

[<starting_bit>+:width]:从起始位开始递增,位宽为width。

[<starting_bit>-:width]:从起始位开始递减,位宽为width。

 起始位可以是变量,但位宽必须是常量。

reg[255:0] data1; //
reg[0:255] data2;//
reg[7:0] byte;
//
byte = data1[31-:8]; //从31位算起,宽度为8位,相当于data2[31:24]
byte = data1[24+:8];//从24位算起,宽度为8位,相当于data2[31:24]
byte = data2[31-:8]; //从31位算起,宽度为8位,相当于data2[24:31]
byte = data2[24+:8];//从24位算起,宽度为8位,相当于data2[24:31]
//起始位可以是变量,但宽度必须是常数。因此可以通过可变域选择
//用循环语句选取一个很长的向量的所有位
for(j=0;j<=31;j=j+1)
byte = data1[(j*8)+:8];//次序为[7:0],[15:8]...[255:248]

//用于初始化向量的一个域

data1[(byteNum*8)+:8] =8'b0;//如果byteNum = 1,共有8位被清零,[15:8]

 2.5整数、实数和时间寄存器数据类型

除reg类型之外,verilog还支持integer,real,和time寄存器数据类型。

整数(integer)

通用的寄存器数据类型,用于对数量进行操作。

声明一个整数类型的变量来完成计数等功能显然比reg更为方便。

位宽为宿主机的字的位数,最小应为32位。

reg类型的寄存器变量为无符号数,而整数类型的变量则为有符号数。

实数(real)

实常量和实数寄存器数据类型,可以使用十进制或科学计数法。实数声明不能带有范围,默认值为0;

如果将一个实数赋给一个整数,那么实数将会被取整为最接近的整数

时间寄存器(time)

时间变量通过time来声明,宽度与具体实现有关,最小为64位。

通过调用系统函数$time可以得到当前的仿真时间。

2.6数组

允许声明reg,integer,time,real,realtime及其向量类型的数组,对数组维数没有限制。

形如<数组名>[<下标>],对于多维数组需要说明其每一维的索引

赋值

integer count[0:7];//8个计数变量组成数组
reg bool[31:0];//32个1位的布尔寄存器变量组成数组
time chk_point[1:100];//100个时间检查变量组成数组
reg [0:4] port_id[0:7];//8个端口标识变量组成数组,端口位宽为5
integer matrix[4:0][0:255];//二维的整数型数组
reg [63:0] array_4d [15:0] [7:0] [7:0] [255:0];//四维64位寄存器型数       组
wire [7:0] w_array2 [5:0];//声明8位向量数组
wire w_array1 [7:0] [5:0];//声明1位线型变量的二维数组
//赋值
count[5]=0;//count中第五个整数型单元(32位)复位
chk_point[100] = 0;//第100个时间型单元(64位)复位
port_id[3] = 0;//第3个寄存器型单元(5位)复位
marix[1][0] = 33339;//第1行第0列的整数型单元(32位)置为33339
array_4d[0][0][0][0][15:0] = 0;//把四维数组中索引号为[0][0][0][0]的寄存器型单元的0~15位都置于0

2.7存储器

对寄存器,RAM和ROM建模。使用寄存器的一维数组来表示存储器,数组每个元素称为一个元素或一个字(Word),由一个数组索引来指定,每一个字的位宽为1位或多维。

2.8参数

使用parameter在模块内定义常数。参数代表常数,不能像变量那样赋值,但是每一个模块实例的参数值可以在编译阶段被重载。通过参数重载使得用户可以对模块实例进行定制。

局部参数使用关键字localparam来定义,其作用等同于参数,区别在于它的值不能改变,不能通过参数重载语句(defparam)或通过有序参数列表或命名参数赋值来直接修改。

2.9字符串

字符串保存在reg类型的变量中,每一个字符占用8位(一个字节)。左补左截。

特殊字符

转义字符 显示的字符
换行
tab(制表空格)
%% %
\
" "
ooo 1到3个八进制数字字符

3系统任务和编译指令

3.1系统任务

为某些常用操作提供了标准的系统任务(系统函数),包括屏幕显示、线网值动态监视、暂停和结束仿真。

所有系统任务都具有$<keyword>的形式

显示信息($display)

用于显示变量、字符串或表达式的主要系统任务

用法:$display(p1,p2,p3,...,pn);

p1,p2,p3,...,pn是双引号括起来的字符串、变量或者表达式,会自动在字符串结尾插入一个换行符。

字符串格式说明

格式  显示 
 %d或%D

用十进制显示变量 

%b或%B 

用二进制显示变量 

%s或%S 

显示字符串 

%h或%H 

用十六进制显示变量 

%c或%C 

 显示ASCII字符

%m或%M 

显示层次名 

%v或%V 

显示强度 

%o或%O 

用八进制显示变量 

%t或%T 

显示当前时间 

%e或%E 

用科学记数法格式显示实数 

%f或%F 

用十进制浮点数格式显示实数 

%g或%G  用科学记数法或十进制格式显示实数,显示较短的格式 

 监视信息

通过系统函数$monitor,提供了对信号值变化进行动态监视的手段。

用法:$monitor(p1,p2,p3,...,pn);

p1,p2,p3,...,pn可以是变量、信号名或双引号括起来的字符串。其对参数列表中的变量值或信号值进行不间断监视。因此在任意仿真时刻只有一个监视列表有效,也就是只有最后一次的调用有效

 两个用于控制监视的系统任务:$monitoron和$monitoroff

用法:$monitoron;(允许监视任务的执行)

         $monitoroff;(暂停监视)

在$monitor中使用系统函数$time来取得系统仿真时间。

暂停和结束仿真

用法:$stop;

         $finish;

3.2编译指令

使用方法'<keyword>;

'define

用于定义文本宏

'include

可以在编译期间将一个Verilog源文件包含在另一个源文件中,作用类似于C语言中的#include结构。

原文地址:https://www.cnblogs.com/fxygrzb/p/5913379.html