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

设计17位异步递增计数器遇运行时致命错误:范围宽度表达式需为正

解决Active HDL中17位异步递增计数器的运行时错误

我用上升沿触发D触发器设计17位异步递增计数器,代码编译无错误,但在Active HDL中初始化仿真时触发运行时致命错误:Range width expression must be positive,错误指向D触发器实例化的代码行。

原代码如下:

`timescale 1us/ 1ns 

module upcounter (clk, pr, clr, out);
    input wire clk;
    input wire pr;
    input wire clr;
    output wire [16:0] out;
    
    wire [16:0] fb;
    wire [16:0] i_wire;
    
    genvar i;

    generate
    for (i = 0; i<17; i++) begin
        if (i == 0)begin
            dff d[i] (.clk(clk),.pr_b(pr),.clr_b(clr),.d(fb[i]),.q_b(fb[i]),.q(i_wire[i]));
        end else begin 
            dff d[i] (.clk(fb[i-1]),.pr_b(pr),.clr_b(clr),.d(fb[i]),.q_b(fb[i]),.q(i_wire[i]));
        end
        assign out[i] = i_wire[i];
    end
    endgenerate
endmodule

错误原因

问题出在dff d[i]的写法上:在generate循环内实例化模块时,Active HDL会将d[i]解析为创建一个宽度为i的实例数组。当i=0时,数组宽度为0,触发了"Range width expression must be positive"的错误。

两种修正方案

方案一:提前声明实例数组

先在generate块外声明完整的dff实例数组,再在循环内绑定每个实例的端口:

`timescale 1us/ 1ns 

module upcounter (clk, pr, clr, out);
    input wire clk;
    input wire pr;
    input wire clr;
    output wire [16:0] out;
    
    wire [16:0] fb;
    wire [16:0] i_wire;
    
    genvar i;
    // 提前声明17个dff实例的数组
    dff d[16:0];

    generate
    for (i = 0; i<17; i++) begin
        if (i == 0)begin
            // 为数组第i个元素绑定端口
            assign d[i].clk = clk;
            assign d[i].pr_b = pr;
            assign d[i].clr_b = clr;
            assign d[i].d = fb[i];
            assign fb[i] = d[i].q_b;
            assign i_wire[i] = d[i].q;
        end else begin 
            assign d[i].clk = fb[i-1];
            assign d[i].pr_b = pr;
            assign d[i].clr_b = clr;
            assign d[i].d = fb[i];
            assign fb[i] = d[i].q_b;
            assign i_wire[i] = d[i].q;
        end
        assign out[i] = i_wire[i];
    end
    endgenerate
endmodule

方案二:使用唯一实例名

在循环内为每个D触发器生成唯一的实例名称(避免数组索引写法):

`timescale 1us/ 1ns 

module upcounter (clk, pr, clr, out);
    input wire clk;
    input wire pr;
    input wire clr;
    output wire [16:0] out;
    
    wire [16:0] fb;
    wire [16:0] i_wire;
    
    genvar i;

    generate
    for (i = 0; i<17; i++) begin
        if (i == 0)begin
            // 直接用固定名称命名第一个实例
            dff d_0 (.clk(clk),.pr_b(pr),.clr_b(clr),.d(fb[0]),.q_b(fb[0]),.q(i_wire[0]));
        end else begin 
            // 用循环变量i生成唯一实例名d_1到d_16
            dff d_`i (.clk(fb[i-1]),.pr_b(pr),.clr_b(clr),.d(fb[i]),.q_b(fb[i]),.q(i_wire[i]));
        end
        assign out[i] = i_wire[i];
    end
    endgenerate
endmodule

说明

两种方案都能解决Active HDL的解析问题,核心是避免在循环内动态声明宽度为i的实例数组。异步递增计数器的逻辑本身是正确的:每个D触发器的D端接Q非,低位Q非作为高位时钟,实现异步翻转计数。

内容的提问来源于stack exchange,提问作者MD. SHAZZAD HOSSAIN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:27:08