FPGA/verilog 学习笔记—— Verilog基础语法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA/verilog 学习笔记—— Verilog基础语法相关的知识,希望对你有一定的参考价值。
文章目录
- Verilog基础语法
- 一、基础知识
- 1. 逻辑值
- 2. 数字进制格式
- 3. 标识符
- 二、数据类型
- 1. reg和wire类型
- (1)reg寄存器类型
- (2)wire线网类型
- (3)reg和wire的区别
- 2. integer类型
- 3. parameter类型
- 三、运算符
- 1. 运算符优先级
- 2. 算术运算符
- 3. 关系运算符
- 4. 逻辑运算符
- 5. 条件运算符
- 6. 位运算符
- 7. 移位运算符
- 8. 位拼接运算符
Verilog基础语法
一、基础知识
1. 逻辑值
逻辑值 | 代表 | 对应电路 |
0 | 低电平 | GND |
1 | 高电平 | VCC |
X | 未知(高电平或低电平) | 可能是VCC或GND |
Z | 高阻态 | 悬空状态,外部没有激励信号 |
2. 数字进制格式
- Verilog数字进制格式包括二进制、八进制、十进制、十六进制
- 进制示例
进制 | 写法 | 代表 |
二进制 | | 4位二进制数0101(B) |
十进制 | | 4位十进制数2(D),二进制0010(B) |
十六进制 | | 4位十六进制数a(H),二进制1010(B) |
- 缺省是32位十进制表示:直接写
100
,Verilog理解为32d100
- 二进制数每4位数可以加下划线增加可读性:
16b1001_1010_1010_1001 = 16h9AA9
3. 标识符
- 用于定义模块名、端口名、信号名
- 标识的第一位必须是字母或下划线
- 大小写敏感
- 可是任意一组以下符号的组合
- 数字(不能做第一位)
- 字母
-
$
符号(不能做第一位) -
_
下划线
- 良好的命名规范
- 不要大小写混用
- 普通内部信号最好全部小写
- 信号名应当简洁、清晰、易懂
- 示例:
- 用有意义的词:
sum
、cpu_addr
等 - 用下线区分词:
cpu_addr
- 采用一些前缀后缀:
clk_50
、clk_cpu
二、数据类型
- 三种基本数据类型
- 变量数据类型(共5种):reg、integer、time、real、realtime…
- 线网数据类型(共11种):wire、tiror、trireg、tri、wand、tril、wor…
- 参数数据类型:parameter…
- Verilog允许定义各个类型的数组
- 真正在数字电路中起作用的是寄存器类型和线网类型(可以映射到实际的数字电路)
1. reg和wire类型
(1)reg寄存器类型
- 寄存器表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器存储的值
- 关键字:
reg
reg[31:0] delay_cnt; //delay_cnt是一个位宽32位的寄存器,注意高位写前面
reg key_reg; //key_reg是一个位宽为1的寄存器
- 默认初始值:
X
- reg类型的数据只能在
always
和initial
块中被赋值 - reg类型的物理意义:
- 如果此过程语句描述的是时序逻辑,即
always
语句带时钟信号,则此寄存器对应触发器 - 如果此过程语句描述的是组合逻辑,即
always
语句不带时钟信号,则此寄存器对应硬件连线
(2)wire线网类型
- 线网数据表示结构实体(如门)之间的物理连线
- 关键字:
wire
、tri
,常用wire
型
wire key_flag; //1位位宽
wire [1:0]my_flag; //2位位宽
- 线网的数据不能存储值,它的值是由驱动它的元件决定的;如果没有驱动原件连接到线网类型变量上,则此变量是高阻的,即值为:
z
- 可以驱动线网类型变量的元件
- 门
- 连续的赋值语句
- assign语句
(3)reg和wire的区别
- 类型区别
- reg是一种变量类型(和integer、time类型并列)
- wire是一种线网类型(和wand、tir类型并列)
- 赋值
- reg只能在initial和always块中赋值
- wire只能通过连续赋值语句assign或通过模块输入输出端口赋值
- 初始值
- reg初始值为
x
(未知) - wire初始值为
z
(高阻)
- 强度值
- reg不能被赋予强度值
- wire可以被赋予强度值
2. integer类型
- 整形变量包含一个整数值,可以作为普通变量使用,通常用于高层次行为建模
- 支持有符号数,算数运算结果以2的补码表示
- integer数至少有32位,具体实现时可以提供更多位
- 定义
- 格式
integer a1,a2,a3..,an[msb:lsb]
- 示例
integer a,b,c; //3个整型变量
integer d[3:6]; //1个整型变量数组
- 直接定义的
interger a
,a也可以当作数组访问。如a[6]
之类的访问是合法的
- 整型和位向量的转换
//整型->位向量
reg [31:0] sel_reg;
integer sel_int;
sel_reg = sel_int;
//位向量->整型
integer j;
reg[3:0] bcq;
j = 6; //j = 32b0000...0110
bcq = j; //bcq的值为4b0110
bcq = 4‘0101;
j = bcq; //j = 32b0000...0101
j = -6; //j = 32b1111...11010
bcq = j; //bcq = 4b1010
- 转换赋值总是从最右边的位开始,到最左边的位结束,多余的位被截断
3. parameter类型
- 参数其实就是一个常量
- 关键字:
parameter
- 可以一次定义多个参数,之间用
,
分隔 - 每个参数定义的右边必须是一个常量表达式
- 常见用途
- 定义状态机的状态
- 定义数据位宽(比如
wire [len:0] flag;
这里的len
就可以定义位成参数变量,方便修改) - 定义延时的大小
- 采用标识符来代表一个常量可以提升程序的可维护性和可读性
- 在模块调用时,可以用参数传递来改变被调用模块中已定义的参数
三、运算符
1. 运算符优先级
2. 算术运算符
- 注意
a/b
会截断舍去小数
3. 关系运算符
4. 逻辑运算符
5. 条件运算符
-
result = (a>=b)?a:b;
6. 位运算符
- 如果位宽不一致,会先给短的数据高位补零,使二者位宽一致后再运算
7. 移位运算符
- 都是用0补移出来的空位
- 左移时,位宽增加;右移时,位宽不变
-
4b1001 << 2 == 6b100100
为真
4b1001 >> 1 == 4b0100
为真
8. 位拼接运算符
-
c = a,b[3:0]; //拼接a和b的低四位作为c信号,a的部分在高位,b的部分在低位
以上是关于FPGA/verilog 学习笔记—— Verilog基础语法的主要内容,如果未能解决你的问题,请参考以下文章
基于 FPGA verilog 的 Ethercat 主站工程代码
实现FPGA Verilog HDL与NIOS II的通信数据交换——利用AVALON总线