Verilog 入门指南
因本人近期公司似乎要使用FPGA做一些项目因此本人从0开始学习FPGA,如果您观看此内容默认为您至少了解并使用过c/cpp语言,并了解一些c/cpp底层原理或了解一定计算机编程语言.
1. 基础语法
1.1 数据格式
wire:网络连线格式(表示元器件之间的连接线)reg:寄存器
1.2 Verilog 格式说明
Verilog 与 C/C++ 类似,区分大小写。关键字和变量名必须正确匹配,否则底层无法正确识别代码块。
2. 数字表示
2.1 不同进制表示
- 二进制:
b/B或BIN - 十进制:
d/D或DEC - 十六进制:
h/H或HEX - 八进制:
o/O或OTC
在 Verilog 中,数字变量声明格式为n'进制值,其中n表示位数:
8'b00000000:8 位二进制变量,值为 8 个 08'hAB:8 位十六进制变量,值为 0xAB
2.2 特殊状态表示
Verilog 支持两种特殊状态:
x:未知态(可能是高电平也可能是低电平)z:高阻态(物理上无实际连接)
表示方法:
8'b1111z000 // 第4位为高阻态 8'b11111?11 // 低3位为高阻态 8'b1111x111 // 第4位为未知态 1'bx // 1位二进制变量,值为未知态2.3 下划线使用
为提高可读性,可在数字间使用下划线分隔:
8'b1111_1111 // 合法 8'b_1111_1111 // 非法(不能在进制标识符后直接加下划线) 8'b1_1_1_1_1_1_1_1 // 合法但不推荐3. 数据类型
3.1 wire 类型
表示硬件单元间的物理连接,用于模块的输入输出连接。wire 变量必须有驱动源,否则默认为高阻态(“Z”)。
特殊类型:
wand:线与wor:线或
示例:
wire a = 8'b11111111; wire b;3.2 reg 类型
用于表示存储单元,可保持数据原值:
reg reg_a; reg reg_b;3.3 parameter
用于声明常量(类似 C 中的const),编译时确定且运行时不可修改:
parameter data = 8'b01001111; parameter a = 1, b = 2; parameter size = data * 2;局部参数使用localparam,区别仅在于作用域。
3.4 数组
reg[7:0] reg_array[0:3]; // 4个8位寄存器 wire wire_array[0:7]; // 8个线网 integer integer_array[0:3]; // 4个整数 time time_array[0:1]; // 2个时间值 real real_array[0:2]; // 3个实数 reg [7:0] reg_2d_array[0:1][0:3]; // 2x4的8位寄存器数组注意:
int:只能表示二态(1/0)integer:可表示四态(1/0/z/x)
3.5 字符串
Verilog 中可通过位操作处理字符,每个字符用8位表示:
reg[39:0] hello = "hello"; // 40位存储5个字符支持转义字符如\r、\t等,每个转义字符占1字节。
verilog入门
1.基础语法
1.数据格式
wire== 网络连线格式 (线网表示元器件之间的相连线)
reg== 寄存器
2.verilog格式
1.verilog区分大小写
本质来讲 verilog 和 c/cpp几乎相同 因此在verilog中:关键字和变量名是需要区分大小写.如使用错误的变量名或错误的关键字去做一些代码工作 底层是无法正确匹配到正确的代码块的
2.数字
1.不同进制在verilog中的体现
二进制==b/B==BIN
十进制==d/D==DEC
十六进制==h/H==HEX
八进制==o/O==OTC
在 verilog中在 声明一个数字变量之前 根据 n’b n’d n’h n’o 这个n去判断这个变量 的长度
如:
8'b00000000则表示 为 8位 的 二进制 变量 变量内容为 8 个 0 字节
8'hAB则表示 为 8位 的十六进制变量 内容位 0xA 和 0xB
而在varilog的数字变量声明中有特殊的两种方式 如 x(未知态) 和 z(高阻态)
z在数电模电中我们明确的知道 Z为高阻态 即表示为在 物理状态下没有实际性的连接 为不高不低的状态
在verilog中有两种声明z(高阻态的方式)
z/?
8'b1111z000== 代表为 二进制中 第四位为 高阻态
8'11111?11== 代表为 二进制中 低三位 为高阻态
8'b1111?111 // 第四位为高阻态 8'b11111z11 // 低三位为高阻态x是一个新的概念即表示为 在一段线或引脚状态的电平信号为未知可能是高也可能是低
在verilog中声明x(未知态) 的方法如下
8'b1111x111== 代表为 二进制中 第四位为未知态
1'bx // 一个长度为1的二进制变量中存储着一个未知态2.下划线
在verilog中我们可以使用_去让一些变量变得更可读
8b1111_1111是可行的 代表了 高位 为 1111 低位 也为 1111
而8b_1111_1111是不可行的 只能在每一位数字之间加_而不能在 b ---- 1 之间添加下划线
甚至在极端情况下8'b1_1_1_1_1_1_1_1都是可行的 但是不推荐如此使用
8'b1111111 8'b1111_1111 8'hAB3.数据类型
1.wire 类型表示硬件单元之间的物理连接 用于连接模块的输出和输入
在 verilog_fpga中有多种wire表示方式 wand wor
wire变量代表了基础的线连接类型 必须有一个连续的驱动源如另一个模块的输出或组合逻辑)来驱动。如果没有任何驱动连接到 wire 变量,其缺省值为高阻态(“Z”),表示该线没有被驱动。
wand 即代表为 w(线) and(与) 与普通MCU开发中的IIC线程使用线与一样
wor 即代表了 w(线) or(或) 会对线做或操作
wire a = 8'b11111111; wire b;2.reg
reg 类型用于表示存储单元,能够保持数据的原值。
reg rag_a; reg reg_b;3.parameter
parameter是一种用于常量声明的类型 类似于 c语言中的const关键字
paramater在编译时值就已经确定运行时无法再次改变
局部参数声明方式用localparam本质上区分方法只是作用域的区分
parameter data = 8'b01001111; // 声明常量data为长度为8的 二进制 parameter a = 1, b = 2; // 声明常量 a 为 1, b 为 2 parameter size = data * 2; // 声明size 为 data x 24.数组array
reg[7:0] reg_array[0:3]; // 代表声明了一个 存储4个8位寄存器变量 wire wire_array[0:7]; // 声明了可以存储8个线网的数组 integer integer_array[0:3]; // 声明了一个整数数组 长度为4 time time_array[0:1]; // 声明了一个可以存储两个时间的数组 real real_array[0:2]; // 声明了一个可以存储两个实数 reg [7:0] reg_2d_array[0:1][0:3]; // 声明一个 8位长 的2x4寄存器数组注: 在verilog中intinteger是有区别的
int只能声明 两种态 如10即在电平信号中代表高低电平
integer可以声明 四种态10z(高阻态)x(未知态)
5.字符串
在c/cpp体系中char是可以存储字符的
chara="a";int8_tb="b";而在verilog中我们可以对每一位的字符进行操作那么整个逻辑会变得更舒适因此我们可以使用数组去存储8的倍数的二进制 一个8字节二进制即代表一个char(int8_t) = 一个字符
n个8代表n个字符 即n * 8 = n个字符串
reg[39:0] hello = "hello"; // 40长度二进制/8 = 5个字节 = 存储"hello"注:verilog中有类似于c/cpp换行符但是也会占一位字节
\r\t等等