IObundle/iob-soc

run on xilinx zynq

Closed this issue · 8 comments

if I want to run this project on ZCU102, what should I do to modify the folder vivado/AES-KU040-DB-G?

I ckeck the resources of ZCU102. It has a 256MB DDR4 connected to PL, so I think it may work. After I run the program
make fpga-run BOARD=ZCU102 INIT_MEM=0 RUN_EXTMEM=1
it print

Info: Running console

+-----------------------------------------------+
|                   IOb-Console                 |
+-----------------------------------------------+

  BaudRate = 115200
  StopBits = 1
  Parity   = None

IOb-Console: connecting...

IOb-Bootloader: connected!
IOb-Bootloader: DDR in use
IOb-Bootloader: program to run from DDR
IOb-UART: requesting to receive file
IOb-Console: got file send request
IOb-Console: file name b'firmware.bin' 
IOb-Console: file of size 20328 bytes
IOb-Console: file sent
IOb-UART: file received
IOb-Bootloader: Loading firmware...
IOb-UART: requesting to send file
IOb-Console: got file receive request
IOb-Console: file name b's_fw.bin' 
IOb-Console : file size: 20328 bytes
IOb-Console: file received
IOb-UART: file sent
IOb-Bootloader: Restart CPU to run user program...

but the user program doesn't start
and the trap signal is high, I want to know what happen and how to fix the bug.

jjts commented

Did you create a ZCU102 folder with all the necessary files inside? Please look at the hardware/fpga/BASYS3 folder for example and let me know.

Thanks for your reply. As you said, I created a folder named ZCU102 under /hardware/fpga/vivado and then added and modified the contents based on the AES-KU040-DB-G folder. Since I saw that the AES-KU040-DB-G project used a DDR section, I thought it would be similar to ZCU102, so I followed that template. First, I referred to the ZCU102 user manual and added ddr.xdc and top_system.xdc files. The main difference between ZCU102 and AES-KU040-DB-G regarding DDR is that ZCU102 has a 256Mb*16 DDR with the model number MT40A256M16GE-075E.

After that, I added and modified the Makefile, changing the data model, DDR data, and address bus widths for ZCU102 based on the DDR IP configurations in Vivado.

ROOT_DIR:=../../../..

BOARD=ZCU102

BOARD_SERVER=$(ZCU102_SERVER)

BOARD_USER=$(ZCU102_USER)

DEVICE=xczu9eg-ffvb1156-2-e

\#specify any conditions that prevent running this FPGA

NORUN = 0

\#DDR controller address and data widths

DDR_ADDR_W=29

DDR_DATA_W=128

VHDR+=ddr4_axi_wire.vh

ddr4_axi_wire.vh:

​    $(LIB_DIR)/software/python/axi_gen.py axi_wire 'ddr4_' 'ddr4_' 'ddr4_'

include ../vivado.mk

Then, I copied the /verilog folder to ZCU102 and modified the bit widths related to the DDR section, changing them from 32 bits to 16 bits.

module top_system
  (

   //differential clock input and reset
   input         c0_sys_clk_clk_p, 
   input         c0_sys_clk_clk_n,
   input         reset,

   //uart
   output        uart_txd,
   input         uart_rxd,

`ifdef USE_DDR
   output        c0_ddr4_act_n,
   output [16:0] c0_ddr4_adr,
   output [1:0]  c0_ddr4_ba,
   output [0:0]  c0_ddr4_bg,
   output [0:0]  c0_ddr4_cke,
   output [0:0]  c0_ddr4_odt,
   output [0:0]  c0_ddr4_cs_n,
   output [0:0]  c0_ddr4_ck_t,
   output [0:0]  c0_ddr4_ck_c,
   output        c0_ddr4_reset_n,
   inout [1:0]   c0_ddr4_dm_dbi_n,
   inout [15:0]  c0_ddr4_dq,
   inout [1:0]   c0_ddr4_dqs_c,
   inout [1:0]   c0_ddr4_dqs_t,
`endif 
                 
   output        trap
   );

Lastly, I made modifications to top_system.tcl under /vivado, adjusting the bit widths and configurations for the DDR and AXI components.

        set_property -dict \
            [list \
                 CONFIG.NUM_SLAVE_PORTS {1}\
                 CONFIG.AXI_ADDR_WIDTH {29}\
                 CONFIG.ACLK_PERIOD {3333} \
                 CONFIG.INTERCONNECT_DATA_WIDTH {128}\
                 CONFIG.M00_AXI_IS_ACLK_ASYNC {1}\
                 CONFIG.M00_AXI_WRITE_FIFO_DEPTH {32}\
                 CONFIG.M00_AXI_READ_FIFO_DEPTH {32}\
                 CONFIG.S00_AXI_IS_ACLK_ASYNC {1}\
                 CONFIG.S00_AXI_READ_FIFO_DEPTH {32}\
                 CONFIG.S00_AXI_WRITE_FIFO_DEPTH {32}] [get_ips axi_interconnect_0]

        set_property -dict \
        [list \
             CONFIG.C0.DDR4_TimePeriod {833} \
             CONFIG.C0.DDR4_InputClockPeriod {3332} \
             CONFIG.C0.DDR4_CLKOUT0_DIVIDE {5} \
             CONFIG.C0.DDR4_MemoryPart {MT40A256M16GE-075E} \
             CONFIG.C0.DDR4_DataWidth {16} \
             CONFIG.C0.DDR4_AxiSelection {true} \
             CONFIG.C0.DDR4_CasLatency {18} \
             CONFIG.C0.DDR4_CasWriteLatency {12} \
             CONFIG.C0.DDR4_AxiDataWidth {128} \
             CONFIG.C0.DDR4_AxiAddressWidth {29} \
             CONFIG.ADDN_UI_CLKOUT1_FREQ_HZ {100} \
             CONFIG.C0.BANK_GROUP_WIDTH {1}] [get_ips ddr4_0]

I forked the repository and placed the code in it. The repository can be found at the following address: https://github.com/zchliu/iob-soc. Inside the /hardware/fpga/vivado/ directory, there is a ZCU102 folder containing the code I added. It can be successfully compiled and synthesized.

Afterward, I connected the development board and powered it on. I executed the command make fpga-run BOARD=ZCU102 INIT_MEM=0 RUN_EXTMEM=1. Initially, there was normal output, which could be seen in the code of boot.c.

Info: Running console

+-----------------------------------------------+
|                   IOb-Console                 |
+-----------------------------------------------+

  BaudRate = 115200
  StopBits = 1
  Parity   = None

IOb-Console: connecting...

IOb-Bootloader: connected!
IOb-Bootloader: DDR in use
IOb-Bootloader: program to run from DDR
IOb-UART: requesting to receive file
IOb-Console: got file send request
IOb-Console: file name b'firmware.bin' 
IOb-Console: file of size 20328 bytes
IOb-Console: file sent
IOb-UART: file received
IOb-Bootloader: Loading firmware...
IOb-UART: requesting to send file
IOb-Console: got file receive request
IOb-Console: file name b's_fw.bin' 
IOb-Console : file size: 20328 bytes
IOb-Console: file received
IOb-UART: file sent
IOb-Bootloader: Restart CPU to run user program...

It transferred the firmware.bin compiled by riscv-gcc to the DDR on the board through UART and then attempted to restart. However, at this point, the trap LED on the development board lit up, indicating that the CPU entered the trap state, and there was no other output in the terminal. It seemed to be stuck. I tried pressing the reset signal, but there was no response.

Is there any mistake in my process? I used the template of AES-KU040-DB-G instead of BASYS3. Did I miss any files that could cause issues when the CPU restarts?

jjts commented

The first comment is 256MB is DDR_ADDR_W=28, not 29

Thank you for your suggestion. I made a calculation mistake earlier. The address width should be 28 instead of 29. However, even after changing the address width, the CPU still couldn't start correctly. Do you have any other suggestions?

jjts commented

The trap condition means that either the program wasn't written correctly or is being read incorrectly.

It means what it reads from memory is not recognized as a valid instruction.

My suggestion is to remove iob-soc and debug the DDR controller only in the PL. Once you know it is good then add iob-soc.

jjts commented

Another issue may be that the cache has a bug preventing it from working with a backend different from 32 bits.

Can you try with cache backend, axi interconnect, and ddr controller at 32 bits?

jjts commented

This issue will be closed as not followed up