Yes, it is possible to program FPGA Block RAM connected to a Cortex-M0 processor using JTAG. JTAG provides a standard way to debug and program embedded systems and can be used to write data to Block RAM inside an FPGA fabric from an external JTAG host. Here is an overview of how it can be accomplished:
Overview of JTAG Interface
JTAG stands for Joint Test Action Group and defines a common protocol used for testing, debugging, and programming integrated circuits and boards after manufacture. The JTAG interface consists of a dedicated 4-pin or 5-pin port that provides a standard way to access internal components:
- TCK – Test Clock
- TMS – Test Mode Select
- TDI – Test Data In
- TDO – Test Data Out
- TRST – Test Reset (optional)
By shifting data on TDI and pulsing TCK, instructions can be sent to tell a device to switch into debug/programming mode. TDO can be used to read data back from the device. Using JTAG, you can halt and single-step through code, set breakpoints, and access internal registers and memory.
Connecting JTAG to Cortex-M0 and FPGA
For a Cortex-M0 processor and FPGA fabric on the same device, the JTAG interface will be connected to pins on both the processor and programmable logic. The ARM CoreSight architecture used in Cortex-M devices includes JTAG as part of its debug capability. Meanwhile, the FPGA portion will also expose a JTAG interface to allow programming of the fabric. Here are two common ways the JTAG can be connected:
- Separate JTAG Interfaces – The processor and FPGA logic may each have their own dedicated JTAG pins. This allows them to be programmed independently but requires two connectors on the board.
- Shared JTAG Interface – A single JTAG connector can be shared between the cores using an FPGA pin multiplexer controlled by a JTAG selector bit. This reduces pins but only one device can use JTAG at a time.
Accessing Block RAM via Cortex-M0 JTAG
Once connected, the Cortex-M0 JTAG interface can be used to program Block RAM in the FPGA fabric by leveraging the External Debug Interface (EDI). This allows an external host to access the processor’s internal peripheral buses via special debug register mappings. By configuring EDI, the JTAG host can:
- Halt and reset the Cortex-M0 core
- Map Block RAM addresses to EDI address space
- Write Block RAM by accessing EDI mapped addresses
- Resume Cortex-M0, allowing it to interact with programmed Block RAM
Software will need to run on Cortex-M0 to properly initialize interfaces to the Block RAM. But the actual RAM contents can be written over JTAG. The EDI mechanism provides efficient access without needing to process JTAG instructions in the Cortex-M0 itself.
Pros and Cons of Using Cortex-M0 JTAG
Compared to programming the FPGA logic directly, using the Cortex-M0 JTAG with EDI has some tradeoffs:
Pros:
- Allows FPGA and processor debugging over a single JTAG chain
- Cortex-M0 can initialize interfaces required to access Block RAM
- EDI provides quick mmap style access to Block RAM from host
- Software debug can be intermixed with Block RAM programming
Cons:
- Two-step process: halt core, write Block RAM, resume core
- EDI has limited address range (may need smaller Block RAM segments)
- Creates dependency on Cortex-M0 being initialized correctly
- No direct access to other FPGA resources like DSP blocks
Alternative of Using FPGA JTAG Directly
For complete flexibility and simplicity, the FPGA JTAG interface can be used directly to program all fabric resources. This treats the FPGA portion as an independent device from the processor:
- Halt Cortex-M0 core to prevent interference
- Directly access FPGA program/configuration logic via JTAG
- Write framing data and Bitstream to configure FPGA fabric
- Within Bitstream, initialize Block RAM contents
- Resume Cortex-M0 to interact with programmed FPGA
This approach avoids any dependency on the Cortex-M0 software state and provides lowest level access. However, the FPGA fabric may need to be re-initialized if the Cortex-M0 is reset/reprogrammed. The choice depends on the tradeoffs for a particular system.
Software Needed for Programming
To actually perform JTAG programming of Block RAM, appropriate host software tools are required. For the Cortex-M0 EDI method, a debug probe like SEGGER J-Link combined with GDB or OpenOCD can be used. For direct FPGA access, the FPGA vendor’s tools like Xilinx Vivado or Intel Quartus are needed. There are also some open source options like UrJTAG.
On the target device, the Cortex-M0 will need code to properly enable JTAG DEBUG mode, EDI peripheral access, and interfaces to the Block RAM. This can either be done in bootloader code or a debug stub if already deployed in flash. The FPGA itself requires no special on-board software.
Real-World Examples
This general approach of accessing FPGA resources via the Cortex-M JTAG/EDI is used in a variety of real applications. Some examples include:
- Xilinx Zynq SoCs – EDI allows programming the on-chip FPGA fabric from Cortex-A host processors
- Lattice iCE40 FPGAs – EDI used to initialize SB_RAM blocks when Cortex-M1 is on same die
- Cypress PSoC FPGAs – Connecting Cortex-M0 and FPGA fabric via EDI interface
For these platforms, software libraries and drivers are available to abstract the lower level JTAG/EDI implementation details from designers.
Conclusion
In summary, interfacing a Cortex-M0 processor and FPGA Block RAM via JTAG is certainly feasible by leveraging the EDI module or directly accessing FPGA JTAG. Hardware must connect JTAG correctly between the components while software initializes the cores and programs the Block RAM contents as needed. With the right tools and drivers, JTAG provides a flexible solution for debugging and programming the complete system.