Verilog读书笔记---数据类型、系统任务、`define、parameter、localparam三者的区别

简介: Verilog读书笔记---数据类型、系统任务、`define、parameter、localparam三者的区别

本文目的


主要梳理之前学习Verilog的疏漏内容,系统了解Verilog语法。

Verilog的数据类型:


Verilog有两组主要的数据类型:网络数据类型(Net Data Type)和寄存器数据类型(Register Data Type)。其他的数据类型有:事件(Event)、参数(Parameter)和范围(Specparam)以及其他数据类型。

Verilog还是用强度值来解决数字电路中不同强度的驱动源之间的赋值冲突

image.png

如果两个具有不同强度的信号驱动同一个线网,则竞争结果值为高强度信号的值。

如果两个强度相同的信号之间发生竞争,则结果为不确定值。

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


整数


是一种通用的寄存器数据类型,用于对数量进行操作,使用integer进行声明。

integercounter;       //一般用途的变量用作计数器initialcounter=-1;    //-1存储到寄存器中

实数:


实常量和实数寄存器数据类型使用关键字real来声明,可以用十进制或科学计数法来表示。实数声明不能带有范围,其默认值为0.如果将一个实数赋予一个整数,那么实数将会被取为最接近的整数。realdelta;         //定义一个名为delta的实型变量

时间寄存器


仿真是按照仿真时间进行的,verilog使用一个特殊的时间寄存器数据类型来保存仿真时间。时间变量通过使用关键字time来声明,其宽度与具体实现无关,最小为64位。通过调用系统函数$time可以取得当前的仿真时间。

数组


Verilog中允许声明reg、integer、time、real、realtime及其向量类型的数组,对数组的维数没有限制,即可声明任意维数的数组。线网数组也可用于连接实例的端口,数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如<数组名>[<下标>]
Integercount[0:7];       //由八位计数变量组成的数组regbool [31:0];              //由32个1位的布尔寄存器变量组成的数组wire [7:0] w_array2 [5:0];        //声明8位向量的数组

注意:不要把数组和线网或寄存器向量混淆起来。向量是一个单独的元件,它的位宽是n,数组由多个元件组成,其中每个元件的位宽为n或1.

nets型


wire型数据常用来表示用于以assign关键字指定的组合逻辑信号。

Verilog程序模块中输入输出信号类型默认为wire型。

wire型信号可以用做方程式的输入,也可以用做”assign”语句或者实例元件的输出

image.png

reg型


reg是寄存器数据类型的关键字。

寄存器是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值,其作用相当于改变触发器存储器的值。

reg型数据常用来表示always模块内的指定信号,代表触发器。

通常在设计中要由always模块通过使用行为描述语句来表达逻辑关系。在always块内被值的每一个信号都必须定义为reg型,即赋值操作符的右端变量必须是reg型

rg型号数据的格式:

reg[n-1:0]数据名1,数据名2,…,数据N;

//定义了N个寄存器变量,每个数据位宽为n

reg型数据的默认值是不定的。reg型数据可以为正值或负值。当一个reg型数据是一个表达式中的操作数时,它的值被当做无符号值,即正值(如果一个4位的reg型数据被写入-1,在表达式中运算时,其值被认为是+15)

reg型和wire型的区别:reg型保持最后一次的赋值,而wire型需要持续驱动。

Memory型


image.png

尽管memory型数据和reg型数据的定义格式很相似,但是要注意不同之处。Memory描绘的是深度,reg描绘的是宽度。

Reg [ n-1:0 ] rega;  //一个n位寄存器Regmema [ n-1 ]  //一个由n个一位寄存器组成的存储器组一个n位的寄存器可以在一条赋值语句里进行赋值。而一个完整的存储器不行Rega=0//合法的赋值语句Mema=0//非法的赋值语句Mema[3]=0//合法,给memory中的第三个单元赋值为0

数组


Verilog中允许声明reg、integer、time、real、realtime及其向量类型的数组,对数组的维数没有限制,即可声明任意维数的数组。线网数组也可用于连接实例的端口,数组中的每个元素都可以作为一个标量或者向量,以同样的方式来使用,形如<数组名>[<下标>]。

Integer count[0:7]; //由八位计数变量组成的数组

reg bool [31:0]; //由32个1位的布尔寄存器变量组成的数组

wire [7:0] w_array2 [5:0]; //声明8位向量的数组

=注意:不要把数组和线网或寄存器向量混淆起来。向量是一个单独的元件,它的位宽是n,数组由多个元件组成,其中每个元件的位宽为n或1.==

向量


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

wirea;      //标量线网变量,默认wire [7:0] bus;          //8位的总线regclock  ;                 //标量寄存器,默认reg   [0:40]        virtual_addr;    //向量寄存器,41位宽的虚拟地址

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

可变向量域选择


image.png

Verilog的系统任务


系统任务也属于行为级建模,系统任务的调用要出现在initial与always结构中。所有的任务都已$开头。

1、d i s p l a y , display,display,write用于信息的显示和输出。

image.png

image.png

调用方式:eg:$display("%b+%b=%b",a,b,sum);
$write("%b+%b=%b",a,b,sum);

注:如果没有在指定变量的显示格式,不会输出数值。如果没有指定变量显示的位置,变量值会在字符串部分之后直接显示出来,变量之间是没有间隔的,只是一次简单的显示。


显示任务d i s p l a y 默 认 显 示 的 格 式 是 十 进 制 的 , 还 有 display默认显示的格式是十进制的,还有display默认显示的格式是十进制的,还有displayb,d i s p l a y o , displayo,displayo,displaybh的显示格式分别是二进制,八进制,十六进制。同理有w r i t e , write,write,writeo,w r i t e b , writeb,writeb,writeh。

display与write的区别是:d i s p l a y 会 在 每 次 显 示 信 息 后 自 动 换 行 , display会在每次显示信息后自动换行,display会在每次显示信息后自动换行,write不会换行.

2、$strobe探测任务

探测任务的语法和显示任务完全相同,也是把信息显示出来。也有s t r o b e , strobe,strobe,strobeb,s t r o b e o , strobeo,strobeo,strobeh四种。

两者的区别在于:s t r o b e 命 令 会 在 当 前 时 间 部 结 束 时 完 成 ; 而 strobe命令会在当前时间部结束时完成;而strobe命令会在当前时间部结束时完成;而display是只要仿真器看到就会立即执行。

3、$monitor监测任务

监测任务用于持续监测指定变量,只要这些变量发生了变化,就会立即显示对应的输出语句,并且在仿真中只能进行一次调用,后面的调用会覆盖前面的。

eg:initialbegin$monitor("x=%b,y=%b,cin=%b",x,y,cin);
end

同理,有m o n i t o r , monitor,monitor,monitorbm o n i t o r o monitoromonitoromonitorh。

可用$monitoroff,monitoeron关闭监事和打开监视。

4、s t o p , stop,stop,finish仿真控制任务

区别:s t o p 暂 停 当 前 方 针 , stop暂停当前方针,stop暂停当前方针,finish终止值当前方针。

`define:作用 -> 常用于定义常量可以跨模块、跨文件;

范围->整个工程;
parameter:作用->常用于模块间参数传递;
范围->本module内有效的定义;
localparam作用->常用于状态机的参数定义;
范围->本module内有效的定义,不可用于参数传递;
localparamcannotbeusedwithinthemoduleportparameterlist.

2、应用举例

`define、parameter、localparam三者的区别及举例


`define


概念:可以跨模块的定义,写在模块名称上面,在整个设计工程都有效。一旦`define指令被编译,其在整个编译过程中都有效。例如,通过另一个文件中的`define指令,定义的常量可以被其他文件调用,
直到遇到 `undef;
举例:定义 `defineUART_CNT10'd1024使用 `UART_CNT

parameter


概念:本module内有效的定义,可用于参数传递;
           如果在模块内部定义时无法进行参数传递,
           若在模块名后照下面这样写则可以进行传递

举例:定义

modulevideo_in#(parameterMEM_DATA_BITS=64,
parameterINTERLACE=1//0)          (
inputclk,
inputrst_n,
outputburst_finsh          );

使用 -> 调用此模块的时候可以像端口信号传递一样进行参数传递

video_in#( .MEM_DATA_BITS ( 64 ),          .INTERLACE     ( 1  )
)u_video_in (
        .clk             (clk_50m),
        .rst_n          (rst_n),
        .burst_finsh (burst_finsh)
        );

localparam:


概念:本module内有效的定义,不可用于参数传递;localparamcannotbeusedwithinthemoduleportparameterlist.
一般情况下,状态机的参数都是用localparam的。

举例:

localparamBURST_LEN=10'd64;     /*一次写操作数据长度 */localparamBURST_IDLE=3'd0;       /*状态机状态:空闲 */localparamBURST_ONE_LINE_START=3'd1;       /*状态机状态:视频数据一行写开始 */localparamBURSTING=3'd2;       /*状态机状态:正在处理一次ddr2写操作 */localparamBURST_END=3'd3;       /*状态机状态:一次ddr2写操作完成*/localparamBURST_ONE_LINE_END=3'd4;       /*状态机状态:视频数据一行写完成*/reg[2:0]  burst_state=3'd0;       /*状态机状态:当前状态 */reg[2:0]  burst_state_next=3'd0;       /*状态机状态:下一个状态*/
目录
相关文章
|
6月前
|
编译器 C#
C#.Net筑基-类型系统②常见类型 --record是什么类型?
`record`在C#中是一种创建简单、只读数据结构的方式,常用于轻量级数据传输。它本质上是类(默认)或结构体的快捷形式,包含自动生成的属性、`Equals`、`ToString`、解构赋值等方法。记录类型可以继承其他record或接口,但不继承普通类。支持使用`with`语句创建副本。例如,`public record User(string Name, int Age)`会被编译为包含属性、相等比较和`ToString()`等方法的类。记录类型提供了解构赋值和自定义实现,如密封的`sealed`记录,防止子类重写。
|
6月前
|
Dragonfly 安全 数据安全/隐私保护
什么是WPA3?与WPA2有啥区别?
【4月更文挑战第14天】
4954 2
什么是WPA3?与WPA2有啥区别?
|
存储 数据挖掘 数据库
data的含义与作用及使用方法
data的含义与作用及使用方法
6408 0
|
芯片 索引 内存技术
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
玩转parameter与localparameter,这篇文章就够了【Verilog高级教程】
|
编解码
wrf模式学习记录--如何计算三层嵌套中的e_sn/e_we/ i_parent_start/ j_parent_start
在此记录一下关于wrf模式中如何计算嵌套网格的格点数,即e_sn / e_we
wrf模式学习记录--如何计算三层嵌套中的e_sn/e_we/ i_parent_start/ j_parent_start
|
云栖大会
aPaaS和iPaaS的区别
aPaaS和iPaaS的区别自制脑图
230 0
aPaaS和iPaaS的区别