前言
Verilog最大的缺陷之一是没有数据结构。在SystemVerilog中可以使用struct创建结构,struct只是把数据组织到一起,是数据的集合,所以是可综合的。
结构体是可以通过模块接口进行传递的,这就是本文想描述的内容。
一、结构体的创建
1.1使用typedef创建新的类型
typedef语句用来创建新的类型。在verilog中,可以使用宏进行定,但是宏只是在做文本替换:
//老的verilog风格`define OPSIZE 8`define OPREG reg[`OPSIZE-1 :0]1OPREG op_a op_b;
而在SV中,可以使用typedef,一般约定,所有用户自定义类型都带后缀“_t”。
//新的SystemVerilog风格parameter OPSIZE =8;typedef reg [OPSIZE-1 :0] opreg_t;opreg_t op_a,op_b;
1.2使用struct创建结构体
通过struct把若干变量组合到一个结构体中
创建一个pixel类型
struct (bit[7:0]r,g,b)pixel;
上面的声明只是创建了一个pixel变量,要想在端口和程序中共享它,则必须创建一个新的类型:
typedef struct {bit[7:0]r,g,b;}pixel_s;
pixel_s my_pixel;
1.3合并结构体
- 合并结构允许对数据在存储器中的排布方式有更多的控制。
- 合并结构以连续比特集的方式存放,中间没有闲置的空间。
- 当希望减少存储器使用或存储器的部分位代表了数值时,可以使用合并结构。
二、结构体的使用
这里我们举例说明,假设需要传输一组info信息,在verilog中我们通常使用不同的bit表示不同的信息:
reg [INFO_WIDTH-1 : 0] xx_info;assign xx_info_1 = xx_info[9:0];assign xx_info_2 = xx_info[12:10];assign xx_info_3 = xx_info[17:13];assign xx_info_4 = xx_info[31:18];
这样做,一是不够清晰直白,二是在修改的时候就比较麻烦,还需要维护一份资料,详细记录。曾接手一个项目,一些信号就这样存过来,存过去,bug一堆基本都是信号没对齐,没取到正确的数据导致的。
换SV来做的话,就可以使用结构体:
typedef struct packed{logic [9:0] xx_info_1 ;logic [2:0] xx_info_2 ;logic [4:0] xx_info_3 ;logic [13:0] xx_info_4 ;}xx_info_t;
结构体直接在接口传输:
input xx_info_t xx_info;assign xx_info_1 = xx_info_t.xx_info_1;assign xx_info_2 = xx_info_t.xx_info_2;assign xx_info_3 = xx_info_t.xx_info_3;assign xx_info_4 = xx_info_t.xx_info_4;
如果是嵌套:
xx_info_4 = xx_info_t.xx_info_4_t.xx_info4;
除了引用方便之外,结构体在仿真看波形的时候也特别好用,假设使用第一种Verilog的表示方法,我们只能截取特定bit位进行查看,而结构体则可以以一个集合的形式展现,双击直接就可以展开查看结构体内部各变量元素,同时可以通过参数定义,英文字母显示,debug时候比一堆数字好辨认的多~
另外在使用的时候,建议单独建立一个结构体文件xx_struct.sv ,然后在需要使用结构体的模块将这个文件包含进去就好。
更多内容: 绿皮书