设计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
相关产品推荐
相关产品推荐

