Skip to content

Commit

Permalink
fpga: Last review updates
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrilKoe committed Oct 3, 2023
1 parent cfafe6e commit 886a1f6
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 82 deletions.
4 changes: 2 additions & 2 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ sources:
- target/sim/src/fixture_cheshire_soc.sv
- target/sim/src/tb_cheshire_soc.sv

- target: any(fpga, xilinx)
- target: all(fpga, xilinx)
files:
- target/xilinx/src/fan_ctrl.sv
- target/xilinx/src/dram_wrapper.sv
- target/xilinx/src/dram_wrapper_xilinx.sv
- target/xilinx/src/phy_definitions.svh
- target/xilinx/src/cheshire_top_xilinx.sv
41 changes: 0 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,6 @@ run -all

If you have access to our internal servers, you can run `make nonfree-init` to fetch additional resources we cannot make publically accessible. Note that these are *not required* to use anything provided in this repository.

## Linux image

To build the Linux image for FPGA:
```bash
# Clone and build GCC, OpenSBI, U-Boot and Linux
git clone [email protected]:pulp-platform/cva6-sdk.git --branch fix/cheshire
cd cva6-sdk
git submodule update --init --recursive
make images
# Link the output in the sw dir
ln -s cva6-sdk/install64 sw/boot/install64
# Build the image at sw/boot/linux-[genesys2,vcu128].gpt.bin
make BOARD=[genesys2,vcu128] chs-linux-img

```

On Genesys2, you can now flash this image to your sd card (require sudo).

```bash
# Replace sdX by your SD card device
dd if=sw/boot/cheshire-linux-genesys2.gpt.bin of=/dev/sdX
```

On VCU128, you can now flash this image to the SPI using Vivado:

```bash
# Define XILINX_PORT, XILINX_HOST, FPGA_PATH to let Vivado find your FPGA
# See defaults in xilinx.mk
make chs-xil-flash BOARD=vcu128 MODE=batch
```

## FPGA

To build the bitstream for FPGA, initialize the repository with `make all` then run `make chs-xil-all` followed by desired arguments:

* `BOARD=[genesys2,vcu128]`: select supported evaluation board (note `zcu102` is also supported but do not boot Linux as access to an SPI flash or an SD card is not implemented).
* `INT-JTAG=[1,0]`: (only on vcu128) connect the debugger to the intenal JTAG chain (see BSCANE2 primitive) or to an external JTAG dongle (if 0).
* `MODE=[batch,gui]`: open Vivado GUI or execute in shell.

You can flash the bitstream from the GUI with `make chs-xil-gui` or directly in shell using `make chs-xil-program MODE=batch BOARD=[genesys2,vcu128]`. Here again you will need to define `XILINX_PORT`, `XILINX_HOST`, `FPGA_PATH` for your setup. At IIS, find default values in `carfield.mk`.

## License

Unless specified otherwise in the respective file headers, all code checked into this repository is made available under a permissive license. All hardware sources and tool scripts are licensed under the Solderpad Hardware License 0.51 (see `LICENSE`) with the exception of generated register file code (e.g. `hw/regs/*.sv`), which is generated by a fork of lowRISC's [`regtool`](https://github.com/lowRISC/opentitan/blob/master/util/regtool.py) and licensed under Apache 2.0. All software sources are licensed under Apache 2.0.
Expand Down
4 changes: 2 additions & 2 deletions cheshire.mk
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ chs-clean-deps:
######################

CHS_NONFREE_REMOTE ?= [email protected]:pulp-restricted/cheshire-nonfree.git
CHS_NONFREE_COMMIT ?= f70c019
CHS_NONFREE_COMMIT ?= 4e562fc

chs-nonfree-init:
git clone $(CHS_NONFREE_REMOTE) $(CHS_ROOT)/nonfree
Expand Down Expand Up @@ -162,7 +162,7 @@ CHS_SIM_ALL += $(CHS_ROOT)/target/sim/vsim/compile.cheshire_soc.tcl
#############

include $(CHS_ROOT)/target/xilinx/xilinx.mk
include $(CHS_XIL_DIR)/sim/simulate.mk
include $(CHS_XIL_DIR)/sim/sim.mk
CHS_XILINX_ALL += $(CHS_XIL_DIR)/scripts/add_sources.tcl
CHS_LINUX_IMG += $(CHS_SW_DIR)/boot/linux-${BOARD}.gpt.bin

Expand Down
62 changes: 59 additions & 3 deletions docs/tg/xilinx.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This page describes how to map Cheshire on Xilinx FPGAs to *execute baremetal pr
We currently provide working setups for:

- Digilent Genesys 2 with Vivado `>= 2020.2`
- Xilinx VCU128 with Vivado `>= 2020.2`

We are working on support for more boards in the future.

Expand All @@ -19,9 +20,14 @@ Since the implementation steps and available features vary between boards, we pr
Generate the bitstream `target/xilinx/out/cheshire_top_xilinx.bit` by running:

```
make -C target/xilinx
make chs-xil-all BOARD=genesys2 MODE=[batch,gui]
```

See the argument list below:

* `VIVADO`: The Vivado version to use (see default in `target/xilinx/xilinx.mk`)
* `MODE`: If 'batch', compile in shell, if 'gui', Open Vivado GUI.

Before flashing the bitstream to your device, take note of the position of onboard switches, which control important functionality:


Expand All @@ -33,6 +39,37 @@ Before flashing the bitstream to your device, take note of the position of onboa

The reset, JTAG TAP, UART, I2C, and VGA are all connected to their onboard logic or ports. The UART has *no flow control*. The microSD slot is connected to chip select 0 of the SPI host peripheral. Serial link and GPIOs are currently not available.

### Xilinx VCU128

Generate the bitstream `target/xilinx/out/cheshire_top_xilinx.bit` by running:

```
make chs-xil-all BOARD=vcu128 MODE=[batch,gui] INT-JTAG=[0,1]
```

See the argument list below:

* `INT-JTAG`: If 1, use an external JTAG chain (we use a Digilent JTAG-HS2 cable connected to the Xilinx XM105 FMC debug card). See the connections in `vcu128.xdc`.


As there are no switches on this board, the bootmode is selected by VIO (see next section).

## Using the Vivado GUI

Even after implementing your system in batch mode, you can open the Vivado GUI with:

```
make chs-xil-gui
```

In particular, it will give you access the to Virtual Inputs Outputs (VIOs) after flashing/refreshing the FPGA:

| VIO | Function |
| ----------------- | ----------------------------------------------------------------|
| vio_reset | Positive edge-sensitive reset for the whole system |
| vio_boot_mode | Override the boot-mode switches described above |
| vio_boot_mode_sel | Select between 0: using boot mode switches 1: use boot mode VIO |

## Debugging with OpenOCD

To establish a debug bridge over JTAG, ensure the target is in a debuggable state (for example by resetting into the idle boot mode 0) and launch OpenOCD with:
Expand Down Expand Up @@ -86,7 +123,7 @@ First, build an up-to-date a disk image for your desired binary. For `helloworld
make sw/tests/helloworld.gpt.bin
```

Then flash this image to an SD card (*note that this requires root privileges*):
Then flash this image to an SD card (for Genesys2) (*note that this requires root privileges*):

```
sudo dd if=sw/tests/helloworld.gpt.bin of=/dev/<sdcard>
Expand Down Expand Up @@ -115,9 +152,12 @@ In this case, OpenSBI is loaded by a regular baremetal program called the [Zero-
To create a full Linux disk image from the ZSL, device tree, firmware, and Linux, run:

```
make sw/boot/linux.gpt.bin
# Note that the device tree depends from the board's peripherals
make chs-linux-img BOARD=[genesys2, vcu128]
```

### Digilent Genesys 2

Flash this image to an SD card as you did in the previous section, then insert the SD card and reset into boot mode 1. You should first see the ZSL print on the UART:

```
Expand All @@ -131,3 +171,19 @@ Flash this image to an SD card as you did in the previous section, then insert t
( ))))))))))
```
You should then boot through OpenSBI, U-Boot, and Linux until you are dropped into a shell.

### Xilinx VCU128

This board does not offer a SD card reader. We use the integrated flash:

```
make chs-xil-flash MODE=batch BOARD=vcu128
```

Use the following parameters (defaults are in `target/xilinx/xilinx.mk`) to select your board:

* XILINX_PART : The FPGA part (leave to default)
* XILINX_BOARD : The FPGA board (leave to default)
* XILINX_HOST : The server where your board is connected (or localhost)
* XILINX_PORT : The port opened by Vivado for your board (Vivado usually sets it to 3121)
* VIVADO_PATH : The path to your board as seen in the Vivado Hardware Manager (usually xilinx_tcf/Xilinx/`SerialID`)
2 changes: 1 addition & 1 deletion sw/lib/hal/uart_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int uart_debug_init(void *uart_base, uint64_t core_freq) {
CHECK_ASSERT(0x11, uart_base != 0);
CHECK_ASSERT(0x12, core_freq != 0);
// The UART debug mode uses the sane default 115.2kBaud
uart_init(uart_base, core_freq, 115200);
uart_init(uart_base, core_freq, __BAUDRATE);
fence();
// Nothing went wrong
return 0;
Expand Down
2 changes: 1 addition & 1 deletion sw/sw.mk
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ $(foreach link,$(patsubst $(CHS_SW_LD_DIR)/%.ld,%,$(wildcard $(CHS_SW_LD_DIR)/*.
CHS_CVA6_SDK_IMGS ?= $(addprefix $(CHS_SW_DIR)/deps/cva6-sdk/install64/,fw_payload.bin uImage)

# Create full Linux disk image
$(CHS_SW_DIR)/boot/linux-${BOARD}.gpt.bin: $(CHS_SW_DIR)/boot/zsl.rom.bin $(CHS_SW_DIR)/boot/cheshire_$(BOARD).dtb $(CHS_SW_DIR)/boot/install64/fw_payload.bin $(CHS_SW_DIR)/boot/install64/uImage
$(CHS_SW_DIR)/boot/linux-${BOARD}.gpt.bin: $(CHS_SW_DIR)/boot/zsl.rom.bin $(CHS_SW_DIR)/boot/cheshire_$(BOARD).dtb $(CHS_CVA6_SDK_IMGS)
truncate -s $(CHS_SW_DISK_SIZE) $@
sgdisk --clear -g --set-alignment=1 \
--new=1:64:96 --typecode=1:$(CHS_SW_ZSL_TGUID) \
Expand Down
2 changes: 1 addition & 1 deletion sw/tests/helloworld.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ int main(void) {
char str[] = "Hello World!\r\n";
uint32_t rtc_freq = *reg32(&__base_regs, CHESHIRE_RTC_FREQ_REG_OFFSET);
uint64_t reset_freq = clint_get_core_freq(rtc_freq, 2500);
uart_init(&__base_uart, reset_freq, 115200);
uart_init(&__base_uart, reset_freq, __BAUDRATE);
uart_write_str(&__base_uart, str, sizeof(str));
uart_write_flush(&__base_uart);
return 0;
Expand Down
58 changes: 29 additions & 29 deletions target/xilinx/constraints/genesys2.xdc
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ set_max_delay -datapath \
# VGA #
#######

# set_output_delay -min -clock $soc_clk [expr $SOC_TCK * 0.10] [get_ports vga*]
# set_output_delay -max -clock $soc_clk [expr $SOC_TCK * 0.35] [get_ports vga*]
set_output_delay -min -clock $soc_clk [expr $SOC_TCK * 0.10] [get_ports vga*]
set_output_delay -max -clock $soc_clk [expr $SOC_TCK * 0.35] [get_ports vga*]

############
# Switches #
Expand Down Expand Up @@ -95,11 +95,11 @@ set_output_delay -max -clock $soc_clk [expr 0.20 * $SOC_TCK] [get_ports {sd_d_*
# I2C #
#######

# set_max_delay [expr $I2C_IO_SPEED * 0.35] -from [get_ports {i2c_scl_io i2c_sda_io}]
# set_false_path -hold -from [get_ports {i2c_scl_io i2c_sda_io}]
set_max_delay [expr $I2C_IO_SPEED * 0.35] -from [get_ports {i2c_scl_io i2c_sda_io}]
set_false_path -hold -from [get_ports {i2c_scl_io i2c_sda_io}]

# set_max_delay [expr $I2C_IO_SPEED * 0.35] -to [get_ports {i2c_scl_io i2c_sda_io}]
# set_false_path -hold -to [get_ports {i2c_scl_io i2c_sda_io}]
set_max_delay [expr $I2C_IO_SPEED * 0.35] -to [get_ports {i2c_scl_io i2c_sda_io}]
set_false_path -hold -to [get_ports {i2c_scl_io i2c_sda_io}]

#################################################################################

Expand Down Expand Up @@ -188,27 +188,27 @@ set_property -dict { PACKAGE_PIN R28 IOSTANDARD LVCMOS33 } [get_ports { sd_scl
#set_property -dict { PACKAGE_PIN AK14 IOSTANDARD LVCMOS15 } [get_ports { ETH_TX_EN }]; #IO_L20P_T3_33 Sch=eth_tx_en

## VGA Connector
# set_property -dict { PACKAGE_PIN AH20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L22N_T3_12 Sch=vga_b[3]
# set_property -dict { PACKAGE_PIN AG20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L22P_T3_12 Sch=vga_b[4]
# set_property -dict { PACKAGE_PIN AF21 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L19N_T3_VREF_12 Sch=vga_b[5]
# set_property -dict { PACKAGE_PIN AK20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L24P_T3_12 Sch=vga_b[6]
# set_property -dict { PACKAGE_PIN AG22 IOSTANDARD LVCMOS33 } [get_ports { vga_b[4] }]; #IO_L20P_T3_12 Sch=vga_b[7]

# set_property -dict { PACKAGE_PIN AJ23 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L21N_T3_DQS_12 Sch=vga_g[2]
# set_property -dict { PACKAGE_PIN AJ22 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L21P_T3_DQS_12 Sch=vga_g[3]
# set_property -dict { PACKAGE_PIN AH22 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L20N_T3_12 Sch=vga_g[4]
# set_property -dict { PACKAGE_PIN AK21 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L24N_T3_12 Sch=vga_g[5]
# set_property -dict { PACKAGE_PIN AJ21 IOSTANDARD LVCMOS33 } [get_ports { vga_g[4] }]; #IO_L23N_T3_12 Sch=vga_g[6]
# set_property -dict { PACKAGE_PIN AK23 IOSTANDARD LVCMOS33 } [get_ports { vga_g[5] }]; #IO_L17P_T2_12 Sch=vga_g[7]

# set_property -dict { PACKAGE_PIN AK25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L15N_T2_DQS_12 Sch=vga_r[3]
# set_property -dict { PACKAGE_PIN AG25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L18P_T2_12 Sch=vga_r[4]
# set_property -dict { PACKAGE_PIN AH25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L18N_T2_12 Sch=vga_r[5]
# set_property -dict { PACKAGE_PIN AK24 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L17N_T2_12 Sch=vga_r[6]
# set_property -dict { PACKAGE_PIN AJ24 IOSTANDARD LVCMOS33 } [get_ports { vga_r[4] }]; #IO_L15P_T2_DQS_12 Sch=vga_r[7]

# set_property -dict { PACKAGE_PIN AF20 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L19P_T3_12 Sch=vga_hs
# set_property -dict { PACKAGE_PIN AG23 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L13N_T2_MRCC_12 Sch=vga_vs
set_property -dict { PACKAGE_PIN AH20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[0] }]; #IO_L22N_T3_12 Sch=vga_b[3]
set_property -dict { PACKAGE_PIN AG20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[1] }]; #IO_L22P_T3_12 Sch=vga_b[4]
set_property -dict { PACKAGE_PIN AF21 IOSTANDARD LVCMOS33 } [get_ports { vga_b[2] }]; #IO_L19N_T3_VREF_12 Sch=vga_b[5]
set_property -dict { PACKAGE_PIN AK20 IOSTANDARD LVCMOS33 } [get_ports { vga_b[3] }]; #IO_L24P_T3_12 Sch=vga_b[6]
set_property -dict { PACKAGE_PIN AG22 IOSTANDARD LVCMOS33 } [get_ports { vga_b[4] }]; #IO_L20P_T3_12 Sch=vga_b[7]

set_property -dict { PACKAGE_PIN AJ23 IOSTANDARD LVCMOS33 } [get_ports { vga_g[0] }]; #IO_L21N_T3_DQS_12 Sch=vga_g[2]
set_property -dict { PACKAGE_PIN AJ22 IOSTANDARD LVCMOS33 } [get_ports { vga_g[1] }]; #IO_L21P_T3_DQS_12 Sch=vga_g[3]
set_property -dict { PACKAGE_PIN AH22 IOSTANDARD LVCMOS33 } [get_ports { vga_g[2] }]; #IO_L20N_T3_12 Sch=vga_g[4]
set_property -dict { PACKAGE_PIN AK21 IOSTANDARD LVCMOS33 } [get_ports { vga_g[3] }]; #IO_L24N_T3_12 Sch=vga_g[5]
set_property -dict { PACKAGE_PIN AJ21 IOSTANDARD LVCMOS33 } [get_ports { vga_g[4] }]; #IO_L23N_T3_12 Sch=vga_g[6]
set_property -dict { PACKAGE_PIN AK23 IOSTANDARD LVCMOS33 } [get_ports { vga_g[5] }]; #IO_L17P_T2_12 Sch=vga_g[7]

set_property -dict { PACKAGE_PIN AK25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[0] }]; #IO_L15N_T2_DQS_12 Sch=vga_r[3]
set_property -dict { PACKAGE_PIN AG25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[1] }]; #IO_L18P_T2_12 Sch=vga_r[4]
set_property -dict { PACKAGE_PIN AH25 IOSTANDARD LVCMOS33 } [get_ports { vga_r[2] }]; #IO_L18N_T2_12 Sch=vga_r[5]
set_property -dict { PACKAGE_PIN AK24 IOSTANDARD LVCMOS33 } [get_ports { vga_r[3] }]; #IO_L17N_T2_12 Sch=vga_r[6]
set_property -dict { PACKAGE_PIN AJ24 IOSTANDARD LVCMOS33 } [get_ports { vga_r[4] }]; #IO_L15P_T2_DQS_12 Sch=vga_r[7]

set_property -dict { PACKAGE_PIN AF20 IOSTANDARD LVCMOS33 } [get_ports { vga_hs }]; #IO_L19P_T3_12 Sch=vga_hs
set_property -dict { PACKAGE_PIN AG23 IOSTANDARD LVCMOS33 } [get_ports { vga_vs }]; #IO_L13N_T2_MRCC_12 Sch=vga_vs

## HDMI in
#set_property -dict { PACKAGE_PIN Y21 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_cec }]; #IO_L2P_T0_12 Sch=hdmi_rx_cec
Expand Down Expand Up @@ -506,8 +506,8 @@ set_property -dict { PACKAGE_PIN Y29 IOSTANDARD LVCMOS33 } [get_ports { jtag_t
#set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports { QSPI_D[3] }]; #IO_L2N_T0_D03_14 Sch=qspi_d[3]

## IIC Bus
# set_property -dict { PACKAGE_PIN AE30 IOSTANDARD LVCMOS33 } [get_ports { i2c_scl_io }]; #IO_L16P_T2_13 Sch=sys_scl
# set_property -dict { PACKAGE_PIN AF30 IOSTANDARD LVCMOS33 } [get_ports { i2c_sda_io }]; #IO_L16N_T2_13 Sch=sys_sda
set_property -dict { PACKAGE_PIN AE30 IOSTANDARD LVCMOS33 } [get_ports { i2c_scl_io }]; #IO_L16P_T2_13 Sch=sys_scl
set_property -dict { PACKAGE_PIN AF30 IOSTANDARD LVCMOS33 } [get_ports { i2c_sda_io }]; #IO_L16N_T2_13 Sch=sys_sda

## Display Port IN
#set_property -dict { PACKAGE_PIN AC19 IOSTANDARD LVCMOS18 } [get_ports { RX_AUX_IN_CH_N }]; #IO_L17N_T2_32 Sch=rx_aux_ch_n
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion target/xilinx/src/cheshire_top_xilinx.sv
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ module cheshire_top_xilinx
//////////////

`ifdef USE_DDR
dram_wrapper #(
dram_wrapper_xilinx #(
.axi_soc_aw_chan_t ( axi_llc_aw_chan_t ),
.axi_soc_w_chan_t ( axi_llc_w_chan_t ),
.axi_soc_b_chan_t ( axi_llc_b_chan_t ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
`include "phy_definitions.svh"
`include "common_cells/registers.svh"

module dram_wrapper #(
module dram_wrapper_xilinx #(
parameter type axi_soc_aw_chan_t = logic,
parameter type axi_soc_w_chan_t = logic,
parameter type axi_soc_b_chan_t = logic,
Expand Down
2 changes: 2 additions & 0 deletions target/xilinx/src/phy_definitions.svh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
`define USE_DDR3
`define USE_FAN
`define USE_VIO
`define USE_I2C
`define USE_VGA
`endif

`ifdef TARGET_ZCU102
Expand Down

0 comments on commit 886a1f6

Please sign in to comment.