Forum Discussion
Run-time errors using EMIF in Agilex 5 NIOS-V design
Hello,
I am using Quartus Prime Pro 26.1.1, with the Agilex 5 development board (AXE5-Eagle). I am trying to run the NIOS-V code from the LPDDR4 memory, using JTAG to download/debug. The reset and exception vectors are set to the On-Chip RAM. I used the sample design provided for that board - AXE5 Eagle mipi_hdmi_mira220 and removed everything related to MIPI and HDMI. Added JTAG Uart IP. The resulting sample design is attached (mipi_hdmi_mira220.zip). In the software/ directory you can also see the FreeRTOS BSP I used.
I created a simple FreeRTOS application that just prints some string to stdout.
What I am seeing is - the RISC-V processor throws exceptions - one of the following - Misaligned Read Address, Misaligned Write Address or Invalid Instruction. This happens in alt_load_section(). If I execute step-by-step, no exception is thrown. But if I just run the application it fails.
Is there something else that need to be added/updated/changed, in order to be able and execute code from LPDDR4 using the EMIF IP?
I could not find any existing sample design, using NIOS-V and EMIF, with code execution from EMIF.
Thank you,
D.
5 Replies
- dim1
New Contributor
I did notice that s0_axi4_ctrl_ready was not used. Attached is an updated design where the s0_axi4_ctrl_ready is connected to the NIOS-V reset, to keep NIOS-V in reset until the EMIF is ready. It did not change anything - still the same problem.
- RaduB_Altera
Occasional Contributor
Hello,
My name is Radu, and I am investigating your question.
It is a bit out of my expertise area, so I am trying to enlist some experts to help. Will get back to you in a day or two.
In the meantime, see below some suggestions coming from an AI assistant, as they may be helpful:
Connecting s0_axi4_ctrl_ready only to the Nios reset pin is not enough, and it is not a synchronized reset. ctrl_ready is an asynchronous EMIF output. If you feed it into the same Reset Controller that drives core_init_n, calibration deadlocks. Use two Reset Controllers:
- EMIF reset: ninit_done + board reset + PLL lock → core_init_n and the EMIF AXI4-Lite CSR reset only.
- CPU/system reset: EMIF reset output and s0_axi4_ctrl_ready, synchronized to the Nios clock → Nios reset, ndm_reset_in, OCRAM, JTAG UART.
That still may not be the whole issue. Nios V/m instruction and data managers are 32-bit AXI4-Lite, and they are connected directly to a 256-bit LPDDR4 s0_axi4 through Platform Designer GENERIC_CONVERTER logic. .text, .rwdata, .bss, heap and stack are all in LPDDR4 at 0x80000000, so alt_load_section() is a DRAM-to-DRAM copy while the CPU is already fetching from DRAM. That matches “works when single-stepped, fails at full speed.”
On Agilex 5 Fabric EMIF, unaligned access is not supported (ARADDR/AWADDR must be a multiple of 32 bytes). A 256-bit beat with ARSIZE < 5 is a narrow read. This device (A5ED065BB32AE4SR0) is in the OPN set documented as not supporting narrow reads. The GHRD does not exercise this topology: it runs from OCRAM and reaches LPDDR4 through Address Span Extender.
Please capture SignalTap on s0_axi4 during the crash (clock = Nios/s0_axi4 clock):
- ctrl_ready / s0_axi4_reset_n must stay 1
- ARSIZE/AWSIZE must be 5, addr[4:0] must be 0, RRESP/BRESP must be OKAY
- WSTRB for a 32-bit store must enable only one 4-byte lane
If ARSIZE is 2 or addr[4:0] is non-zero, the interconnect is issuing an unsupported EMIF transfer and reset changes will not make XIP reliable. In that case insert the GHRD-style Address Span Extender (32-bit datapath, one window, control port disabled) — or another upsizer that forces full-width aligned beats — between Nios and s0_axi4.
In parallel, please run a small OCRAM-only program (code, stack, and data in on-chip RAM) that waits for EMIF ready and then does 32-bit and byte-lane memory tests into LPDDR4 at full speed. Also set hal.linker.allow_code_at_reset=1 and point the OCRAM init file at this application; it currently still references the old MIPI hex.
If you can, please also report mcause, mepc, and mtval from the trap. I do not want to call a final root cause until the AXI traces confirm the beat shape.
Thank you,
Radu- dim1
New Contributor
Hello Radu,
Thank you for your message and suggestions.
I already did LPDDR4 memory test, using the Altera sample program available for NIOS II, re-built for NIOS-V. Run the application from the on-chip RAM only. All tests passed.
I added second Reset Controller, as suggested. That changed nothing.
Next I captured arsize and I saw that it is 2, not 5. I saw that on every instruction fetch, arsize is always 2.
The mcause I was seeing are 0, 2, 4 and 6. Though, I was using NIOS-V g initially, and then switched to NIOS-V m, just to keep things as simple as possible.
Finally, I add the Address Span Extender - and it worked. With it, now the application starts and runs Ok.
Is using the Address Span Extender the only way to use EMIF with NIOS-V, for XIP from LPDDR4, without having to create a new IP?
Thank you,
D.
- RaduB_Altera
Occasional Contributor
Thank you for the measurements! That isolates the issue. And glad to hear it is working now!
ARSIZE=2 on every instruction fetch means the Platform Designer width converter is issuing AXI narrow reads (4-byte transfers) into the 256-bit LPDDR4 interface. On this device (A5ED065BB32AE4SR0), Fabric EMIF does not support narrow reads; it expects full-width transfers (ARSIZE=5) with addresses aligned to 32 bytes. mcause 0/2/4/6 is what you get when those reads return bad instruction or data. Reset changes cannot fix that, and Nios V/g vs V/m does not change it either — both managers are 32-bit.
That is also why the OCRAM memory test passed: instruction fetches were not going to LPDDR4. XIP puts a continuous stream of instruction reads onto that unsupported path.
You do not need to create a new IP. Address Span Extender is the supported catalog IP for connecting Nios V to EMIF, including as instruction/data memory. It is what the Agilex 5 Nios V GHRD uses. A direct Nios AXI4-Lite connection to s0_axi4 is not a reliable XIP topology here, because that path keeps ARSIZE=2.
ASE is not required in your design because the DRAM is larger than 4 GB (your LPDDR4 window already fits in the 32-bit map). It is required because it is the supported adapter that presents a 32-bit window to Nios and lets the interconnect issue legal full-width EMIF beats. There are other bridges in the catalog, but they are not the documented XIP solution and they can still pass narrow ARSIZE through. I recommend staying with ASE.
For execute-in-place, please keep: datapath 32-bit, a single sub-window, and the slave control port disabled. If you want a final check, SignalTap on s0_axi4 with ASE in place should show ARSIZE=5 and ARADDR[4:0]=0.
Thank you,
Radu - dim1
New Contributor
Hello Radu,
Thank you for the detailed explanation!
In the IP catalog, I see AXI Address Span Extender IP.
Is the AXI Address Span Extender IP equivalent to the Address Span Extender? Would not that be better to use, considering that the EMIF so_axi4 is an AXI4 bus?
Another question: In the EMIF IP User Guide, in Table 12 Limitations on Narrow Read Transfer, in the Non-Lockstep configuration, when only the primary controller is used, does it mean that narrow read is supported on all Agilex 5 D and E series devices, except on the two devices listed in the table?
Thank you,
D.