Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function SystemVerilog/Verilog:有没有办法找到压缩结构字段的整数位偏移量?_Function_Struct_Verilog_Offset_System Verilog - Fatal编程技术网

Function SystemVerilog/Verilog:有没有办法找到压缩结构字段的整数位偏移量?

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

我想知道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_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?