#ZYNQ Custom Board Bring Up Guide
This is a guide for bringing up custom ZYNQ boards. It covers test sequence, test method, common error situations and code and project that can help to investigate a bring-up problem.
Note: This guide assumes developers are famaliar with Vivado and SDK. For more info about Vivado/SDK tutorials, please refer to [UG940](http://www.xilinx.com/support/documentation/sw_manuals/xilinx2013_4/ug940-vivado-tutorial-embedded-design.pdf).
For how a ZYNQ board should be designed, please refer to [UG1046](http://www.xilinx.com/support/documentation/sw_manuals/ug1046-ultrafast-design-methodology-guide.pdf) Ultrafast Embedded Methodology Guide
This document is under development. Please feel free to fork and provide pull requests.
## Bring Up Plan
Generally the board bring up process follows a rule from basic to specific.
- Power should be checked first
- JTAG connection is the main debug channel. So it should be checked next. It can be used to verify CPU clock, PLL, basic functions and FPGA functions.
- UART is the main way for ARM applications to communicate with host PC. We use a simple Hello World application running on OCM to test it.
- Most systems use external DDR. It needs to be tested before running any large applications such as u-boot and Linux.
- Flash can be tested via SDK or u-boot.
- Ethernet can be tested by u-boot, Linux or standalone applications.
- If any other peripherals are used, they can then be tested based on u-boot or Linux platform. If any issue happens, we can go back to standalone app to test the peripheral to eliminate the impact from OS.
## The Vivado Project ##
A Vivado Project is needed before any software based check is run, e.g. Hello World for UART. The ZYNQ processor initialization configurations are set in Vivado. It is suggested that the settings of PS is added one after another after it is verified to work on hardware. Otherwise, if the CPU doesn't come up perfectly, it's hard to know what's wrong.
Here's a list of the essential settings for first time boot
- Input of PS Clock (PS_CLK) Speed. Target CPU speed would be set to around 666M automatically. No need to change.
- MIO Bank voltage
- UART pin number
- UART baud rate is set to 115200 by default, no need to change.
- DDR can be disabed at first.
This is the smallest system to be tested. More features can be enabled after basic features have been verified.
## Power
### Before Powering Up
* Make sure there are no shorted circuits between each power rail and GND
* Make sure the power on/off sequencing is designed according to "Power-On/Off Power Supply Sequencing" Chapter in ZYNQ Datasheet. Power management IC is recommended to control and adjust the power sequence. If the power sequence guide is not followed, ZYNQ may fail to work or be damaged. ([AR65240](http://www.xilinx.com/support/answers/65240.html))
### After Powering Up
* Check all the power rails should be at the correct voltage
* PS_POR_B and PS_SRST_B should be high when system is stable
* Check the PS clock frequency is toggling as expected between 30MHz and 50MHz
## JTAG
ZYNQ has several JTAG connection methods. The following description assumes the PS PL cascade JTAG mode is being used. In this mode, JTAG cable is connected to PL Bank 0 JTAG signals. PS_MIO[2] is set to 0. PS and PL should both be seen in JTAG debug software.
### Test JTAG via XMD
* Launch XMD
* In Windows: run `Xilinx Microprocessor Debugger` from Windows start menu -> Xilinx Design Suite -> Vivado -> SDK
* In Linux: run `source settings(32/64).(sh/csh)` within Vivado installation directory, then type `xmd` in Linux console
* XMD is replaced by XSCT in the latest version of SDK. Connect command is simplified. Memory read/write command doesn't change.
* Run `connect arm hw` in XMD and check the output
* If unsuccessful, check JTAG cable connection, power sequence, power connection and clock connection
* If connect successful, it shows
```
JTAG chain configuration
Device ID Code IR Length Part Name
1 4ba00477 4 arm_dap
2 23731093 6 xc7z045
```
* In XSCT, use `connect` to connect to the JTAG server `hw_server` and use `target` to list the devices in the chain, use `target <number>` to choose which target device to connect.
* Try to read and write OCM via XMD
* `mrd 0x00001000` - `mrd` means memory read.
* `mwr 0x00001000 0x12345678` - write something to OCM
* `mrd 0x00001000` - check write result
* 0x00000000 to 0x0002FFFF is the OCM address after boot
* Try to program a bit file
* How to prepare a bit file is not covered in this doc. Refer to UG940 or CTT-ZYNQ.pdf for the process.
* Run `fpga -f download.bit` in XMD to program the bit file
### Common Errors ###
* Only PL logic can be found in JTAG chain. ARM can not be found.
* MIO_2 controls the selection of Cascaded JTAG and Independent JTAG. If Independent JTAG is selected, ARM cannot be seen in the JTAG chain.
* PS_SRST_B should be high after powering up. Otherwise, PS will be held in reset state and only PL will be seen in the JTAG chain.
### Known Issues ###
* If there are more than one ZYNQ in the JTAG chain, XMD cannot connect to the second ZYNQ if software version is prior to 2014.1
## UART
### Hello World in OCM
The default Hello World example application in SDK sets the running memory in DDR. If DDR has not been initialized properly, Hello World app won't be run successfully. The best way to test UART is to run the Hello World in OCM.
* Create a ZYNQ design in Vivado
* Configure Reference Clock `Clock Configuration -> Input Frequency`
* Setup UART pin `MIO Configuration -> IO Peripherals -> UART 0/1`
* Generate output products and export to SDK `IP Integrator -> Generate Block Design`
* Create the Hello World app in OCM
* Create a workspace
* Create a BSP and import the Vivado exported XML
* Create a new application and select the Hello World template
* Modify Linker Script to make Hello World app run in OCM
* Right Click the Hello World app, select `Generate Linker Script`
* In Basic Tab, set all sections in `ps7_ram_0_S_AXI_BASEADDR` from the drop down menu
* Save. SDK will generate lscript.ld and recompile the app automatically
* Connect UART console in host PC
* Run the Hello World app by Right Click the app, select `Run As` -> `Launch on Hardware`
* The "Hello World" should be printed
* If it's not printed, it means something goes wrong. Try `Debug As` -> `Launch on Hardware (System Debugger)`. If the debugger can stop at main(), it means the initialization by ps7_init.tcl is passed, clock, PLL and DDR have been initialized properly. Hello world application has a proper environment to run but UART may not be configured properly, UART circuit on PCB board has some issues, or PC UART driver/console is not setup correctly.
* If XMD/XSCT console stops at "executing psu_init()" but the debugger cannot stop at main() of hello world function, it means the initialization doesn't pass. Check hardware settings in Vivado and PCB circuit.
## DDR Memory
### Setting Up DDR3
ZYNQ Memory Controller supports training and write leveling for DDR3. For most DDR3 memory components which obey the routing rules, setting up DDR3 is as easy as to input the DDR3 part number and enabling all three DRAM trainings in DDR Configuration.
### Setting Up DDR2
Since DDR2 training is not supported by ZYNQ, DDR2 board delay details needs to be input into DDR Configuration manually.
* Input DDR2 component part number
* Select `Training/Board Details` from `User Input` to `Calculated`
* Input trace length in mm in Board Delay Calculation Table, the DQS to CLK delay and Board delay will be calculated automatically.
* If the DDR component only uses one clock, input CLK1, CLK2 and CLK3 length same as CLK0
### Test DDR
#### Memory Tests Example Application
The simple memory test applicati