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
问题原因
- 地址偏移错误:
UART_ADDRESS_RANGE被定义为16'h0000,导致每次地址偏移量为0,所有地址都等于基地址。 - 关联数组访问与打印错误:打印时使用整数
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
相关产品推荐
相关产品推荐

