目录
2.parameter 与 local parameter定义
1 常量与变量
1.1常量
常量是 Verilog 中不变的数值, Verilog 中的常量有三种类型: 整数型、实数型、字符串型,最常用的是整数型。
整数型常量常采用基数表示法表示,这种写法清晰明了。例如:
(1) 8’hab 表示 8bit 的 十六 进制数,换算成二进制是 1010_1011;
(2) 8’d171 表示 8bit 的 十 进制数,换算成二进制是 1010_1011;
基数表示法:
[ N进制换算为二进制后 位宽 总长度] [ ' ] [数值进制符号 N(b、o、d、h)] [与数值进制符号对应的数值]
(1) 当 [换算为二进制后位宽的总长度] 比 [与数值进制符号对应的数值] 的实际位数多,则自动在[与数值进制符号对应的数值]的左边补足 0;如果位数少,则自动截断[与数值进制符号对应的数值]左边超出的位数。
(2) [位宽的总长度]可有可无,比如将数字写成 “ ’haa”,那么这个十六进制数的[位宽的总长度]就取决于[与数值进制符号对应的数值]的长度,不过规范写法是不可以漏的。
(3)数字中的下划线没有任何意义,但是可以很好的增强可读性,推荐每 4 个bit 后加一个下划线,例如: 4’b11011011 和 4’b1101_1011 表示的是一样的值。
1.2变量
Verilog 语言中主要的两种变量类型
1. 线网型:表示电路间的物理连接;
2. 寄存器型: Verilog 中一个抽象的数据存储单元。
线网型变量最常用的变量就是 wire,而寄存器型是 reg。
wire 可以看成直接的连接,在可综合的逻辑中会被映射成一根真实的物理连线;而 reg 具有对某一个时间点状态进行保持的功能,如果在可综合的时序逻辑中表达,会被映射成一个真实的的物理寄存器。
在设计逻辑的时候要明确定义每个信号是 wire 还是 reg 属性。凡是在 always 或initial 语句中被赋值的变量(赋值号左边的变量),不论表达的是组合逻辑还是时序逻辑,都一定是 reg 型变量;凡是在 assign 语句中被赋值的变量,一定是 wire 型变量。
2.parameter 与 local parameter定义
parameter 与 local parameterd都是定义参数的标识符。
parameter称为参数,一种常量,通常出现在 module 内部,常被用于定义状态机的状态、数据位宽和计数器个数等。
例如:
module water_led
#(
parameter CNT_MAX = 25'd24_999_999 ,
parameter CNT = 3'd3
)
(
input wire clk ,
input wire rst ,
output reg [4:0] led
);
local parameterd称为本地参数定义也可以写成localparam,含义和parameter一样。代码位置在module外部。
例如:
module water_led
(
input wire clk ,
input wire rst ,
output reg [4:0] led
);
local parameter CNT_MAX = 25'd24_999_999 ;
local parameter CNT = 3'd3;
区别:当定义的参数不需要被例化(被其他层文件调用时),两者没有区别。但是当上层文件如仿真文件需调整计时器计时时间,这时定义参数只能使用parameter,因为local parameter只能在当前文件生效。
3.赋值语句
赋值语句的赋值方式有两种,分别为 “<=”(非阻塞赋值)和 “=”(阻塞赋值)。
3.1阻塞型赋值:以 “=” 进行赋值
(1)“此路不通无法继续”
在串行语句块当中,是按照语句的先后顺序执行的(例如c语言),该句还没有执行完不会执行下面的语句。
(2)阻塞型过程赋值语句的执行过程:首先计算右端赋值表达式的值,然后 立即 将计算结果赋值给“=”左端的被赋值变量。
3.2非阻塞赋值:以 "<="进行赋值
(1)“此路不通可继续”
在串行语句块当中,所有语句是并行执行。非阻塞语句赋值操作执行完之前,下一条语句也可以开始执行。
(2)非阻塞型过程赋值语句的执行过程:是在同一语句块时刻上的其他普通操作结束后才得以执行,也就是并行执行。这也就是为什么fpga运行速度快的原因。
阻塞赋值常用于组合逻辑电路中,而非阻塞赋值常用于时序逻辑电路。电路设计中常用的是时序逻辑电路故非阻塞语句一定要理解。
4.if else与if case
Verilog HDL 语言中存在两种分支语言: if-else 条件分支语句 和 case 分支控制语句
if else 的三种常用格式:
(1) if
if(<条件表达式 1>)
语句或语句块 1;
(2) if else 最常用格式
if(<条件表达式 1>)
语句或语句块 1;
else if(<条件表达式 2>)
语句或语句块 2;
………
else
(3) if else嵌套使用
if(<条件表达式 1>)
if(<条件表达式 1>)
语句或语句块 1;
else
语句或语句块 2;
else if(<条件表达式 2>)
语句或语句块 ;
………
注意:在时序电路设计中缺少else分支不会产生lauch,但是在组合电路中不行,综合代码是会报错。
case的使用格式:
case(<控制表达式>)
<分支语句 1> : 语句块 1;
<分支语句 2> : 语句块 2;
<分支语句 3> : 语句块 3;
………
<分支语句 n> : 语句块 n;
default : 语句块 n+1;
endcase (不可以漏)
5.逻辑值
在 Verilog 语言中,共有四种逻辑状态,即”0“ “1” “X”和“Z。
“X”用作信号状态时表示未知,当用作条件判断时(在 casex 或 casez)表示不关心;
“Z”表示高阻状态,也就是没有任何驱动,通常用来对三态总线进行建模,仿真中蓝线警示。
在综合工具眼中,或者说在实际实现的电路中,并没有什么 X 值,只存在 0、 1 和 Z 三种状态。在实际电路中还可能出现亚稳态,它既不是 0,也不是 1,而是一种不稳定的状态,仿真过程中为红线警示。
Verilog 语言中的所有数据都是由以上描述的 4 种基本逻辑值“0”、“1”、“X”和“Z”构成的,同时,“X”和“Z”是不区分大小写的,例如 0z1x 和 0Z1X 表示同一个数据。
6.常用的系统函数
Verilog 语言中 预先 定义了一些任务和函数,用于完成一些特殊的功能,它们被称为系
统任务和系统函数,这些函数大多数都是只能在 Testbench 仿真中使用的,使我们更方便
的进行验证。
$display $write $strobe $monitor $stop $finish $time $random $readmemb | //打印信息,自动换行 //打印信息 //打印信息,自动换行,最后执行 //监测变量 //暂停仿真 //结束仿真 //时间函数 //随机函数 //读文件函数 |