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

Verilog 4位计数器EPWave仿真异常:初始5秒未计数排查

4位计数器仿真初始不计数问题排查

我用Verilog编写了一个4位计数器模块,需在EPWave中实现以下仿真流程:时钟每1秒翻转一次;计数器先运行5秒,随后置复位,再运行12秒。已编写计数器模块及测试代码,但仿真显示初始5秒计数器完全不计数,请问问题出在哪里?

计数器模块代码

module contador_sequencial(
    input clk,
    input reset,
    output reg [3:0] count
);

  always@(posedge clk or posedge reset) begin
    if(reset) begin
      count <= 4'b0000;
    end else if (count == 4'b1001) begin
      count <= 4'b0000;
    end else begin
      count <= count + 1'b1;
    end
  end
endmodule

测试代码

module testbench;
  reg clk;
  reg reset;
  wire [3:0] count;
  
  contador_sequencial counter(.clk(clk), .reset(reset), .count(count));
  
  initial begin
    clk = 0;
    forever #1000 clk = ~clk;
  end
  
  initial begin
    $dumpfile("dump.vcd");
    $dumpvars;
    reset = 0;
    #5000
    reset = 1; 
    #1000 
    reset = 0;
    #12000 
    $finish;
  end
endmodule

仿真现象

初始5秒计数器未计数,对应波形图如下:
初始5秒计数器未计数波形


问题原因

核心问题有两个:

  1. 计数器寄存器未初始化:Verilog中reg类型变量默认初始值为未知态x。测试代码初始阶段reset=0,计数器进入else分支执行count <= count + 1'b1,但x + 1结果还是x,因此无论多少个时钟沿,count始终保持未知态,看起来完全没计数。
  2. 时间单位与预期不符:你期望时钟周期为1秒,但Verilog默认时间单位是1ns,测试代码中#1000实际代表1000ns(1us),#5000是5us,和你想要的“5秒”完全不是一个量级。不过这不是初始不计数的直接原因,但会导致仿真流程和预期时间线错位。

解决方法

方法1:初始化计数器寄存器

在计数器模块中给count显式设置初始值:

module contador_sequencial(
    input clk,
    input reset,
    output reg [3:0] count = 4'b0000 // 新增初始值
);

  always@(posedge clk or posedge reset) begin
    if(reset) begin
      count <= 4'b0000;
    end else if (count == 4'b1001) begin
      count <= 4'b0000;
    end else begin
      count <= count + 1'b1;
    end
  end
endmodule

方法2:测试代码开头先触发复位

在测试流程开始时先给一个复位脉冲,强制count初始化为0:

initial begin
  $dumpfile("dump.vcd");
  $dumpvars;
  reset = 1; // 先置复位
  #1000
  reset = 0; // 释放复位,开始计数
  #5000
  reset = 1; 
  #1000 
  reset = 0;
  #12000 
  $finish;
end

额外修正:匹配预期的时间单位

如果要让仿真时间和“秒”对应,需在代码开头添加时间单位定义,同时修正时钟周期:

`timescale 1s/1ms // 定义时间单位为1秒,精度1毫秒

module testbench;
  reg clk;
  reg reset;
  wire [3:0] count;
  
  contador_sequencial counter(.clk(clk), .reset(reset), .count(count));
  
  initial begin
    clk = 0;
    forever #0.5 clk = ~clk; // 每0.5秒翻转一次,实现1秒周期
  end
  
  initial begin
    $dumpfile("dump.vcd");
    $dumpvars;
    reset = 1;
    #1 // 复位1秒
    reset = 0;
    #5 // 运行5秒
    reset = 1; 
    #1 // 复位1秒
    reset = 0;
    #12 // 运行12秒
    $finish;
  end
endmodule

内容的提问来源于stack exchange,提问作者Arthur Araújo Rabelo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:20:37