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

ModelSim仿真正常但DE10-Nano FPGA运行失败,求问题排查

Hey there! Let's dig into why your bit bouncer isn't working on the DE10-Nano even though simulations look perfect. I’ve gone through your code and common FPGA board bring-up pitfalls, so here are the key areas to check and fix:

1. Reset Signal: The Most Overlooked Culprit

Your clk_divn module has a reset input, but there’s no mention of how you’re handling it on the board:

  • Board Reset Connection: Make sure you’ve tied the DE10-Nano’s reset key (usually KEY0) to the reset port of clk_divn. Also, add a debounce circuit for the key—mechanical buttons have bounce, which can cause messy reset pulses that the FPGA doesn’t interpret correctly.
  • Asynchronous vs Synchronous Reset: Your clk_divn uses asynchronous reset, but in practice, synchronous resets (tied to the clock edge) are more reliable for FPGAs. If the reset isn’t properly triggered, your counters might not initialize, leading to a broken clk_out signal that kills the bit bouncer’s clock.
  • Bit Bouncer Needs Reset Too: You set initial values for bouncer_out and direction, but SRAM-based FPGAs like the one on DE10-Nano don’t retain initial values on power-up. Add a reset input to bit_bouncer to force the initial state when the board powers on or resets.

2. Clock Chain: PLL & Divider Checks

You mentioned using an internal PLL followed by clk_divn:

  • PLL Lock Status: Always tie the PLL’s lock signal into your design—if the PLL isn’t locked, the clock output is unstable or incorrect. Use this lock signal to enable your modules only after the clock is stable.
  • PLL Frequency Configuration: Double-check that your PLL is outputting the frequency you expect. The DE10-Nano uses a 50MHz crystal; if your PLL outputs, say, 100MHz instead of 50MHz, your clk_divn’s N parameter will produce a clock that’s twice as fast (or slow) as intended—fast enough that LEDs look like they’re always on, or slow enough that you’d wait minutes for a shift.
  • clk_divn Logic Flaw: Your current divider uses both posedge and negedge counters, which can introduce timing issues on the board. A simpler, more reliable approach is to use a single posedge counter and flip the output when the counter hits half of N. This ensures a clean 50% duty cycle clock.

3. Bit Bouncer Logic: Blocking vs Non-Blocking Assignment Bug

This is a classic gotcha that often slips past simulations but breaks on hardware:

  • In your always @(posedge clock) block, you use a blocking assignment (=) for bouncer_out and a non-blocking assignment (<=) for direction. Blocking assignments update values immediately in the same clock cycle, so when bouncer_out hits 8'b10000000, the blocking assignment shifts it right first, then direction checks the already-updated value instead of the original 8'b10000000. This breaks the direction flip logic.
  • Fix this by using non-blocking assignments for both signals—this ensures all updates happen at the end of the clock cycle, matching how hardware actually behaves.

4. I/O Pin Assignment: Are LEDs Connected?

It sounds obvious, but it’s easy to miss:

  • Open Quartus’s Pin Planner and confirm each bit of bouncer_out is mapped to the correct DE10-Nano LED pins (usually labeled LED[0] to LED[7]).
  • Verify the pin voltage standard is set to 3.3V LVCMOS—this is the default for DE10-Nano’s GPIO, but it’s worth double-checking.

Fixed Code Examples

Here’s the corrected bit_bouncer with reset and proper non-blocking assignments:

module bit_bouncer(clock, reset, enable, bouncer_out); 
input clock;
input reset;
input enable;
output reg [7:0] bouncer_out;

reg direction;

always @ (posedge clock or posedge reset) begin
    if(reset) begin
        bouncer_out <= 8'b00000001;
        direction <= 1'b0;
    end else if(enable) begin
        bouncer_out <= direction ? (bouncer_out >> 1) : (bouncer_out << 1);
        direction <= (bouncer_out == 8'b10000000) ? 1'b1 : 
                     (bouncer_out == 8'b00000001) ? 1'b0 : 
                     direction;
    end
end
endmodule

And a simplified, more reliable clk_divn:

module clk_divn #(
    parameter WIDTH = 20,
    parameter N = 1000000)
(clk, reset, clk_out);
input clk;
input reset;
output reg clk_out;

reg [WIDTH-1:0] count;

always @(posedge clk) begin
    if (reset) begin
        count <= 0;
        clk_out <= 1'b0;
    end else begin
        if (count == N-1) begin
            count <= 0;
            clk_out <= ~clk_out;
        end else begin
            count <= count + 1;
        end
    end
end
endmodule

Troubleshooting Steps to Follow

  1. First, test the clk_divn alone: Hook its clk_out to an LED and verify it’s blinking at the expected rate.
  2. Add the PLL lock signal as an enable for both modules to ensure they only run when the clock is stable.
  3. Implement the reset fixes and re-synthesize the design.
  4. Finally, test the full bit bouncer circuit.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:33:15