Recent Posts

Pages: [1] 2 3 ... 10
1
Trenz Electronic FPGA Modules / Re: TE0722 step by step
« Last post by offroad on June 15, 2019, 03:51:55 PM »
the complete design with some redundant folders deleted for Vivado 2019.1
2
Trenz Electronic FPGA Modules / TE0722 step by step
« Last post by offroad on June 15, 2019, 03:42:43 PM »
"Small step for man. Huge leap for Frodo"

Not being a Zynq guru, it took a surprisingly long time to bring up this little board without "shortcuts" so that I understand (or at least believe I do...) what is happening.
This quick write-up is meant both for myself later, maybe also for others who are running into the same issues (but it's not supposed to be a "recipe" to be followed through blindly). And if I'm getting something wrong, please do comment.

The approach here is pretty much the opposite of embedded Linux with all bells and whistles on board - the option still remains. The spirit here is that for an FPGA-designer, an ARM core (or two) at 600+ MHz with huge (compared to BRAM) OCM plus cache is something Big and Shiny...

Specific challenges with this board:
====================================
- DDR-less operation: Xilinx considers this "non-mainstream" and it requires a few manual tweaks
- FSBL integration: Because of above, the arguably easiest way to integrate user ARM code is to put it into the FSBL
- However, debugging FSBL code is not as straightforward as having a regular application
- The UART needs to be routed through PL, so it is only available after the bitstream has loaded (FSBL running from flash cannot print debug info until almost the handover point)
- reportedly, it can be soft-bricked for lack of a boot mode jumper. It never happened to me on this board (fingers crossed) but some care is advised. See [1] for recovery

TE0790 preparation:
===================
- DIP switches "1-4: off off on on" for flashing
- Diamond 3.10.0.111.2 should autodetect the LCMX02-256HC device
- add filename xmod_DIP40_rev01.jed
- click "program"
- Output: INFO - Operation successful (no errors)
- in case of "CHECK_SECURITY_PROTECT_KEY", check that above version is used (do not install service pack over it)
- DIP switches "1-4: on off on on" for regular operation

Power:
======
The supply via TE0790 worked fine in my experiments to power the board, also for flashing the TE0790 CPLD. There once was a shutdown after a minute or so when the RGB LED was on. I'm not paranoid about breaking a two-digit-priced board, but be aware that there is a risk of e.g. burning a regulator.

Goals:
======
Following this walkthrough should lead to a PL / PS design that boots from SPI with following features:
- control of the on-board LED (via MIO, does not require PL and is very useful for debugging FSBL via blink codes)
- control of the RGB LED (via PL)
- UART (requires routing through the PL)

Steps:
======
1) implementation of PL part in Vivado (leads to bitstream and board support files)
2) auto-generation of a FSBL project in SDK and modification for no-DDR operation
3) add blink codes for FSBL debugging
4) control the RGB LED once the bootloader has brought up PL and AXI interface
5) print "Hello world" through the UART

Version:
========
Vivado 2019.1 webedition was used but earlier versions should work just as well

1) PL implementation
====================
- Start Vivado. File/Project/New (Wizard). Select component "XC7Z010CLG225-1" (use schematic or a magnifying glass on the board to determine the Zynq version).
- Flow manager: IP integrator: Create block design. Click on the "+" button to "add IP" and add ZYNQ processing system (hint: use search box)

we now configure the Zynq processing system:
- double-click the "processing_system7_0 component"
- Page navigator / "DDR configuration": disable the "enable DDR" checkbox. This reflects the fact that there is no DDR chip on the TE0722 board.
- Page navigator / clock configuration / Basic clocking / PL fabric clocks:
- - note (default) that input frequency / MHz is 33.3 MHz. This corresponds to the oscillator in the schematic (U8) that feeds into the Zynq chip at pad C7, PS_CLK_500
- - note (default) that "processor / memory clocks" : CPU : ARM PLL is set to 666.6 MHz. This sets the processor's clock to the maximum value allowed.
- - note that FCLK_CLK0 is be checked (default).
This provides a clock from PS to PL. Note that this clock requires the ARM processor to be configured (it's not available if loading the bitstream to PL via Vivado)
- enable "MIO configuration / Memory interfaces / Quad SPI flash" checkbox and set to Single SS 4-bit IO with MIO 1..6
This enables access to the flash chip, to be able to load the FPGA bitstream later in the FSBL. The settings (4 bits, MIO 1..6) correspond to the schematic.
- enable "MIO configuration / I/O peripherals / UART 0" and set IO to EMIO.
This provides a UART for xil_printf() later. As there are no suitable MIO pins routed on this board, EMIO makes the UART signals accessible to the PL (they appear in the schematic component after closing the dialog)
- note (default) "PS-PL Configuration: General: UART0 baud rate" is 115200. This is the baudrate we need later to connect to the UART with a terminal program.
- enable "MIO configuration: GPIO : GPIO MIO (with IO = "MIO") with all other GPIO/* boxes cleared
This allows software control of MIO7 (see schematic), which drives the green on-board LED
- note (default) PS-PL configuration / GP Master AXI interface / M_AXI GPO interface checkbox ("enables General purpose AXI master interface 0") is enabled.
This provides the bus where we will attach a GPIO component for the RGB LED.
Close the "Zynq 7 processing system" dialog with OK.

For demo / debug purposes we want to add control of the RGB LED, using a GPIO block.
- In the block diagram, right click background, "add IP", locate "AXI GPIO" (hint: use search box)
- in the newly created "axi_gpio_0" component, right-click the "GPIO" label, then "make external"
- click on the newly created "GPIO_0" pin, and rename it via the "External interface properties" window to "RGB_LED" (we are hereby defining the arbitrary signal name)
- double-click the axi_gpio_0 component, click "all outputs" and set GPIO width to 3. Set "default output value" to 0x7 (this turns the LED off when the bitstream is loaded to the FPGA)
- right click the background, "run connection automation". This will add AXI bus infrastructure for the GPIO block.
- at this point, the block diagram should have a single "RGB_LED" outbound pin.
- in "processing_system7_0", click on UART0 to open the group showing UART0_TX and UART0_RX
- right-click on UART0_TX, "make external"
- right-click on UART0_RX, "make external"

Now go to "block design / sources / Constraints / constrs_1"
- right click "add sources" "add or create constraints", "create file" (enter some name)
- right-click the file, under "Source file properties" disable "Used in: Synthesis"
- open that file and copy the following lines into it:

Code: [Select]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property CFGBVS VCCO [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]

set_property PACKAGE_PIN J15 [get_ports {RGB_LED_tri_o[0]}]
set_property PACKAGE_PIN L14 [get_ports {RGB_LED_tri_o[1]}]
set_property PACKAGE_PIN K12 [get_ports {RGB_LED_tri_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {RGB_LED_tri_o[*]}]

set_property PACKAGE_PIN K15 [get_ports UART0_TX_0]
set_property PACKAGE_PIN L13  [get_ports UART0_RX_0]

set_property IOSTANDARD LVCMOS33 [get_ports UART0_TX_0]
set_property IOSTANDARD LVCMOS33 [get_ports UART0_RX_0]
The first part sets general configuration options (bank voltages, see schematic, and to use weak pull-up on unused pins)
Signals are connected ("constrained") to specific FPGA pins (PACKAGE_PIN), and IO levels are set ("IOSTANDARD").
Note, the names match those in the block diagram with some name mangling (_0 and _tri_o attached), e.g. found from error messages.

Then, in Sources/Design Sources/(name of the toplevel block design), right-click "create HDL wrapper" ("let Vivado manage").
PROGRAM AND DEBUG/Generate Bitstream. This will take a minute, now the HW design is built.

At this point, double-check the warnings. I got about 100 critical warnings from a generated .xdc file used in synthesis when it shouldn't ("because the property does not exist for objects of type "pin")
There are 336 regular warnings, but nothing that relates directly to the design (unconnected pins, no constraints selected for write, deprecated options yabbadabba)

Now, "File, Export hardware", enable "include bitstream".

Optional bitstream upload (debug)
=================================
Uploading the FPGA design can rule out some errors even though debugging is rather limited
PROGRAM AND DEBUG, "open hardware manager", "Program device". The small red LED should turn off if the bitstream is recognized. If in doubt, rebuild with a default output value of 0x6 for the RGB LED GPO, this will enable the red RGB LED on bitstream loading.

2) Auto-generation of a FSBL project in SDK
===========================================

(Make sure that Vivado's hardware manager is disconnected, also the other way around that SDK debugger is disconnected before using the Vivado programmer. The two don't get along too well...)
Vivado: File / launch SDK
SDK: File / new / Application project. Enter a name e.g. I will use "walkthrough". Click Next, select ZYNQ FSBL, click Finish.

- disable DDR check: edit walkthrough/src/main.c
Locate this block

Code: [Select]
#ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR

    /*
     * DDR Read/write test
     */
Status = DDRInitCheck();
if (Status == XST_FAILURE) {
fsbl_printf(DEBUG_GENERAL,"DDR_INIT_FAIL \r\n");
/* Error Handling here */
OutputStatus(DDR_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
}

and change into

Code: [Select]
#define XPAR_PS7_DDR_0_S_AXI_BASEADDR 0
#ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR
(in other words, the DDRInitCheck() call and its return value check are deleted)

Reason: There is no DDR, so the check would fail.

3) Add blink code for FSBL debugging (see [5])
===========================================

As there is no UART, we add a simple blink code debug function.
Insert this in walkthrough/src/main.c, for example right before int main(void)

Code: [Select]
#include "xgpiops.h"
#include "sleep.h"
XGpioPs_Config* mioGpioConfig = NULL;
XGpioPs mioGpio;
// this is the MIO number of the green LED (see schematic)
#define ledpin 7
void doblink(int n){
  if (!mioGpioConfig){
    mioGpioConfig = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
    u32 Status = XGpioPs_CfgInitialize(&mioGpio, mioGpioConfig, mioGpioConfig->BaseAddr);
    if (Status != XST_SUCCESS){
      xil_printf("failed to initialize MIO_GPIO");
    };
    XGpioPs_SetDirectionPin(&mioGpio, ledpin, 1);
    XGpioPs_SetOutputEnablePin(&mioGpio, ledpin, 1);
  } // if startup

  for (int ix = 0; ix < n; ++ix){
    XGpioPs_WritePin(&mioGpio, ledpin, 0x1);
    usleep(300000);
    XGpioPs_WritePin(&mioGpio, ledpin, 0x0);
    usleep(300000);
  }
  usleep(500000);
}
We make it blink once at startup ...
Code: [Select]
doblink(1);
fsbl_printf(DEBUG_GENERAL,"\n\rXilinx First Stage Boot Loader \n\r");
... twice before and three times after loading the boot image (FPGA bitstream)
Code: [Select]
doblink(2);
HandoffAddress = LoadBootImage();
doblink(3);
Now the code should be functional already:
In "Project explorer", right-click "walkthrough", "create boot image".
Change output format to "MCS", "Create image".

Flashing requires the fsbl_flash bootloader that comes with the pre-built TE0722 reference design:
Click Xilinx/Program Flash
For "Image file", select the mcs file that was just created (hint: the file selector is dangerous, may want to go to another project...)
For "bootloader", select the one from the prebuilt distribution (this is only a tool for flashing).
E.g. \prebuilt\software\10\zynq_fsbl_flash.elf

With the flashed design, power-cycling should show the following LED pattern:
- initially RED (no PL bitstream)
- green blinks once (FSBL enters)
- green blinks twice (before image load)
- RED goes dark (PL was configured)
- green blinks three times

4) control the RGB LED once the bootloader has brought up PL and AXI interface
========================================================
This is very similar to 3) but note that the GPIO write will lock up if the AXI interface hasn't been woken up by the FSBL
At this point, we're also done editing the FSBL and start putting the user code into the place where it is supposed to go:

- open src/fsbl_hooks.c
- at the function FsblHookBeforeHandoff(), add

Code: [Select]
#include "xgpio.h"
#include "sleep.h"
(before the function) and
   
Code: [Select]
XGpio Gpio; /* The Instance of the GPIO Driver */

Status = XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
if (Status != XST_SUCCESS) {
  xil_printf("Gpio Initialization Failed\r\n");
}
XGpio_DiscreteWrite(&Gpio, 1, 6);
sleep(1);
XGpio_DiscreteWrite(&Gpio, 1, 5);
sleep(1);
XGpio_DiscreteWrite(&Gpio, 1, 3);
sleep(1);
XGpio_DiscreteWrite(&Gpio, 1, 7);

into the function (note, the LED is turned on with a logical 0. The above sequence is ~1, ~2, ~4, ~0 for red, green, blue, off)

5) Hello world
Finally, add

Code: [Select]
while (1){
xil_printf("Hello world\r\n");
}
at the same location as in 4)

Download Teraterm and open
File/New connection, select the COM port that corresponds to the TE0790 serial port
Setup / serial port: Set baud rate to 115200

Conclusion:
===========

Following the above discussion should result in a PL/PS design that loads from flash and is reduced to the essentials.
There are many follow-up topics that come to mind, especially when reading the documentation (e.g. using the cache for memory, execute-in-place for FLASH code) but it's getting late and those are questions for another day :)


References
==========

[1] https://wiki.trenz-electronic.de/display/PD/TE0722-Recovery
[2] https://wiki.trenz-electronic.de/display/PD/TE0722+TRM
[3] https://wiki.trenz-electronic.de/display/PD/DDR+less+ZYNQ+Design
[4] https://www.trenz-electronic.de/fileadmin/docs/Trenz_Electronic/Modules_and_Module_Carriers/special/TE0722/REV02/Documents/SCH-TE0722-02.PDF
[5] https://forums.xilinx.com/t5/Xcell-Daily-Blog-Archived/Driving-the-Zynq-SoC-s-GPIO-Adam-Taylor-s-MicroZed-Chronicles/ba-p/389611
3
UltraScale / Re: HDMI output TE0820+TE0701
« Last post by Oleksandr Kiyenko on June 14, 2019, 08:25:06 AM »
Hi Sarah,

you need to figure out what happens with I2C communication to ADV7511 to be sure that it configured correctly.

Best regards
Oleksandr Kiyenko
4
UltraScale / Re: HDMI output TE0820+TE0701
« Last post by SaW on June 13, 2019, 05:32:01 PM »
Hi Oleksandr,
so we have tested it but the screen doesn't stay ON.
We measure the i2C communication, it is doing the initialisation (sending the good data at least). But when we ask to read the register that we just initialized, we received only 0x14 as value.
One thing observed the frequency is not totally the same than the ii_sck_rate, for a frequency of normally 400000 on the scope we see 333333, but nothing has been change in the fsbl except the part for the adv7511, vdma and vtc configuration.

we tried to read the i2c probe on the uboot and it was only sending back the address from the Si5338A PLL and the EEPROM. We couldn't get the value from the adv chip.
I took the uboot from the TE0820 base without adding anything… did you need to change something there for the connection too?
thank you a lot for your help again,
Best regards,
Sarah
5
UltraScale / Re: HDMI output TE0820+TE0701
« Last post by Oleksandr Kiyenko on June 13, 2019, 12:41:48 PM »
Hi Sarah,
for this test, the device tree looks OK. VDMA and VTC are disabled. Without adv7511 configuration you will not get the correct image. Put ADV7511 initialization code into (FSBL adv7511.c and adv7511.h from HDMI701\sw_lib\sw_apps\zynq_fsbl\src) and stop Linux boot in u-boot to see if screen is ON. If it will stay ON try to direct write to framebuffer memory, pixels should appear on the screen.

Best regards
Oleksandr
6
UltraScale / Re: Mask poll failed at ADDRESS: 0xFD4023E4 MASK: 0x00000010
« Last post by JH on June 13, 2019, 10:58:42 AM »
Hi,
follow instruction of the reference design:
18.3 design includes a console menue to select the correct assembly variant.
This should set the correct PS settings. If not, send me the generated log file (subfolder ./vlog)
br
John
7
UltraScale / Re: Mask poll failed at ADDRESS: 0xFD4023E4 MASK: 0x00000010
« Last post by baldrism on June 13, 2019, 10:11:53 AM »
Hello JH,

in the preset.xml file there is a list of DDR settings. Please, see the following attached image "preset_xml.png".
However, when I try to add these settings in my Zynq, there are some errors.
In particular it says the following:
"Validation failed for parameter 'PSU UIPARAM DDR CL(PSU_DDRC_CL) with value '17' for BD Cell 'zynq_ultra_ps_e_0'. Supported CAS Latency for Speed Bin 2400 with Operating Freq 1066.56 {16}.

Therefore my system didn't work due to these DDR failures.
Do you know how can I solve that and why there are these warnings?

Thanks,

baldrism
8
Trenz Electronic FPGA Modules / Re: TE0790 CPLD programming "note to self"
« Last post by JH on June 13, 2019, 06:44:18 AM »
Hi,
we didn't tried out newest service pack until now.
Thanks to share this information and possible solution.
br
John
9
Trenz Electronic FPGA Modules / TE0790 CPLD programming "note to self"
« Last post by offroad on June 12, 2019, 11:11:25 PM »
Problem: Programming the CPLD had earlier worked using Diamond 3.10.0.111.2 but failed later with the 3.144.3 service pack version giving an error "CHECK_SECURITY_PROTECT_KEY".
I had also updated the generic FTDI drivers to the latest ones from FTDI's homepage, as the Lattice installation apparently broke other FTDI code on the same machine by reverting to older FTDI drivers.
Solution: Reinstalling the original Diamond version and reinstalling its USB drivers (dialog during install) solved the issue, on Windows 8.
10
UltraScale / Re: HDMI output TE0820+TE0701
« Last post by SaW on June 12, 2019, 02:03:12 PM »
Hi Oleksandr,
sorry to bother you again with it, i recompiled the Linux kernel, this time without allowing Xilinx_DMA config and Zynqmp_DMA, and actually the screen stayed ON until the boot is finished but when this one is finished the screen goes back to sleep mode. Also for this short time the screen is on the screen stay black i don't see anything.
But i check and the FSBL is configuring the vdma at least it seems since it doesn't send any error back
could you just check my device tree and tell me if it is correct or not?
Code: [Select]
amba_pl@0 {
#address-cells = <0x2>;
#size-cells = <0x2>;
compatible = "simple-bus";
ranges;

dma@a0010000 {
#dma-cells = <0x1>;
clock-names = "s_axi_lite_aclk", "m_axi_mm2s_aclk", "m_axis_mm2s_aclk";
clocks = <0x3 0x47 0x3 0x47 0x3 0x47>;
compatible = "xlnx,axi-vdma-6.3", "xlnx,axi-vdma-1.00.a";
interrupt-names = "mm2s_introut";
interrupt-parent = <0x4>;
interrupts = <0x0 0x59 0x4>;
reg = <0x0 0xa0010000 0x0 0x1000>;
xlnx,addrwidth = <0x20>;
xlnx,flush-fsync = <0x1>;
xlnx,num-fstores = <0x1>;
status = "disabled";

dma-channel@a0010000 {
compatible = "xlnx,axi-vdma-mm2s-channel";
interrupts = <0x0 0x59 0x4>;
xlnx,datawidth = <0x20>;
xlnx,device-id = <0x0>;
};
};

PERIPHERAL@ff380000 {
compatible = "xlnx,PERIPHERAL-1.0";
reg = <0x0 0xff380000 0x0 0x80000>;
};

PERIPHERAL@ff990000 {
compatible = "xlnx,PERIPHERAL-1.0";
reg = <0x0 0xff990000 0x0 0x10000>;
};

v_tc@a0000000 {
clock-names = "clk", "s_axi_aclk";
clocks = <0x33 0x3 0x47>;
compatible = "xlnx,v-tc-6.1", "xlnx,v-tc-6.1";
interrupt-names = "irq";
interrupt-parent = <0x4>;
interrupts = <0x0 0x5a 0x4>;
reg = <0x0 0xa0000000 0x0 0x10000>;
xlnx,generator;
status = "disabled";
};

misc_clk_0 {
#clock-cells = <0x0>;
clock-frequency = <0x47868c0>;
compatible = "fixed-clock";
status = "disabled";
linux,phandle = <0x33>;
phandle = <0x33>;
};
};
vdma and vtc are disabled
and inside chosen :
Code: [Select]
#address-cells = <0x1>;
#size-cells = <0x1>;
ranges;

framebuffer@0x7FC00000 {
compatible = "simple-framebuffer";
reg = <0x7fc00000 0x384000>;
width = <0x500>;
height = <0x2d0>;
stride = <0x1400>;
format = "a8b8g8r8";
status = "okay";
};
Maybe the framebuffer shouldn't be with the label okay? but if i don't, it doesn't initialize it.
i also tried with you small app (adv7511) but it doesn't recognize the address for the i2c... could the problem be there ? (but i2cdetect works…)
sorry for all the question
thank you in advance for your help :)
best regards
Sarah
Pages: [1] 2 3 ... 10