【IC】Verilog(1):基本概念

一.简介

Verilog HDL作为通用的硬件描述语言,其语法知识与C语言很相似。在Verilog里面,用模块的概念来代表一个功能块。在设计的过程中,根据顶层设计的要求来选择相应的功能块。

二.基本概念

1.模块

model
...
<模块内容>
...
endmodel

2.词法约定

2.1空白符
空白符(\b)、制表符(\t)以及换行符

2.2注释

a=b&&c;//单行注释
a=b&&c;/*多行
         注释*/

多行注释里可以嵌套单行注释;多行注释之间不可以嵌套:

/*这是//合法的注释*/
/*这是/*不合法的*/注释*/

2.3数字声明
指明位数的数字

//表示形式
<size>'<base format><number>//位宽度(十进制数)、基数格式、数字

//合法的基数格式
'<h>//十六进制
'<d>//十进制
'<o>//八进制
'<b>//二进制

//举例
4'b1111//这是一个4位的二进制数
8'o2//这是一个8位的八进制数
12'habc//这是一个12位的十六进制数

未指明位数的数字
若在数字说明中没有指明基数,则默认为十进制数;若没有指定位宽度,则默认与仿真器和使用的计算机相关(最小为32位)。

//举例
250//这是一个32位的十进制数
'b11111//这是一个32位的二进制数

X和Z值
x表示不确定值;z表示高阻值。

32'bz//这是一个32位的高阻值
12'ox//这是一个12位的八进制数,所有位都不确定
12'h11x//这是一个12位的十六进制数,四个最低位不确定
      /*十六进制中,x或z代表4位
       八进制中,x或z代表3位
       二进制中,x或z代表1位*/

负数
在位宽前面加一个减号“-”可表示该数为负数。减号不可放基数与数字之间。

-6'd3//等于-3
-6'sd3//带有符号算术运算的负数,相当于-3
6'd-3//非法说明

下划线以及问号
下划线可出现在除了第一个字符外的任何一个位置,以提高阅读性;
在常数表示中,问号相当于z

2.4字符串
字符串是用双引号括起来的字符队列,其只能在一行书写完毕。

3.数据类型

3.1线网
线网用关键字wire声明,若没有指明为向量,则默认线网的位宽为1;线网的值由驱动源决定,若没有驱动源,则线网的值为z。

//举例
wire a;//声明a是wire类型
wire b,c;//声明b、c是wire类型
wire b=1'b0;//b在声明时被赋值为0

3.2寄存器
寄存器用关键字reg声明,默认值为x。与线网不同,寄存器不需要驱动源,在仿真中的任意时刻,寄存器的值都可以通过赋值来改变。

//举例
reg reset;//声明能保持数值的变量reset
reg signed [63:0] m;//64位带符号的值

3.3向量
向量通过[high#:low#]或[low#:high#]进行说明,方括号内的左侧总是代表向量的最高有效位。

//举例
wire a;//默认线网a为标量即1位
wire [7:0] bus;//8位的总线
wire [31:0] busa,busb,busc;//3条32位宽的总线
wire [0:31] busd;//32位宽的总线,0是总线busd的最高有效位

向量域的选择

//举例
busa[7]//向量busa的第7位
busb[1:0]//向量busb的两个最低位
busb[0:1]//非法,方括号左侧是向量的高位

可变向量域的选择

//操作符形式
[<starting_bit>+:width]//从起始位开始递增,位宽为width
[<starting_bit>-:width]//从起始位开始递减,位宽为width

//举例
reg [255:0] data1;
reg [0:255] data2;
reg [7:0] byte;
byte=data1[24+:8];//从24位算起,宽度为8,相当于data1[31:24]
if(j=0;j<=31;j=j+1)
byte=data2[(j*8)+:8];//次序为[0:7]、[8:14]...

3.4整数、实数以及时间寄存器数据类型
整数类型使用integer进行声明;
实常量和实数寄存器数据类型使用real进行声明,若将一个实数赋值给整数,则实数会被取整为最接近的整数;
时间变量使用time进行声明,调用系统函数$time可以得到当前的仿真时间。

3.5数组

//数组命名形式
<数组名>[<下标>]

//举例
integer count [0:7];//由8个计数变量组成的数组
reg [4:0] port_id [0:7];//由8个端口标识变量组成的数组,端口变量的位宽为5
integer matrix [4:0] [0:255];//二维的整数型数组

//对数组元素的赋值
count [5]=0;//把count数组中第五个整数型单元赋值为零
matrix [1] [0]=33559;//把数组中第1行第0列的整数单元置为33559
port_id=0;//非法,企图写整个数组

3.6参数
参数用parameter在模块内定义,参数代表常数,每个参数值可以在编译阶段被重载;若用localparam来定义,则值不能改变。(状态机的状态编码不能改变,故常用localparam来定义)。

3.7字符串
字符串在reg类型的变量中,每个字符占用8位(一个字节)。在声明保存字符串的reg变量时,其位宽应当比字符串的位长稍大

4.系统任务和编译指令

4.1系统任务
所有的系统任务都具有$的形式。
显示信息
$display是用于显示变量、字符串或表达式的主要系统任务。

//用法
$display(p1,p2,p3,...,pn);//p1,p2,p3,...,pn是用双引号括起来的字符串、变量或表达式

//举例
$display("Hello welcome to here");
--Hello welcome to here//显示小括号内的字符串
$display($time);
--230//显示当前仿真时间(假设为230)
reg [0:40] Virtual_addr;
$display("At time %d virtual address is %h",$time,Virtual_addr);
--At time 200 virtual address is 1fe0000001c//在时间为200的时刻,显示41位虚拟地址1fe0000001c

字符串格式说明(只列出了部分)

格式 显示
%d或%D 用十进制显示变量
%b或%D 用二进制显示变量
%s或%S 显示字符串
%h或%H 用十六进制显示变量
%o或%O 用八进制显示变量
%t或%T 显示当前时间格式
%e或%E 用科学计数法格式显示实数
%f或%F 用十进制浮点数格式显示实数
\n 换行
\t tab(表格)
%% %
\ \
" "

监视信息
m o n i t o r 是 用 于 对 信 号 值 变 化 进 行 动 态 监 视 的 手 段 , 其 只 需 要 调 动 一 次 即 可 在 整 个 仿 真 过 程 中 生 效 。 若 在 源 描 述 中 调 用 了 多 个 monitor是用于对信号值变化进行动态监视的手段,其只需要调动一次即可在整个仿真过程中生效。若在源描述中调用了多个 monitor是用于对信号值变化进行动态监视的手段,其只需要调动一次即可在整个仿真过程中生效。若在源描述中调用了多个monitor,则只有最后一次调用生效,前面调用被覆盖。

//用法
$monitor(p1,p2,p3,...,pn);//格式与$display格式相同
$monitoron;//允许监视任务执行
$monitoroff;//暂停监视任务

//举例
initial
begin
$monitor($time,"Value of signals clock=%b reset=%b",clock,reset);
end//时钟每5个时间单位翻转一次,复位信号10个时间单位后变低
--0 Value of signals clock=0 reset=1
--5 Value of signals clock=1 reset=1
--10 Value of signals clock=0 reset=0

暂停和结束仿真
系统任务 s t o p 用 于 暂 停 仿 真 , 用 法 : stop用于暂停仿真,用法: stop用于暂停仿真,用法:stop;
系统任务 f i n i s h 用 于 结 束 仿 真 , 用 法 : finish用于结束仿真,用法: finish用于结束仿真,用法:finish;

4.2编译指令
`define
该编译指令用于定义文本宏。

//用法
在使用预定义的常数或者文本宏时,在宏名前加上前缀号“`”//注意是前缀号,而不是单引号

//举例
`define S $stop;//定义别名,可以用`S来代替$stop;
上一篇:ZYNQ PS PL 数据交互 Bram


下一篇:Verilog HDL基本语句