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

SystemVerilog测试平台:创建运行时确定位宽的logic数组

解决SystemVerilog运行时动态位宽数据类的队列存储问题

由于SystemVerilog的类参数必须在编译时确定,无法直接在运行时根据变量值实例化参数化类,我们可以通过基类多态+子类参数化封装的方式实现需求,既保留子类内部的packed logic类型,又能统一存储到队列中。

核心思路

  1. 定义抽象基类,包含位宽元数据和纯虚方法,屏蔽具体位宽的操作细节;
  2. 参数化子类继承基类,内部维护固定位宽的packed logic数组,实现基类的虚方法来完成数据的读写、转换;
  3. 队列存储基类句柄,运行时通过虚方法自动适配不同位宽的子类实现。

代码实现

1. 定义抽象基类

基类仅声明必要的元数据和接口,不涉及具体数据存储:

class MyBaseData;
    int bit_depth;
    metadata_type_t some_info_about_thedata;

    // 纯虚方法:写入指定索引的数据(bit数组格式)
    pure virtual function void set_data(int index, bit[] data_bits);
    // 纯虚方法:读取指定索引的数据(返回bit数组)
    pure virtual function bit[] get_data(int index);
    // 纯虚方法:打印指定索引的数据(调试用)
    pure virtual function void print_data(int index);
endclass

2. 实现参数化子类

子类根据编译时确定的位宽,维护packed logic数组,并实现基类的虚方法,完成bit数组与packed类型的转换:

class #(parameter BIT_DEPTH) MyData extends MyBaseData;
    logic [BIT_DEPTH-1:0] thedata [];

    function new(metadata_type_t md);
        super.bit_depth = BIT_DEPTH;
        super.some_info_about_thedata = md;
        this.thedata = new[md.thedatasize]; // 初始化动态数组长度
    endfunction

    virtual function void set_data(int index, bit[] data_bits);
        if(data_bits.size() != BIT_DEPTH) begin
            $error("[MyData#%0d] Data width mismatch: expected %0d bits, got %0d", BIT_DEPTH, BIT_DEPTH, data_bits.size());
            return;
        end
        // 将bit数组赋值给packed logic变量
        for(int i=0; i<BIT_DEPTH; i++) begin
            thedata[index][i] = data_bits[i];
        end
    endfunction

    virtual function bit[] get_data(int index);
        bit[] data_bits = new[BIT_DEPTH];
        // 将packed logic变量转换为bit数组
        for(int i=0; i<BIT_DEPTH; i++) begin
            data_bits[i] = thedata[index][i];
        end
        return data_bits;
    endfunction

    virtual function void print_data(int index);
        $display("[MyData#%0d] Index %0d: %0b", BIT_DEPTH, index, thedata[index]);
    endfunction
endclass

3. 队列存储与使用

队列存储基类句柄,运行时无需关心具体子类的位宽,直接通过虚方法操作数据:

// 定义存储基类句柄的队列
MyBaseData data_queue[$];

// 实例化不同位宽的子类并加入队列(编译时确定每个子类的BIT_DEPTH)
metadata_type_t md_8bit = '{thedatasize: 4}; // 假设元数据包含数组长度
metadata_type_t md_16bit = '{thedatasize: 2};
metadata_type_t md_24bit = '{thedatasize: 3};

data_queue.push_back(new MyData#(8)(md_8bit));
data_queue.push_back(new MyData#(16)(md_16bit));
data_queue.push_back(new MyData#(24)(md_24bit));

// 遍历队列操作数据
while(data_queue.size() > 0) begin
    MyBaseData mbd = data_queue.pop_front();
    
    // 读取并打印数据
    mbd.print_data(0);
    
    // 构造新数据并写入
    bit[] new_data = new[mbd.bit_depth];
    foreach(new_data[i]) new_data[i] = $random(); // 生成随机bit数据
    mbd.set_data(0, new_data);
    
    // 打印修改后的数据
    mbd.print_data(0);
end

方案优势

  • 子类内部保留了logic [BIT_DEPTH-1:0]的packed类型,符合原始需求;
  • 基类多态实现了位宽无关的操作,队列存储无需关注具体位宽;
  • 所有位宽相关的逻辑被封装在子类中,代码模块化且易维护;
  • 完全适配测试平台场景,无需考虑可综合性。

内容的提问来源于stack exchange,提问作者John M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:50:13