Skip to content

Adding support for Nexys A7.#1613

Open
juanschroeder wants to merge 1 commit intoopenhwgroup:mainfrom
juanschroeder:add_nexysa7_dev_board_support
Open

Adding support for Nexys A7.#1613
juanschroeder wants to merge 1 commit intoopenhwgroup:mainfrom
juanschroeder:add_nexysa7_dev_board_support

Conversation

@juanschroeder
Copy link
Copy Markdown

MIG DDR2 config generated in Vivado.
Using Digilent SD PMOD on 'D' port.
Running at 20 MHz (like Arty A7).

MIG DDR2 config generated in Vivado.
Using Digilent SD PMOD on 'D' port.
Running at 20 MHz (like Arty A7).
@rosethompson
Copy link
Copy Markdown
Contributor

Hi @juanschroeder. Thank you very much for porting the Nexys A7. It would be great to merge this PR.

Our repo requires signing the Eclipse commiter agreement (ECA) in-order to commit changes to the repo. If you are willing, please read the ECA, https://www.eclipse.org/legal/eca/ and sign the form using the same email address as the one used with your github. The emails must match. The email must also match the email address used in the commit message's author field. Once signed the failed check will pass and we can merge your changes.

Thank you again for your contribution.

@juanschroeder
Copy link
Copy Markdown
Author

Ok, that's done. If you have any issues on the Nexys A7 just let me know, I haven't tested it with latest main/master branch but I still have the board at hand.

@danidep02
Copy link
Copy Markdown

Hi Juan and Rose,

I am currently trying to run the CVW-Wally core on a Nexys A7 board, which is very interesting for my work. So first of all thanks a lot for porting support for this board!

I followed the general workflow (similar to the Arty A7 setup) and adapted it for Nexys A7 using the nexysa7 target. Here is what I have done so far:

1. Build and SD card preparation

  • Built Buildroot and generated the Linux image successfully.

  • Flashed the SD card using:

    ./flash-sd.sh \
      -b /opt/riscv/buildroot \
      -d /opt/riscv/buildroot/output/images/wally-nexysa7.dtb \
      /dev/sda
    
  • Verified that partitions were written correctly:

    • /dev/sda2 (OpenSBI) and /dev/sda3 (kernel) contain valid data (not zeros).
    • hexdump shows expected binary content (e.g., “RISCV” in the kernel).

2. Hardware setup

  • Using a Digilent Pmod SD connected to port JD (as mentioned in the PR).
  • SD card is inserted before programming the FPGA.
  • USB connected to JTAG/UART (J10).

3. Bitstream

  • Built using:

    make nexysa7
    
  • Opened WallyFPGA.xpr in Vivado and programmed the FPGA successfully (Program Succeeded).

4. UART connection

  • Connected using:

    screen /dev/ttyUSB1 115200
    
  • The device exists and opens correctly (no permission issues).


Problem

After programming the FPGA and resetting the board, I get no output at all on UART (completely silent terminal).

Given that:

  • The SD card contents are correct,
  • The UART device is valid,
  • The bitstream programs successfully,

it seems that the system is not reaching the boot stage (or not producing UART output at all).


Additional context

I also checked issue #1614 regarding SD card problems. In my case:

  • The SD card is not returning zero data (verified via hexdump),
  • So it does not seem to be the same issue.

Questions

  • Is there anything specific required for Nexys A7 beyond make nexysa7?
  • Should the UART be expected to produce output even if SD boot fails?
  • Could this be related to clocking, reset, or constraints specific to the Nexys A7 port?

Any guidance would be greatly appreciated. I would be happy to test patches or provide more debug information.

Thanks again for the Nexys A7 support!

Dani

@juanschroeder
Copy link
Copy Markdown
Author

Hi Daniel,

Thanks for checking and thanks to you for all the amazing RVFPGA work. It was the reason why I bought my Nexys A7 board in the first place :).

I'll try to do a clean rebuild later today or tomorrow to see what happens. But for now I can tell the following:

  • after reset the CPU runs the bootrom, which is 'on-chip' and therefore it should always print something, even when there's no SD card or adapter if I remember correctly. I guess after printing the banner in the UART if there is no SD card/adapter it would die somewhere around these llines:
[0.05342] Initializing SPI Controller.
[0.05702] Initializing SD Card in SPI mode.

The fact that is not printing anything in the UART (which comes through the same micro USB cable) points more towards an issue with the CPU/SoC and than to an issue with the SD card hardware/data.

  • Apart from building the bitstream with 'make nexysa7' and all the binaries with the instructions in the documentation I think nothing else should be necessary.

  • Given that this SoC doesn't have JTAG/debugging features yet (or not that I know, there's a PR around I think) what you can do is use ILA in Vivado. Some signals should be added by default to the ILA instantiation in 'small-debug.xdc' (see wally.tcl for the 'nexysa7' case) so you can track with that where exactly the program counter (PCM) is getting stuck. With ILA data is very 'RAW' but if you try t match its values what's in 'fpga/zsbl/bin/boot.objdump' you can see what's happening.

This might be a bit tricky to debug if it's the first time you are working with Wally. I'll take a look to this soon and confirm whether I see anything wrong with a clean build of this branch.

@stineje
Copy link
Copy Markdown
Member

stineje commented Apr 12, 2026 via email

@juanschroeder
Copy link
Copy Markdown
Author

juanschroeder commented Apr 12, 2026

Nice, it would be great to have the JTAG option to avoid the ILA debugging.

So, I cloned the repo, built the bitstream and tried it on the board.
I did a clean checkout of the repo here. The exact steps I used are listed below:

$ git clone git@github.com:juanschroeder/cvw.git cvw_nexysa7_pr
$ cd cvw_nexysa7_pr/
$ git checkout remotes/origin/add_nexysa7_dev_board_support
$ git submodule init
$ git submodule update
$ cp ../cvw_nexysa7/setup.sh.DEV .
$ source ../setup_rv_toolchain_cvw.sh 
$ source ../setup_vivado_2024.sh 
$ source setup.sh.DEV 
$ cd fpga/generator/
$ make nexysa7

You probably have to use http clone instead (http://.... instead of git@...)
I don't remember what's the 'standard' way to do this, but that's how I deal with setup.sh (I use my own setup.sh.DEV):

$ diff setup.sh setup.sh.DEV 
27,29c27,29
<     # export RISCV=
<     echo -e "${FAIL_COLOR}\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory.${ENDC}"
<     return 1
---
>     export RISCV=$RISCV
>     #echo -e "${FAIL_COLOR}\$RISCV directory not found. Checked /opt/riscv and ~/riscv. Edit setup.sh to point to your custom \$RISCV directory.${ENDC}"
>     #return 1

After that, I opened Vivado and opened the project generated in fpga/generator/WallyFPGA.xpr
I opened 'Hardware Manager' and 'connected' to the board.
I should have mentioned this in the PR: something that can be an issue with this board is the default JTAG speed. What I normally do is to run this in Vivado console:

set_property PARAM.FREQUENCY 1000000 [get_hw_targets */xilinx_tcf/Digilent/*]
1 MHz is probably too slow (faster also works) but it's safe.
After flashing the bitstream in Vivado (finds the path for the .bit and .ltx automatically) I see this in the serial port even when I have no micro SD card adapter connected to the board:


 █▀█        █▀█        █▀█        █▀▀                 █ █
 █          █ █        █▄▀        █▄▄       ▄▄▄       █ █
 █▄█        █▄█        █ █        █▄▄                 ▀▄▀
 ____          ____  ____      ___      ___   ____    ___
 \   \        /   / /    \    |   |    |   |  \   \  /  /
  \   \  __  /   / /      \   |   |    |   |   \   \/  /
   \   \/  \/   / /   /\   \  |   |    |   |    \     /
    \          / /   ____   \ |   |___ |   |___  |   |
     \___/\___/ /___/    \___\|_______||_______| |___|

[0.05342] Initializing SPI Controller.
[0.05703] Initializing SD Card in SPI mode.
[0.06125] CMD0:

And it gets stuck there trying to communicate (SPI) to the micro SD card that is not connected. So, that should be what you should get even with no SD card.

I'm using Vivado 2024.2 and I haven't built/tried this with any other Vivado version or with any other Nexys A7 board than the only one I have.
The most important change w.r.t. the Arty A7 board is the MIG IP generated with the ddr2-nexysa7.tcl script. If for any reason the board you have has a different DDR chip or if there is an issue accessing RAM I don't remember what would happen. DDR is only accessed for the first time later when loading SD card content into DDR but I'm not sure if an issue there would make UART stuff in the FIFO not being printed (?).
I think the CPU would not go out of reset until the c0_init_calib_complete signal goes high (see sysrst instantiation), so if DDR is not working well then the CPU would not go out of reset and that is something you can check in ILA.

I can share my bitstream if that could be useful.
Let me know if you need any further help.

@juanschroeder
Copy link
Copy Markdown
Author

I forgot to add the 'reset' signal here, but it seems that the CPU does not go out of reset until DDR calibration is complete:

image

If for any reason calibration fails, then CPU would probably not get out of reset, so that's something you can check.
I added the missing c0_init_calib_complete signal at the end of small-debug.xdc as shown below:

create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe8]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8]
connect_debug_port u_ila_0/probe8 [get_nets [list c0_init_calib_complete ]]

@danidep02
Copy link
Copy Markdown

danidep02 commented Apr 13, 2026

Hi Juan and James,

Thanks again for your work on this port, and I’m really glad to hear that RVfpga was useful for you 🙂

I’ve been testing the Nexys A7 support and managed to get the full system running end-to-end. The bitstream builds and programs correctly, and over UART I can see the complete boot flow:

  • BootROM executes correctly (SPI + SD init)
  • OpenSBI loads successfully
  • Linux kernel starts booting

However, the system consistently crashes during early Linux boot with a kernel panic:

Kernel panic - not syncing: System is deadlocked on memory

From the log, this happens while unpacking the root filesystem:

unpack_to_rootfs → do_populate_rootfs

and the system reports only ~41 MB of available memory:

Memory: 41632K/131072K available

So the failure seems to be happening at runtime due to memory constraints rather than a bring-up issue.

Have you observed similar behavior on your side, or is there anything specific that should be adjusted (e.g. rootfs size or configuration) for the Nexys A7 setup?

I'm attaching the boot log:
wally_boot.log

I’d be happy to try any suggestions or provide more logs if needed.

Thanks again!

Dani

@juanschroeder
Copy link
Copy Markdown
Author

Hi Daniel,

Great.

Indeed, I have observed this kind of behavior and it's indeed a problem of the initramfs size + its unpacking needing RAM at the same time and the limited 128 MB. I might have not tested properly a clean Buildroot build for the PR content.

Can you try the patch attached to make the initramfs smaller and tell me if it works?
patch_defconfig_a7.patch

That should reduce both Kernel partition size and bootrom load time from the SD card (p3).
If that works then it needs to be discussed whether a change like this is something that should be done for all targets by default (all use same defconfig) or whether every target should use different Buildroot defconfig (which also needs a change in the base setup).

I personally use Yocto instead of Buildroot, but I am not sure if it works with the Wally master branch for Nexys A7, probably not: https://github.com/juanschroeder/kas-cvwsoc

Juan

@danidep02
Copy link
Copy Markdown

Hi Juan,

Thanks for the quick reply!

I applied your patch to reduce the initramfs size and that solved the issue. The system now boots correctly all the way to a working shell.

Previously, I was consistently hitting an out-of-memory kernel panic during early boot (while unpacking the rootfs), but with the reduced initramfs everything runs fine.

So the full flow is now working:

  • BootROM → OK
  • OpenSBI → OK
  • Linux kernel → OK
  • Rootfs unpack → OK

It looks like the default Buildroot configuration is a bit too large for a 128 MB system, and reducing it fixes the problem.

Thanks a lot for your help!

Dani

Screenshot from 2026-04-13 15-37-10

@stineje
Copy link
Copy Markdown
Member

stineje commented Apr 13, 2026 via email

@juanschroeder
Copy link
Copy Markdown
Author

Hi James,

The PR is so far this thread. I can add add a new commit to the PR if you agree to remove the stuff in the defconfig patch I mentioned in my previous message: https://github.com/user-attachments/files/26674723/patch_defconfig_a7.patch

The defconfig is referenced from linux/Makefile and it's not board/target dependent (for now at least).

Or maybe a 'wally_minimal_defconfig' or so can be created instead for a more 'minimal' rootfs (which can be good for some use cases). Maybe some README should be updated accordingly.

Just let me know what's your preference.

@danidep02
Copy link
Copy Markdown

Hi all,

I managed to get the Nexys A7 working using the on-board microSD slot instead of the PMOD. The only modifications were in the top-level wiring and constraints.

XDC changes (mapping SPI to on-board microSD and commenting the PMOD-SD):

  • set_property -dict { PACKAGE_PIN B1 IOSTANDARD LVCMOS33 } [get_ports SDCCLK] ;# SD_SCK
  • set_property -dict { PACKAGE_PIN C1 IOSTANDARD LVCMOS33 } [get_ports SDCCmd] ;# SD_CMD
  • set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports SDCIn] ;# SD_DAT0 (MISO)
  • set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports SDCCS] ;# SD_DAT3 (CS)
  • set_property -dict { PACKAGE_PIN A1 IOSTANDARD LVCMOS33 } [get_ports SDCCD] ;# SD_CD
  • set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports SD_RESET }

Top-level change (fpgaTopNexysA7.sv):

  • assign SD_RESET = 1'b0;

I am using a SanDisk Ultra 32 GB microSD and it works without issues.

Best regards
Dani

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants