Function SystemVerilog/Verilog:有没有办法找到压缩结构字段的整数位偏移量?
我想知道verilog或systemverilog中是否有一个标准函数可以返回压缩结构中某个字段的位偏移量。例如,请参见下面假设函数$find\u field\u offset的使用:Function SystemVerilog/Verilog:有没有办法找到压缩结构字段的整数位偏移量?,function,struct,verilog,offset,system-verilog,Function,Struct,Verilog,Offset,System Verilog,我想知道verilog或systemverilog中是否有一个标准函数可以返回压缩结构中某个字段的位偏移量。例如,请参见下面假设函数$find\u field\u offset的使用: typedef struct packed { logic [31:0] field_1, logic [15:0] field_2, logic [63:0] field_3 } struct_type; struct_type the_struct; int field_1_offs
typedef struct packed
{
logic [31:0] field_1,
logic [15:0] field_2,
logic [63:0] field_3
} struct_type;
struct_type the_struct;
int field_1_offset;
assign field_1_offset = $find_field_offset(the_struct.field_1);
谢谢 如果有一个函数以您提供的形式返回这个值,那就没有什么意义了。原因是这里没有任何变量。您只需将一个值传递给该方法,编译器就无法确定您想要在
struct\u type
中获取field1
的偏移量
使用nativeSystemVerilog可以做的最好的事情是定义自己的函数,该函数基于枚举参数返回偏移量。不经意间:
typedef enum { FIELD1, FIELD2, FIELD3 } struct_type_fields_e;
function int unsigned get_offset(struct_type_fields_e field);
case (field)
FIELD1 : return 0;
FIELD2 : return 32;
FIELD3 : return 48;
endcase
endfunction
您可能可以使用一些VPI代码做更多的工作,但是您需要更改调用函数的方式。如果您可以使用VPI,那么您可以通过一点类型自省来做您想要做的事情。这样做的问题是,您不能以自己喜欢的方式调用函数,因为据我所知,编译器会丢失
field1
实际的上下文。我的意思是,函数会看到一个逻辑向量值,但不知道它来自结构
如果您同意将函数调用更改为:
$find_field_offset(the_struct, "field1"); // note "field1" in quotes
然后,从技术上讲,可以计算出结构类型是struct\u type
,并在其所有字段上循环,找到名为“field1”
的字段,并返回该字段的偏移量
使用VPI代码的问题在于,对VPI对象模型的支持因供应商而异。您必须幸运地使用一家支持我们这里需要的功能的供应商。这可能不是一个好的、方便的方法。但这是本机SV代码,用于在
struct\u type
function automatic int get_offset_struct_type_field_1;
struct_type x = '0;
x.field_1 = '1;
for (integer i = 0; i < $bits(x); i=i+1) begin
if (x[i] == 1) return i;
end
endfunction
函数自动int-get\u-offset\u-struct\u-type\u-field\u 1;
结构类型x='0;
x、 字段_1='1;
对于(整数i=0;i<$bits(x);i=i+1)开始
如果(x[i]==1)返回i;
结束
端功能
谢谢您的示例。下面是一些迂腐的检查和消息传递,以确认某些层次结构的所有字段的偏移量和大小。char_idx是结构中半字节的字符位置,如果从$writememh或类似文件中读取为字符串。在初始块内调用此taks,以确认下游解析将能够正确解释十六进制表示
task report_offsets(
);
phy_mon_info_s tr;
integer char_idx;
$display("tr is made of %0d bits",$bits(tr));
for (integer idx = 0;idx< $bits(tr);idx++) begin
char_idx = ($bits(tr) - idx - 1) >> 2;
tr = 1'b1 << idx;
if (|tr.inst > 0) $display("tr.inst claims bit %0d hex char %0d" ,idx, char_idx);
if (|tr.clock_count) $display("tr.clock_count claims bit %0d hex char %0d" ,idx, char_idx);
if (|tr.phy_info.dir) $display("tr.phy_info.dir claims bit %0d hex char %0d" ,idx, char_idx);
if (|tr.phy_info.data_type) $display("tr.phy_info.data_type claims bit %0d hex char %0d" ,idx, char_idx);
for (int inner = 0;inner< PHY_MON_FRAME_DWS;inner++) begin
if (|tr.phy_info.header[inner]) $display("tr.phy_info.header[%0d] claims bit %0d hex char %0d",inner,idx, char_idx);
end
if (|tr.phy_info.payload_dws) $display("tr.phy_info.payload_dws claims bit %0d hex char %0d",idx, char_idx);
if (|tr.phy_info.prim) $display("tr.phy_info.prim claims bit %0d hex char %0d" ,idx, char_idx);
if (|tr.phy_info.num_prims) $display("tr.phy_info.num_prims claims bit %0d hex char %0d" ,idx, char_idx);
if (|tr.phy_clock) $display("tr.phy_info.phy_clk claims bit %0d hex char %0d" ,idx, char_idx);
end
assert($bits(tr.inst ) % 4 == 0) else $error("total bits in tr.inst %0d is not a multiple of 4!",$bits(tr.inst ));
assert($bits(tr.clock_count ) % 4 == 0) else $error("total bits in tr.clock_count %0d is not a multiple of 4!",$bits(tr.clock_count ));
assert($bits(tr.phy_info.dir ) % 4 == 0) else $error("total bits in tr.phy_info.dir %0d is not a multiple of 4!",$bits(tr.phy_info.dir ));
assert($bits(tr.phy_info.data_type ) % 4 == 0) else $error("total bits in tr.phy_info.data_type %0d is not a multiple of 4!",$bits(tr.phy_info.data_type ));
assert($bits(tr.phy_info.header ) % 4 == 0) else $error("total bits in tr.phy_info.header %0d is not a multiple of 4!",$bits(tr.phy_info.header ));
assert($bits(tr.phy_info.payload_dws ) % 4 == 0) else $error("total bits in tr.phy_info.payload_dws %0d is not a multiple of 4!",$bits(tr.phy_info.payload_dws ));
assert($bits(tr.phy_info.prim ) % 4 == 0) else $error("total bits in tr.phy_info.prim %0d is not a multiple of 4!",$bits(tr.phy_info.prim ));
assert($bits(tr.phy_info.num_prims ) % 4 == 0) else $error("total bits in tr.phy_info.num_prims %0d is not a multiple of 4!",$bits(tr.phy_info.num_prims ));
assert($bits(tr.phy_clock ) % 4 == 0) else $error("total bits in tr.phy_clock %0d is not a multiple of 4!",$bits(tr.phy_clock ));
assert($bits(tr ) % 4 == 0) else $error("total bits in tr %0d is not a multiple of 4!",$bits(tr ));
endtask
任务报告\u(
);
物理信息系统tr;
整数字符idx;
$display(“tr由%0d位组成,$bits(tr));
对于(整数idx=0;idx<$bits(tr);idx++)开始
char_idx=($bits(tr)-idx-1)>>2;
tr=1'b1 0)$显示(“tr.inst声明位%0d十六进制字符%0d”,idx,字符idx);
if(| tr.clock_count)$display(“tr.clock_count声明位%0d十六进制字符%0d”,idx,char_idx);
if(| tr.phy_info.dir)$display(“tr.phy_info.dir声明位%0d十六进制字符%0d”,idx,char_idx);
if(| tr.phy_info.data_type)$display(“tr.phy_info.data_type声明位%0d十六进制字符%0d”,idx,字符idx);
对于(int-inner=0;inner
对于字段_1和字段_2,您希望假设函数返回什么?0和32?