目录
简化数据
define RTL 层级路径
paremeter 定义参数
typedef 构建数据结构
数据类型
定宽数组
合并数组(属于定宽数组)
动态数组
>> << 流操作符
automatic/static的method/data
post_randomize
testbench的封装
`define TB_TOP top
`define RTL_WRAPPER `TB_TOP.ip_core
`define IP_ENGINE_TOP `RTL_WRAPPER.u_ips_engine_top// Register
// generate
// for(i=0;i<4;i=i+1)
// begin: VFX_REG // VF_REG[*]
// ip_vfx_reg u_vf_reg(.....)
// end
// endgenerate`define IP_VF0_REG `IP_ENGINE_TOP.VFX_REG[0].u_vf_reg
`define IP_VF1_REG `IP_ENGINE_TOP.VFX_REG[1].u_vf_reg
`define IP_VF2_REG `IP_ENGINE_TOP.VFX_REG[2].u_vf_reg`define SELECT_CHA(chx) (1 << (32'h + (chx))) // 左移
parameter CORE_ID = (32'h001);
parameter VF_REG = (32'h000);
parameter CTRL_1 = (VF_REG + 32'h2);
Verilog中`define、parameter、localparam三者的区别及举例
int //32bit 有符号 整数
typedef bit[31:0] unit; //32bit 无符号 整数
typedef int unsigned unit; //等效// struce 自定义类型
typedef struct {int a;byte b;int d;} my_struct_s;
my_struct_s st= '{32'haaaa_dddd,8'hbb,32'hbbbb_cccc};//合并结构的struct
typedef sturct packed {bit[31:4] rsv_31_4;bit[3:3] num_3;bit[2:2] num_2;bit[1:1] num_1;
} CTRL_Type;构建一个描述符结构
typedef struct packed {bit[127:0] __rsv__ ;bit[31:16] block_id;bit[15:9] block_size;bit[8:7] block_st;bit[6:0] block_o;
} BLOCK_Descriptor_Type; // _Type _t: typedef定义
BLOCK_Descriptor_Type de_1_s; // _s : struct类型
int value[5]; //value[0] value[1] .... value[4]
int value[0:4]; //效果一样多维数组
int num[4][3];
int num[0:3][0:2];多维数组的赋值int packed_size[4][2] = '{'{$urandom_range(32,128), $urandom_range(32,128},'{$urandom_range(32,128), $urandom_range(32,128},'{$urandom_range(32,128), $urandom_range(32,128},'{$urandom_range(32,128), $urandom_range(32,128}};
多维动态数组
1.
class block_gen;
rand bit[63:0] block_idx[][];function new();block_idx = new[4];foreach (block_idx[i]) beginblock_idx[i] = new[8]; endendfunctionfunction print();foreach(block_idx[i,j])$display("block_idx[%0d][%0d] = %064h",i,j,block_idx[i][j]);endfunction
endclass2.
Cust_Type mem_pkg [4][2][]; //4个lane,2个channel,不定个idxfor(int lae = 0; lae < 4; lae ++) beginfor(int chl = 0; chl < 2; chl ++) beginmem_pkg[lae][chl] = new[$urandom_range(10,128)]; // 动态数组的大小end
endforeach (mem_pkg[i,j,k]) begin // 多维度的foreach循环mem_pkg[i][j][k] = new(); // mem_pkg classassert(mem_pkg[i][j][k]).randomize());
end
流操作符 ( >> 从左往右展开 << 从右往左展开 )initial beginint h;bit [7:0] j[4] = '{8'ha,8'hb,8'hc,8'hd};bit [7:0] q,w,e,r;bit [7:0] k[4]; //非合并数组bit [3:0][7:0] m;//合并数组bit [7:0] dyna_a[];//动态数组h = { >> bit [7:0] {j}}; // {j} = '{8'ha,8'hb,8'hc,8'hd} h = 32'h0a0b0c0d{>> {q,w,e,r}} = j; {q,w,e,r} = { >> {j}}; // 也可以{>>{k}} = j; //正确k = {>>{j}}; //错误,k是非合并数组m = {>>{j}}; // m是合并数组{>>{m}} = j; {>> {dyna_a}} = j; //正确dyna_a = {>> {j}}; //正确{>>{dyna_a with [0:2]} = j;// with限制动态数组大小
endinitial begin//动态数组,队列,定宽数组也可以操作bit [7:0] data[];bit [63:0] value = 64'h12345678_11223344;data = {>> bit [7:0] {value}}; // data 为动态数组,此时不需要new()。{>> {data}} = value; // 一些仿真器这样写也可以, value不需要加 {} 。{>> {data}} = {<< {value}}; //也可以两边都使用流操作符
end// 动态数组与 struct自定义类型转换
initial beginbit [7:0] data[];typedef sturct packed {bit[31:4] rsv_31_4;bit[3:3] num_3;bit[2:2] num_2;bit[1:1] num_1;} CTRL_Type;CTRL_Type data_s = 32'haaaa_1234;data = {>> {data_s}};
end
//在module、program、interface、task和function之外声明的变量拥有静态的生命周期,即存在于整个仿真阶段
//automatic task内的变量默认是automatic类型
//class 中的task默认是automatic类型
//全局变量即伴随着程序执行开始到结束一直存在,例如module中的变量默认情况下全部为全局变量,用户也可理解为module中的变量由于在模拟硬件信号,所以它们是静态生命周期。
module test;initial beginfor(int i=0;i<3;i++) beginint a ; // static a[i] = 1;$display("a:%0b",i);endend
endmodulea:1
a:11
a:111module test;initial beginfor(int i=0;i<3;i++) beginautomatic int a ; // automatica[i] = 1;$display("a:%0b",i);endend
endmodulea:1
a:10
a:100
关于automatic和static, 这些在C语言中解释的更到位:
class c1;
rand int randnum;
int hist[$];
constraint cstr1 {randnum inside {[0:10]};};
constraint cstr2 {!(randnum inside {hist});};
function void post_randomize();hist.push_back(randnum);
endfunction
endclassmodule m1;initial begin
c1 i1;
i1 = new();repeat(10) beginassert(i1.randomize());$display("m1::proc2.i1 randnum %0d", i1.randnum);end
end
endmodule
module clock_gen( SysClk );output SysClk;
endmodulemodule dut_wrapper();dut u_DUT(clk (tb_top.clock) ## 不可以将wire clock 直接连接,要通过tb_top层次化引用);
endmodulemodule tb_top;wire clock; ## reg or wire ???clock_gen u_clock_gen(SysClk(clock)
);dut_wrapper u_dut_wrapper();endmodule
本文发布于:2024-01-27 20:36:15,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063589772491.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |