SV中的一些整合数据的操作
背景
sv中其实有一些整合数据的操作,虽然平时可能用的不多,但是也是非常实用的
核心内容(3-5 个要点)
- typedef
- struct
- union
- packed
我的理解
typedef
typedef的主要作用是用来给一个数据类型重新命名,把它变成一种编码者方便理解的类型。比如我们想要声明几个位宽为32 bit的数据,如果不使用typedef,我们得这么写
bit[31:0] addr;
bit[31:0] wdata;
bit[31:0] rdata;
但如果用typedef,我们就可以这么写
typedef bit[31:0] uint32_t;
uint32_t addr;
uint32_t wdata;
uint32_t rdata;
struct
struct用来创建属于自己的数据类型
struct {bit[7:0] r, g, b;} pixel;
如果后续想要用同样的格式新建一系列数据类型,那就可以搭配typedef
initial begin
typedef struct {bit[31:0] addr;
bit wr;
bit[31:0] wdata;} my_struct_s;
my_struct_s st = '{32'h0000_000C, 1'b1, 32'hFFFF_FFFF};
$display("str=%x %x %x", st.addr, st.wr, st.wdata);
end
union
第一次接触到union的时候感觉很抽象,根本不知道这种数据结构有什么作用,直到遇到了寄存器模型在真正理解了union。union可以用多个变量来描述同一个量,就像寄存器模型,你可以直接往32bit里写,也可以对某一个field进行针对性的修改,但是实际上二者操作的都是同一块内存
typedef struct packed {
logic [28:0] reserved; // Bit 31:3
logic [1:0] mode; // Bit 2:1
logic enable; // Bit 0
} ctrl_fields_t;
typedef union packed {
logic [31:0] raw; // 视图A:CPU看到的完整32位数值
ctrl_fields_t fields; // 视图B:硬件逻辑看到的具名字段
} ctrl_reg_t;
ctrl_reg_t ctrl_reg;
当我实际操作ctrl_reg.fields.enable的时候raw[0]也发生了对应的变化。
packed
我们之前在[[SV数据类型二:定宽数组]]中提到过合并数组,合并数组英文就是packed array,而packed实际上就是将struct中的数据变成一个整体,可以理解为将它们头尾相连
typedef struct packed {
logic [3:0] high; // 占据整体 [7:4] 位
logic [3:0] low; // 占据整体 [3:0] 位
} my_t;
my_t data;
assign data = 8'hAB; // 此时 data.high = 0xA, data.low = 0xB
实战要点
- 工作中可以这么用:在大型的项目中,如果用到了很多位宽相同的数据,用typedef整合一下,代码的可读性会更强
- 容易踩的坑:如果会对struct中的成员变量进行频繁访问,那就不要用packed,不然性能代价会比较大
一句话总结
使用合适的功能整合数据,让代码可读性更强
1721

被折叠的 条评论
为什么被折叠?



