Forum Discussion

m_tanoue's avatar
m_tanoue
Icon for New Member rankNew Member
22 hours ago

About writing JBC files using altera-stapl

We are currently attempting to update the FPGA on a MAX 10 (10M16SCU169I7G) from the SoM using a JBC file written via altera-stapl, which is based on jamplayer. However, the programming process is failing.

From the log, the following messages appear at the end, and it seems that the process terminates as an unrecognized device after the “No SLD node” detection:

No SLD node

Unrecognized device

Exit code = 6... Unrecognized device

Program took 15.000000 seconds to execute.

We are using Quartus Prime Lite 25.1 to create the JBC file.

The JBC file is created by converting a POF file generated by Quartus into a JAM file using Quartus Programmer, then adding one line of source code to the JAM file, and finally converting it into JBC using quartus_jbcc.exe.

Could this mean that there is something wrong with the way the JBC file is generated?

When we create a JBC file from an SOF file using the same procedure, programming succeeds, so we believe there may not be an issue with the JBC file generation method itself.

Since altera-stapl is relatively old, could there be compatibility issues with Quartus as well?
If so, which Quartus version or earlier should we use?

1 Reply

  • Farabi_Altera's avatar
    Farabi_Altera
    Icon for Regular Contributor rankRegular Contributor
    Good question — let me work through the failure modes systematically based on what's documented for MAX 10 JBC/JAM programming.  

    The core issue: POF-based JBC vs. SOF-based JBC for MAX 10

      

    The fact that your SOF-derived JBC succeeds but your POF-derived JBC fails is a very important clue. For MAX 10, programming the internal flash (CFM) via a POF uses the real-time ISP (in-system programming) flow, which has specific requirements that JTAG configuration from a SOF does not.

      

    Most likely root cause: DO_REAL_TIME_ISP not set in the generated JBC

      

    There is a documented issue where JAM/JBC files generated for MAX 10 devices do not contain the DO_REAL_TIME_ISP option. This problem is specifically seen when other FPGA devices are in a JTAG chain with MAX 10, and is due to incorrect formatting in Quartus Prime Software when converting the programming file to JBC or JAM.

      

    When the real-time ISP option is missing or incorrectly set in the JBC, the Jam player can fail with an "Unrecognized device" / Exit code = 6 error — which matches exactly what you're seeing.

      

    There is also a separate but related issue: when a MAX 10 FPGA is blank (new device, or UFM and CFM erased), the JAM player cannot program it successfully and returns "Exit code=10, Device programming failure". This is because the real-time ISP feature is turned on when the device is not in user mode. To fix this, use the JAM player command to disable the real-time ISP feature and program again. If your device is in a partially erased state, this could also contribute.

      

    How to correctly generate the JBC for POF-based (flash) programming

      

    The key step that is easy to miss: you must select "Enable real-time ISP to allow background programming" prior to creating the JAM file to enable ISP clamp for the JAM STAPL flow.

      

    Specifically: in Quartus Prime 17.1 and later, you need to check the option "Enable real-time ISP to allow background programming when available" in the Programmer window before generating the JAM file — this is what produces a JAM/JBC that contains the DO_REAL_TIME_ISP option.

      

    Then, when invoking the player: for real-time ISP with the JBC and Jam STAPL Byte-Code Player, the command is: jbi_22 -aprogram -ddo_real_time_isp=1 file_name.jbc — the -ddo_real_time_isp=1 flag must be passed explicitly.

      

    With quartus_jli the equivalent is: quartus_jli -aPROGRAM --enable=DO_REAL_TIME_ISP <file>.jbc

      

    Regarding Quartus version compatibility

      

    JAM/JBC files generated in Quartus Prime 17.0 do not contain the DO_REAL_TIME_ISP option due to a known bug. The workaround is to use JAM/JBC files generated in version 16.1; the issue was fixed in version 17.1. Since you are on 25.1, this specific 17.0 bug is not your problem — but it confirms that the DO_REAL_TIME_ISP flag in the generated file is version-sensitive and must be verified.

      

    As for altera-stapl / jamplayer compatibility: the Jam STAPL player is a C program that parses the JAM/JBC file and drives the JTAG chain. You can download the latest version of the Jam STAPL and Jam STAPL Byte-Code Player from the Altera website. If you are using an old build of altera-stapl, it may not correctly handle the DO_REAL_TIME_ISP variable or the MAX 10-specific real-time ISP instruction sequence. I'd recommend verifying against the latest player source from Altera, or switching to quartus_jli for validation.

      

    Recommended debug steps

      
       
    1. Open the generated .jam file in a text editor and confirm it contains a DO_REAL_TIME_ISP variable/action. If it does not, regenerate with "Enable real-time ISP to allow background programming" checked in the Programmer before doing File → Create JAM, JBC, SVF or ISC File.
    2.  
    3. As a workaround for the multi-device JTAG chain formatting issue: check "Enable real-time ISP to allow background programming when available" (below the Hardware Setup button), then execute "Create JAM, JBC, SVF or ISC File" to regenerate.
    4.  
    5. When calling the player, explicitly pass -ddo_real_time_isp=1 (or the equivalent in altera-stapl's API).
    6.  
    7. If the device may be blank/erased, disable real-time ISP for the initial programming pass.
    8.  
    9. Validate the full flow using quartus_jli first to isolate whether the issue is in the JBC file itself or in altera-stapl's execution of it.
    10.  
      

    The "No SLD node / Unrecognized device" sequence strongly points to the player failing to enter real-time ISP mode correctly before attempting flash programming — fixing the DO_REAL_TIME_ISP flag in generation and invocation should resolve it.

    Sources: MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · Config/RSU, MAX 10 · General, MAX 10 · Config/RSU