You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SystemVerilog枚举索引关联数组打印异常及键值获取方法咨询

如何正确打印SystemVerilog关联数组的枚举键值对

问题描述

在SystemVerilog中声明了基于枚举类型的关联数组,预期的键值对输出为:

UART1 : 32'h0a00_0000
UART2 : 32'h0a00_1000
UART3 : 32'h0a00_2000
UART4 : 32'h0a00_3000

但实际打印结果中,所有地址值相同,且索引显示为整数而非枚举名称:

test7.m_uart_base_addr[00]=a000000
test7.m_uart_base_addr[01]=a000000
test7.m_uart_base_addr[02]=a000000
test7.m_uart_base_addr[03]=a000000

问题原因

  1. 地址偏移错误:UART_ADDRESS_RANGE被定义为16'h0000,导致每次地址偏移量为0,所有地址都等于基地址。
  2. 关联数组访问与打印错误:打印时使用整数i作为索引访问关联数组,且未使用枚举名称的格式符,导致无法显示枚举键的名称。

解决方法

1. 修正地址偏移宏定义

将UART_ADDRESS_RANGE改为16'h1000,确保每个UART地址偏移正确:

`define UART_ADDRESS_RANGE 16'h1000

2. 正确遍历并打印关联数组

有两种常用方式可以正确打印枚举键值对:

方式一:利用枚举的first()/next()遍历

initial begin      
    test7 = new();
    // 初始化关联数组
    ip_idx_e idx = ip_idx_e.first();
    for (int i=0; i<`NUM_OF_UART; i++) begin
      test7.m_uart_base_addr[idx] = `UART_BASE_ADDRESS + (i * `UART_ADDRESS_RANGE);
      idx = idx.next();
    end

    // 打印关联数组
    idx = ip_idx_e.first();
    do begin
      $display("%s : 32'h%08h", idx.name(), test7.m_uart_base_addr[idx]);
      idx = idx.next();
    end while(idx != ip_idx_e.first()); // 枚举循环结束条件
end

方式二:使用foreach遍历关联数组的键

initial begin      
    test7 = new();
    // 初始化关联数组
    ip_idx_e idx = ip_idx_e.first();
    for (int i=0; i<`NUM_OF_UART; i++) begin
      test7.m_uart_base_addr[idx] = `UART_BASE_ADDRESS + (i * `UART_ADDRESS_RANGE);
      idx = idx.next();
    end

    // 打印关联数组
    foreach(test7.m_uart_base_addr[key]) begin
      $display("%s : 32'h%08h", key.name(), test7.m_uart_base_addr[key]);
    end
end

完整修正代码

`define NUM_OF_UART 4      
`define UART_BASE_ADDRESS 32'h0A00_0000      
`define UART_ADDRESS_RANGE 16'h1000  // 修正偏移量

typedef enum {UART1, UART2, UART3, UART4} ip_idx_e;                                                               

class test7_c;              
  rand ip_idx_e ip_idx;    
  rand int temp;
  rand int arr[];         

  bit[31:0] m_uart_base_addr[ip_idx_e];      

  function int my_rand();                
    return std::randomize(arr) with {    
      unique {arr};                       
      arr.size() inside {[1:10]};        
      arr.sum() inside {[0:100]};        

      foreach(arr[i]) {
        arr[i] > 1;
        arr[i] < 100;
      }            
    };              
  endfunction      

  function void my_print();
    foreach(arr[i])
    $display("arr[%02d]=%02d", i, arr[i]);
  endfunction                                                     
endclass                                 

module dut;        

test7_c test7;    

initial begin      
    test7 = new();
    ip_idx_e idx = ip_idx_e.first();

    // 初始化关联数组
    for (int i=0; i<`NUM_OF_UART; i++) begin
      test7.m_uart_base_addr[idx] = `UART_BASE_ADDRESS + (i * `UART_ADDRESS_RANGE);
      if(idx != ip_idx_e.last()) begin
        idx = idx.next();
      end
    end

    // 打印关联数组(foreach方式)
    $display("=== 关联数组键值对 ===");
    foreach(test7.m_uart_base_addr[key]) begin
      $display("%s : 32'h%08h", key.name(), test7.m_uart_base_addr[key]);
    end
end                                                               
endmodule

输出结果

修正后会得到预期的打印内容:

=== 关联数组键值对 ===
UART1 : 32'h0a000000
UART2 : 32'h0a001000
UART3 : 32'h0a002000
UART4 : 32'h0a003000

内容的提问来源于stack exchange,提问作者bu-ral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:54:55