[SV]SystemVerilog二维关联数组使用案例

本文介绍了SystemVerilog中二维关联数组的使用,包括两种声明方式:方案一为先定义子hash再放入大hash,方案二直接将子hash放入大hash。此外,还讨论了如何在仿真日志中利用Unix时间戳记录并分析任务执行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SystemVerilog二维关联数组使用案例

      摘要:二维的关联数组是一种非常重要的数据结构,在验证环境中用于保存一些特定的对象,用于检索和分析。本文会介绍一种二维关联数组的使用案例。关于SystemVerilog关联数组的基础知识,请参考以下博文:

  1. Systemverilog關聯數組

  2. SystemVerilog關聯數組查找方法

一、二维关联数组的声明 

       在SystemVerilog中,二维关联数组的声明有两种方法:

 1.1 方案一

  • 先定义一个子hash
  • 然后将子hash放入大的hash中
`timescale 1ns/1ps

module hdl_top();

  typedef time        cps_base_hash[string];
  cps_base_hash       task1_cps, task2_cps, task3_cpa;
  cps_base_hash       soc_cps_hash[string];

  initial begin
    task1_cps["begin_time"] = $time();
    task1_cps["end_time"]   = $time() + 'h1010;

    task2_cps["begin_time"] = $time() + 'h1010;
    task2_cps["end_time"]   = $time() + 'h2020;

    task3_cps["begin_time"] = $time() + 'h2020;
    task3_cps["end_time"]   = $time() + 'h3030;

    soc_cps_hash["task1_name"] = task1_cps;
    soc_cps_hash["task2_name"] = task2_cps;
    soc_cps_hash["task3_name"] = task3_cps;

    foreach(soc_cps_hash[key]) begin
      $display("task_name = %s, begin_time = %0d, end_time = %0d", key, soc_cps_hash[key]["begin_time"], soc_cps_hash[key]["end_time"]);
    end

    foreach(soc_cps_hash[x, y]) begin
      $display("First key is %s, second key is %s, value is %p", x, y, soc_cps_hash[x][y]);
    end
  end

endmodule

 1.2 方案二

  • 直接将子hash放入大hash中。
`timescale 1ns/1ps

module hdl_top();

  time              soc_cps_hash[string][string];

  initial begin
    soc_cps_hash["task1_name"]["begin_time"] = $time();
    soc_cps_hash["task1_name"]["end_time"]   = $time() + 'h1010;

    soc_cps_hash["task2_name"]["begin_time"] = $time() + 'h1010;
    soc_cps_hash["task2_name"]["end_time"]   = $time() + 'h2020;

    soc_cps_hash["task3_name"]["begin_time"] = $time() + 'h2020;
    soc_cps_hash["task3_name"]["end_time"]   = $time() + 'h3030;

    foreach(soc_cps_hash[key]) begin
      $display("task_name = %s, begin_time = %0d, end_time = %0d", key, soc_cps_hash[key]["begin_time"], soc_cps_hash[key]["end_time"]);
    end

    foreach(soc_cps_hash[x, y]) begin
      $display("First key is %s, second key is %s, value is %p", x, y, soc_cps_hash[x][y]);
    end
  end

endmodule

二、在仿真日志中记录物理时间

       在分析仿真效率的时候,怎么计算每个task执行了多少时间呢?这儿就涉及到计算2个时间差的问题。计算时间间隔,可以用Linux的时间戳(date +%s),将得到的数据写入文件,最后读回来作差即可。

       Unix时间戳(英文为Unix epoch, Unix time, POSIXme 或 Unix timestamp)是从1970年1月1日00:00:00(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。

function time get_physical_time();
  time        phy_time;
  integer     fptr;

  $system("date +%s > soc_cps_time.csv");

  fptr = $fopen("soc_cps_time.csv", "r");
  $fscanf(fptr, "%0d", phy_time);
  $fclose(fptr);

  $system("rm -rf soc_cps_time.csv");

  return phy_time;

endfunction : get_physical_time

### SystemVerilog二维数组使用方法 #### 1. 数组声明 在 SystemVerilog 中,可以通过指定多个维度来创建多维数组。对于二维数组而言,有两种主要形式:packed 和 unpacked。 - **Unpacked Array**: 外部维度是 unpacked 的,内部维度可以是 packed 或者 unpacked。 ```systemverilog logic [7:0] mem_unpacked[0:3]; ``` - **Packed Array**: 内部维度是 packed 的,外部维度可以是 packed 或者 unpacked。 ```systemverilog logic [3:0][7:0] mem_packed; ``` 上述两种方式都可以用来表示具有四个元素的一维数组,每个元素是一个 8-bit 宽度的数据[^3]。 #### 2. 初始化与赋值操作 初始化可以在定义时完成,也可以通过 `initial` 或其他过程语句来进行: ```systemverilog // 静态初始化 logic [7:0] static_init_array[0:3] = '{8'hFF, 8'hAA, 8'h55, 8'h0F}; // 动态初始化 always @(posedge clk) begin dynamic_init_array[0] <= 8'b1111_0000; end ``` 对于更复杂的结构如二维数组,则需注意内外层循环顺序以及边界条件: ```systemverilog module example_module ( input wire [3:0] input_data [0:3], output reg [3:0] output_data [0:3] ); initial begin : init_block integer i; for (i = 0; i < 4; i = i + 1) begin output_data[i] <= input_data[i]; end end endmodule ``` 这段代码展示了如何在一个模块内实现简单的数据传输功能,其中输入输出均为四行一列的二维数组[^2]。 #### 3. 访问单个元素或部分区域 访问特定位置上的单一数值非常直观;而如果想要获取某一部分连续的内容,则需要用到切片技术: ```systemverilog // 单元格读取/写入 output_data[row_index][col_index] <= some_value; // 行级处理 for (integer row = 0; row < ROWS; ++row) { // 对整行进行操作... } ``` 这里需要注意的是,在某些情况下可能还需要考虑端口方向性和信号类型的匹配问题[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元直数字电路验证

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值