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

基于Basys3的Verilog LED序列仿真:步进变化缺失问题求助

LED移位序列仿真问题修复

需求描述

当输入sw=0(对应内部变量x=0)时,LED需执行以下左移序列:

0000000000000001
0000000000000010
0000000000000100
0000000000001000
0000000000010000
0000000000100000
0000000001000000
0000000010000000
0000000100000000
0000001000000000
0000010000000000
0000100000000000
0001000000000000
0010000000000000
0100000000000000
1000000000000000

当sw=1时,LED序列反向执行右移操作。目前已实现main主模块、zaman计时子模块及testbench测试代码,但仿真时LED向量始终为固定值,未出现预期的步进移位变化。

问题代码分析与修复

1. zaman计时模块问题

原模块使用电平敏感的always @(state)块生成秒脉冲,且采用阻塞赋值,导致sec信号时序异常(持续时间过长或触发时机错误),无法正确触发主模块的移位逻辑。

修复后的zaman模块代码:

`timescale 1ns / 1ps

module zaman(
    output reg Y,
    input clock,
    input reset
);

reg [25:0] state;

always @(posedge clock) begin
    if (reset == 1) begin
        state <= 0;
        Y <= 0;
    end else begin
        if (state == 50000000) begin
            state <= 0;
            Y <= 1; // 生成单时钟周期的秒脉冲
        end else begin
            state <= state + 1;
            Y <= 0;
        end
    end
end

endmodule

修复说明:

  • 将秒脉冲生成逻辑整合到时钟边沿触发的always块中,确保Y(即主模块的sec信号)是单时钟周期的高电平脉冲,准确触发移位操作。
  • 移除冗余的电平敏感always块,避免时序竞争。

2. main主模块问题

  • 复位逻辑使用阻塞赋值,违反时序电路设计规范,导致复位动作不可靠。
  • 移位后立即判断ovr值,由于非阻塞赋值的特性,此时ovr仍为旧值,无法正确触发循环复位逻辑。

修复后的main模块代码:

`timescale 1ns / 1ps

module main(
    output [15:0] led,
    input clk,
    input btnC,
    input sw
);

reg [15:0] state;
reg x;
wire sec;

zaman timer (sec, clk, btnC);

initial begin
    state = 16'b0000000000000001;
    x = 0;
end

always @ (posedge clk) begin
    x <= sw;
    
    if (btnC == 1) begin
        state <= 16'b0000000000000001; // 非阻塞赋值,符合时序规范
    end
    else if (sec == 1) begin
        if (x == 0) begin
            // 左移到最后一位时,重置为初始值
            state <= (state == 16'b1000000000000000) ? 16'b0000000000000001 : (state << 1);
        end
        else if (x == 1) begin
            // 右移到最后一位时,重置为最高位初始值
            state <= (state == 16'b0000000000000001) ? 16'b1000000000000000 : (state >> 1);
        end
    end
end

assign led = state;

endmodule

修复说明:

  • 复位逻辑改用非阻塞赋值,确保时序正确性。
  • 移除冗余的ovr变量,直接通过判断当前state值实现循环移位,避免非阻塞赋值的时序延迟问题。
  • 简化移位逻辑,提升代码可读性与可靠性。

3. Testbench仿真时间问题

原Testbench仅仿真160ms,远小于完成16次移位所需的8秒(50000000个时钟周期×10ns周期×16次=8e9ns=8s),导致无法观察到移位变化。

修复后的Testbench代码:

`timescale 1ns / 1ps

module maintb;

reg clk;
reg btnC;
reg sw;
wire [15:0] led;
    
main uut(.led(led), .btnC(btnC), .sw(sw), .clk(clk));

always #5 clk = ~clk; // 10ns时钟周期

initial begin
    clk = 0;
    btnC = 0;
    sw = 0;
    
    // 复位操作
    btnC = 1;
    #10;
    btnC = 0;
    
    // 仿真足够长时间,覆盖16次移位(8秒)
    #8000000000;
    $finish;
end

endmodule

修复说明:

  • 延长仿真时间至8秒,确保能观察到完整的移位序列。
  • 添加$finish命令,避免仿真无限持续。

验证说明

修复后重新仿真,LED向量会按照预期每秒执行一次移位操作,左移到最高位后自动重置为最低位,右移同理。若需快速验证,可将zaman模块中的计数阈值50000000改为50000,将仿真时间缩短至80ms即可观察到完整序列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 01:17:33