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

求助:Verilog生成块中实现一次性变量索引的实例化代码修正

基于NI_TYPE参数正确实例化模块并分配索引

问题场景

已定义如下参数:

parameter int NI_TYPE[NUM_ROW][NUM_COL] = '{
  '{0, 1, 2},
  '{2, 1, 2},
  '{2, 1, 0}
};

需要根据NI_TYPE的值实例化axi_grid_mni(值为2)和axi_grid_sni(值为1)模块,要求mni_index和sni_index为静态一次性分配的索引,原生成块代码因Verilog生成块的并行执行逻辑无法实现预期的索引递增效果,现提供修正代码如下:

修正后的代码

// 预计算每种类型的实例总数
localparam int MNI_INSTANCE_COUNT = count_matching_type(NI_TYPE, 2);
localparam int SNI_INSTANCE_COUNT = count_matching_type(NI_TYPE, 1);

// 统计指定类型元素数量的函数
function int count_matching_type(int arr[NUM_ROW][NUM_COL], int target_val);
    int count = 0;
    for (int r = 0; r < NUM_ROW; r++) begin
        for (int c = 0; c < NUM_COL; c++) begin
            if (arr[r][c] == target_val) count++;
        end
    end
    count_matching_type = count;
endfunction

// 生成每个位置对应的MNI索引映射表
localparam int MNI_INDEX_MAP[NUM_ROW][NUM_COL] = generate_index_map(NI_TYPE, 2);
// 生成每个位置对应的SNI索引映射表
localparam int SNI_INDEX_MAP[NUM_ROW][NUM_COL] = generate_index_map(NI_TYPE, 1);

// 生成索引映射的函数
function int generate_index_map(int arr[NUM_ROW][NUM_COL], int target_val);
    int current_idx = 0;
    for (int r = 0; r < NUM_ROW; r++) begin
        for (int c = 0; c < NUM_COL; c++) begin
            if (arr[r][c] == target_val) begin
                generate_index_map[r][c] = current_idx;
                current_idx++;
            end else begin
                generate_index_map[r][c] = -1; // 标记非目标类型位置
            end
        end
    end
endfunction

// 模块实例化生成块
genvar row, col;
for (row = 0; row < NUM_ROW; row++) begin : gen_row
    for (col = 0; col < NUM_COL; col++) begin : gen_col
        if (NI_TYPE[row][col] == 2) begin : gen_mni
            axi_grid_mni #(
                .req_t  (mni_req_t),
                .resp_t (mni_resp_t)
            ) u_axi_grid_mni (
                .clk_i     (clk_i),
                .arst_ni   (arst_ni),
                .req_o     (mni_req_o[MNI_INDEX_MAP[row][col]]),
                .resp_i    (mni_resp_i[MNI_INDEX_MAP[row][col]])
            );
        end else if (NI_TYPE[row][col] == 1) begin : gen_sni
            axi_grid_sni #(
                .req_t  (sni_req_t),
                .resp_t (sni_resp_t)
            ) u_axi_grid_sni (
                .clk_i     (clk_i),
                .arst_ni   (arst_ni),
                .req_o     (sni_req_i[SNI_INDEX_MAP[row][col]]),
                .resp_i    (sni_resp_o[SNI_INDEX_MAP[row][col]])
            );
        end
        // 类型为0的位置无需实例化模块
    end
end

关键说明

  1. 原代码问题:Verilog的genvar是编译阶段的静态变量,生成块是并行展开而非顺序执行的,直接在生成块中对mni_index/sni_index自增会导致索引分配混乱,无法保证顺序和唯一性。
  2. 修正核心:通过编译阶段执行的函数,预先遍历NI_TYPE计算出每个位置对应的索引值,生成静态索引映射表,生成块仅需直接引用这些预计算的索引即可,确保索引一次性静态分配,无运行时修改。
  3. 额外优势:预计算的实例总数可用于后续总线信号的宽度定义(如mni_req_o的宽度可设为MNI_INSTANCE_COUNT),提升代码的可维护性。

内容的提问来源于stack exchange,提问作者Foez Ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:20:21