The ARM Cortex-M1 processor is a popular choice for embedded and IoT applications due to its low cost and power efficiency. However, debugging Cortex-M1 designs on an FPGA can be challenging without access to the JTAG interface. This article will provide an overview of techniques to debug your Cortex-M1 FPGA implementation without relying on Virtual JTAG.
Challenges of Debugging Cortex-M1 on FPGA
Unlike ASIC implementations, debugging FPGA designs relies heavily on access to internal signals via the JTAG interface. The Cortex-M1 JTAG interface provides access to internal registers, breakpoint units, and other debug features. However, many low-cost FPGA boards do not expose the JTAG pins, forcing developers to find workarounds.
Without JTAG, observing internal signals and setting breakpoints is difficult. The Cortex-M1 does provide a two-pin SWD interface, but this does not give complete debug access. Workarounds must be implemented in the FPGA design to gain visibility into the processor operation.
Debugging with LEDs
A simple but effective workaround is using FPGA I/O pins to toggle LEDs on key internal signals. This provides a quick visual indication of program flow, execution of critical sections, or values of internal registers. For example, hooking up LEDs to the Cortex-M1’s sleep/active signal, interrupt requests, or instruction pipeline signals can give useful debug insights.
This LED-based debugging can be enhanced by controlling the LEDs with a small state machine, allowing signals to be encoded on a limited number of LEDs. For example, a 4-bit state machine would allow 16 internal signals to be displayed using just 4 LEDs. Limitations of this technique include only providing debug visibility when signals are toggling. Static values are not displayed.
Debugging with Waveforms
For greater visibility into processor behavior, internal signals can be routed to FPGA I/Os connected to an external logic analyzer or oscilloscope. This allows waveforms to be captured showing timing relationships, stalls, and value changes in registers or memory. Waveform captures are invaluable for identifying issues like pipeline stalls, cache misses, interrupt latency, and more.
To implement this, route the Cortex-M1 trace port and up to 32 additional internal signals to FPGA pins. Connect these to an external logic analyzer using probes or a header. Control signals like interrupts and processor modes are useful waveforms to start with. In some cases, a simple threshold trigger on an error signal may be enough to capture a failure event.
Adding Custom Logic for Debug
For more advanced debugging, custom logic can be built into the FPGA to monitor Cortex-M1 operation. This debug logic connects to internal processor buses and pipelines to extract additional data. For example, a debug module can track memory accesses, record ordered program traces, log performance counters, or filter on specific conditions.
Debug logic like this requires understanding the Cortex-M1 internals to tap into key internal buses and pipelines. This additional logic also consumes FPGA resources which may be limited. Lightweight probing of critical processor events is recommended over attempting to log everything. Focus debug instrumentation on likely issues areas or failure scenarios.
Debugging Code with Simulated JTAG
While not a complete JTAG replacement, simulated JTAG can provide enough functionality to debug code. This technique uses the SWD interface to load a custom debug monitor program into Cortex-M1 internal RAM. The debug monitor uses the Cortex-M1 Debug Access Port (DAP) to access registers, memory, and debug units internally.
From the FPGA, developers can communicate with this debug monitor via UART or custom logic. Commands can be sent to read/write memory, set breakpoints, single-step instructions, or halt the core. More advanced monitors can trace instruction execution, record registers, or filter data. This provides debug capabilities without requiring the Cortex-M1 JTAG pins.
Using Platform Level Debug Features
Some FPGA development boards include additional debug features that can be leveraged. For example, some boards have FPGA logic analyzers built-in, or high-speed serial tracing interfaces. Look for FPGA-side debug resources that may already be available before adding custom instrumentation logic.
For example, Xilinx FPGAs feature ChipScope debug cores that capture internal signals without needing physical I/O pins. Intel FPGAs offer Signal Tap for analyzing internal logic. And Lattice FPGAs have the iCE40 Logic Analyzer built-in. Leverage these platform-level solutions if available.
Debugging with Simulator Testbenches
Finally, for system-level and integration testing, simulate the Cortex-M1 FPGA design with a testbench in your HDL simulator. Drive stimulus to the processor and monitor its responses. A testbench can inject simulated data from sensors or other system inputs and validate the FPGA design’s behavior.
While not actual silicon debug, simulation provides valuable verification of your FPGA implementation of the Cortex-M1. Testbenches can simulate corner cases, errors, interrupts, and varied operating environments. Catch design flaws early before debugging on hardware.
Recommendations for Cortex-M1 FPGA Debugging Without JTAG
To summarize, here are some recommendations when debugging your Cortex-M1 FPGA design without access to Virtual JTAG:
- Instrument the design with LEDs on key internal signals for basic debugging.
- Capture waveforms using an external logic analyzer or oscilloscope.
- Build custom debug logic in the FPGA to extract additional processor data.
- Load a debug monitor via SWD to access registers, memory, and debug resources.
- Use platform-level FPGA debug features like internal signal probes.
- Validate the design with comprehensive testbenches in simulation.
While not as easy as using a full JTAG debugger, these techniques can provide meaningful visibility into your Cortex-M1 FPGA implementation without significant hardware changes. With careful instrumentation and creative use of the limited interfaces available, you can work around the lack of JTAG access for debugging needs.
Conclusion
Debugging Cortex-M1 designs running on FPGAs without JTAG is certainly challenging but possible using the right techniques. Instrument the design with debug logic built into the FPGA fabric to gain visibility on internal processor signals. Leverage simulation testbenches to validate behavior. And use LEDs, waveforms, and other creative solutions to tap into key points and monitor processor execution.
With the workarounds outlined in this article, developers can take on Cortex-M1 FPGA projects even without full JTAG debug access. While not ideal, these techniques can provide sufficient insights to analyze bugs, performance issues, and design flaws during the development process.