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
resetport ofclk_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_divnuses 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 brokenclk_outsignal that kills the bit bouncer’s clock. - Bit Bouncer Needs Reset Too: You set initial values for
bouncer_outanddirection, but SRAM-based FPGAs like the one on DE10-Nano don’t retain initial values on power-up. Add a reset input tobit_bouncerto 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
locksignal 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’sNparameter 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 (=) forbouncer_outand a non-blocking assignment (<=) fordirection. Blocking assignments update values immediately in the same clock cycle, so whenbouncer_outhits8'b10000000, the blocking assignment shifts it right first, thendirectionchecks the already-updated value instead of the original8'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_outis mapped to the correct DE10-Nano LED pins (usually labeledLED[0]toLED[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
- First, test the
clk_divnalone: Hook itsclk_outto an LED and verify it’s blinking at the expected rate. - Add the PLL lock signal as an enable for both modules to ensure they only run when the clock is stable.
- Implement the reset fixes and re-synthesize the design.
- Finally, test the full bit bouncer circuit.
内容的提问来源于stack exchange,提问作者Zacharie McCormick
相关产品推荐
相关产品推荐

