struct结构体可以用来定义格式相对固定的数据结构,无论验证环境还是设计代码中都可以用来组织固定格式的信息,比如module input/outpu、fifo出入队信息。最近也仔细学习了下,将之前没有关注过的细节汇总下。

先定义一个结构体,最简单的unpacked struct定义方式如下:

typedef struct{
    logic       ty, par;
    logic [3:0] id;
    logic [3:0] addr;
    integer     data;
} frame_info;
frame_info f1, f2[1:0];

细节1:结构体的花式赋值方式;

不得不说,结构体的赋值方式多种多样,比如说可以这样直接赋值:

f1.ty   = 1'b1;
f1.addr = 4'ha;
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f1.ty, f1.par, f1.id, f1.addr, f1.data);

还可以这样整体赋值:

f1 = '{'b0, 'b1, 'd3, 'd6, 'd20};
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f1.ty, f1.par, f1.id, f1.addr, f1.data);

还可以这样整个数组赋值,注意高位在前低位在后:

f2 = '{'{'b0, 'b1, 'd3, 'd6, 'd20}, '{'b1, 'b0, 'd2, 'd7, 'd40}};
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f2[1].ty, f2[1].par, f2[1].id, f2[1].addr, f2[1].data);

还可以这样按名称赋值,注意加default:

f1 = '{ty:'b1, par:'b0, data:'d52, default:'0};
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f1.ty, f1.par, f1.id, f1.addr, f1.data);

还可以按类型赋值,同样注意加default,但是例如logic[7:0]这种我想加进去报错了 :

f1 = '{logic:'1, integer:'d100, default:'0};
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f1.ty, f1.par, f1.id, f1.addr, f1.data);

你甚至可以混合乱炖赋值:

f1 = '{data:'hff, logic:'h1, default:'0};
$display("frame_info = %0d, %0d, %0d, %0d, %0d", f1.ty, f1.par, f1.id, f1.addr, f1.data);

细节2:默认struct是unpacked的,即地址空间并不连续;需要连续的地址空间,需要packed;

例如如下定义:

typedef struct{
    logic       ty, par;
    logic [3:0] id;
    logic [3:0] addr;
    logic [7:0] data;
} frame_upa;
typedef struct packed{
    logic       ty, par;
    logic [3:0] id;
    logic [3:0] addr;
    logic [7:0] data;
} frame_pac;
logic vr_data;
frame_upa f1 = '{'b0, 'b1, 'd3, 'd6, 'd20};
frame_pac f2 = '{'b1, 'b1, 'd5, 'd2, 'd80};

直接取值是没有问题的:

vr_data = f1.data;
vr_data = f2.data;

但是按照占位整体赋值会报错:

f1 = 18'h1F5;

对于packed类型来说,这些操作都是ok的:

f2 = 18'h1F5;
vr_data = f2[7:0];
vr_data = f2 >> 2;
视频语法学习:B站链接 笔记原地址:https://github.com/Tan-YiFan/DigitalLogic-Autumn2020/tree/syntax/syntax网络不好,可能打不开。 数字电路中,万物皆为二进制。 类型统一为logic,符合这一规律。但这对程序员,可能不太友好。 需要管理变量的位数 同一位数的信号,可能意义完全不同(1010可能是格雷码/正常数值) 对此,引入自定义 具体区别在于: 若 struct node{ }这样来定义 结构体 的话。在定义 node 的 结构体 变量时,需要这样写: struct node n; 若用 ty pe def ,可以这样写: ty pe def struct node{}NODE; 。在申请变量时就可以这样写:NODE n;其实就相当于 NODE 是nod... ty pe def 是类型定义的意思。 ty pe def struct 是为了使用这个 结构体 方便。 具体区别在于: 若 struct node {}这样来定义 结构体 的话。在申请node 的变量时,需要这样写, struct node n; 若用 ty pe def ,可以这样写, ty pe def struct node{}NODE; 。在申请变量时就可以这样写,NODE n; 区别就在于使用时,是否可以省去 struct 这... 首先,int* p;这个语句可以理解为int*是一个新的数据类型。 举一个相似的例子,一般指向整形的指针都是这样使用的: int p; //p是指向一个整型的指针。如果我们在前面使用了 ty pe def int Pint; 则上面的方法,可以改为:Pint p; 同样是声明一个指向整形的指针。 这样 ty pe def struct {…}* Pstr;就不难理解了,Pstr List;就是声明了一个指... 2.6.2 本节引言 给FPGA一个支点,它可以撬动整个数字逻辑。““给我一根杠杆我就能撬动地球”是古希腊数学家、物理学家阿基米德说的,这句话是阿基米德的经典语录,这句话还被翻译为“给我一个支点,我就能撬起整个地球”,用了夸张的方式来说明杠杆原理。” 2.6.3 表示定义了 结构体 struct Lnode,并且 struct Lnode等价于Lnode, struct Lnode *等价于LinkList。所以定义 结构体 变量可以采用 struct Ln... 数字硬件建模System Verilog - 结构体 (一) 结构体 结构体 用于将多个变量组合在一个通用名称下。设计通常具有逻辑信号组,例如总线协议的控制信号,或状态控制器内使用的信号。 结构体 提供了将这些相关变量捆绑在一起的方法。 结构体 中的所有变量都可以单个赋值,或者每个变量都可以单独赋值。 结构体 包可以复制到具有相同定义的另一个 结构体 ,并通过模块端口、任务或函数进出。 结构体 声明 结构体 ...