Verilog LED闪烁代码ModelSim识别reg为数组而非向量及逻辑异常问询
问题排查结论
你遇到的所有问题均为代码逻辑错误,和ModelSim操作无关,具体原因和修复方案如下:
1. 复位赋值不符合预期的原因
核心是两个语法错误叠加:
- 你的代码中
else if (LEDStateCount == Freq);末尾多写了一个多余的分号,直接把条件判断和后面的begin...end块断开,后面的OFF <= 1'b0语句不属于任何条件分支,是always块里独立执行的语句,每一次触发always块都会执行。 - 同一个always块内对同一个reg做多次非阻塞赋值时,最后一次赋值生效。因此复位分支给
OFF赋的1会被最后独立执行的OFF <= 1'b0覆盖,自然和你预期的复位值不符。
2. 计数器不递增、类型显示的问题
- 类型显示是正常的:Verilog中
reg [27:0]这种写法定义的就是压缩数组(Packed Array),也就是你说的28位向量,ModelSim显示的28x1数组就是对应你定义的28位向量,属于工具的正常显示,不是错误。 - 计数器不递增是两个错误导致:
- 测试用例的复位信号没有释放:你测试用例里把
reset_拉低之后就一直保持低电平,电路永远处于复位状态,计数器会一直被赋值为0,自然不会递增。 - 就算复位释放,你当前的逻辑里计数器计到
Freq之后就没有赋值操作,会停在Freq值不会自动清零,也不会触发LED翻转,也无法实现循环闪烁的效果。
- 测试用例的复位信号没有释放:你测试用例里把
3. 累加值改为1后OFF无法初始化的原因
1默认是32位有符号整数,和28位的LEDStateCount运算时会发生位宽隐式转换,在复位未正确释放、加上前面的赋值冲突的情况下,部分仿真器会出现信号初始化异常,出现X态,表现为OFF无法正常初始化,本质还是前面的语法错误和测试用例错误导致的连锁反应。
修正后代码
主模块
module main( input wire clk, //100MHz input wire reset_, output LED1 //LED On/Off Two-States ); reg [27:0] LEDStateCount; //LED Counter - 28 Bit Stored reg OFF; //State of LED localparam [27:0] Freq=50000000; assign LED1 = OFF; always @(posedge clk or negedge reset_)begin if (!reset_)begin LEDStateCount <= 28'b0; //On startup, clear value OFF <= 1'b1; end else if (LEDStateCount < Freq)begin LEDStateCount <= LEDStateCount + 1'b1; //Accumulate to 50,000,000 end else begin // 计数到预设值后翻转LED,清零计数器 LEDStateCount <= 28'b0; OFF <= ~OFF; end end endmodule
测试用例
`timescale 1 ps/ 1 ps module testbenchsaveme(); reg clk; reg reset_; wire LED1; main i1 ( .LED1(LED1), .clk(clk), .reset_(reset_) ); initial begin #100000000 $stop; end always begin clk = 1'b0; #5000 clk = 1'b1; #5000; end initial begin reset_ = 1'b1; #100 reset_ = 1'b0; #200 reset_ = 1'b1; // 释放复位 end endmodule
内容的提问来源于stack exchange,提问作者JTH828
相关产品推荐
相关产品推荐

