diff --git a/cheshire.mk b/cheshire.mk index 0cafc948..7d143de0 100644 --- a/cheshire.mk +++ b/cheshire.mk @@ -11,6 +11,9 @@ BENDER ?= bender VLOG_ARGS ?= -suppress 2583 -suppress 13314 VSIM ?= vsim +# Define board for FPGA flow and/or device tree selection +BOARD ?= vcu128 + # Define used paths (prefixed to avoid name conflicts) CHS_ROOT ?= $(shell $(BENDER) path cheshire) CHS_REG_DIR := $(shell $(BENDER) path register_interface) @@ -55,7 +58,7 @@ chs-clean-deps: ###################### CHS_NONFREE_REMOTE ?= git@iis-git.ee.ethz.ch:pulp-restricted/cheshire-nonfree.git -CHS_NONFREE_COMMIT ?= b11f9e5fbc97209da75e77c93a1e4e0460dddf6c +CHS_NONFREE_COMMIT ?= 0e70b230ea113c8d954329be5406b318cd62cc9a chs-nonfree-init: git clone $(CHS_NONFREE_REMOTE) $(CHS_ROOT)/nonfree diff --git a/sw/boot/cheshire.dts b/sw/boot/cheshire.dtsi similarity index 94% rename from sw/boot/cheshire.dts rename to sw/boot/cheshire.dtsi index dbef5e50..76decc85 100644 --- a/sw/boot/cheshire.dts +++ b/sw/boot/cheshire.dtsi @@ -7,11 +7,13 @@ // Axel Vanoni /dts-v1/; + / { #address-cells = <2>; #size-cells = <2>; compatible = "eth,cheshire-dev"; model = "eth,cheshire"; + chosen { stdout-path = "/soc/serial@3002000:115200"; }; @@ -74,22 +76,16 @@ interrupts = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 16>; reg = <0x0 0x3003000 0x0 0x1000>; }; - spi@3004000 { + spi: spi@3004000 { compatible = "opentitan,spi-host", "lowrisc,spi"; interrupt-parent = <&PLIC0>; interrupts = <17 18>; reg = <0x0 0x3004000 0x0 0x1000>; + num-cs = <2>; clock-frequency = <50000000>; max-frequency = <25000000>; #address-cells = <1>; #size-cells = <0>; - mmc@0 { - compatible = "mmc-spi-slot"; - reg = <0>; - spi-max-frequency = <25000000>; - voltage-ranges = <3300 3300>; - disable-wp; - }; }; vga@3007000 { compatible = "eth,axi-vga"; diff --git a/sw/boot/cheshire_genesys2.dts b/sw/boot/cheshire_genesys2.dts new file mode 100644 index 00000000..6f75f87c --- /dev/null +++ b/sw/boot/cheshire_genesys2.dts @@ -0,0 +1,17 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Cyril Koenig + +/include/ "cheshire.dtsi" + +&spi { + mmc@0 { + compatible = "mmc-spi-slot"; + reg = <0>; // CS + spi-max-frequency = <25000000>; + voltage-ranges = <3300 3300>; + disable-wp; + }; +}; diff --git a/sw/boot/cheshire_vcu128.dts b/sw/boot/cheshire_vcu128.dts new file mode 100644 index 00000000..bd603a8a --- /dev/null +++ b/sw/boot/cheshire_vcu128.dts @@ -0,0 +1,25 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Cyril Koenig + +/include/ "cheshire.dtsi" + +&spi { + nor@1 { + #address-cells = <0x1>; + #size-cells = <0x1>; + // Note : u-boot does not find mt25qu02g + compatible = "mt25qu02g", "jedec,spi-nor"; + reg = <0x1>; // CS + spi-max-frequency = <25000000>; + spi-rx-bus-width = <0x1>; + spi-tx-bus-width = <0x1>; + partition@0 { + label = "all"; + reg = <0x0 0x6000000>; // 96 MB + read-only; + }; + }; +}; diff --git a/sw/sw.mk b/sw/sw.mk index 6f4edf5d..f5fc0847 100644 --- a/sw/sw.mk +++ b/sw/sw.mk @@ -117,7 +117,7 @@ $(foreach link,$(patsubst $(CHS_SW_LD_DIR)/%.ld,%,$(wildcard $(CHS_SW_LD_DIR)/*. $(CHS_SW_OBJCOPY) -O binary $< $@ %.dtb: %.dts - $(CHS_SW_DTC) -I dts -O dtb -o $@ $< + $(CHS_SW_DTC) -I dts -O dtb -i $(CHS_SW_DIR)/boot -o $@ $< %.memh: %.elf $(CHS_SW_OBJCOPY) -O verilog $< $@ @@ -138,7 +138,7 @@ $(foreach link,$(patsubst $(CHS_SW_LD_DIR)/%.ld,%,$(wildcard $(CHS_SW_LD_DIR)/*. $(CHS_SW_OBJCOPY) -I binary -O verilog $< $@ # Create full Linux disk image -$(CHS_SW_DIR)/boot/linux.gpt.bin: $(CHS_SW_DIR)/boot/zsl.rom.bin $(CHS_SW_DIR)/boot/cheshire.dtb $(CHS_SW_DIR)/boot/install64/fw_payload.bin $(CHS_SW_DIR)/boot/install64/uImage +$(CHS_SW_DIR)/boot/linux.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 truncate -s $(CHS_SW_DISK_SIZE) $@ sgdisk --clear -g --set-alignment=1 \ --new=1:64:96 --typecode=1:$(CHS_SW_ZSL_TGUID) \ diff --git a/target/xilinx/README.md b/target/xilinx/README.md deleted file mode 100644 index a4e7c05c..00000000 --- a/target/xilinx/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# VCU128 emulation - -```bash -# Build the bitstream: -make -# Re-build the bitstream without -# re-building the IPs: -make rebuild-top -# Simulate with the IPs -# Note you need to generate the -# Vivado IP models before -make sim -``` diff --git a/target/xilinx/constraints/cheshire.xdc b/target/xilinx/constraints/cheshire.xdc index b53845ee..921b3fe7 100644 --- a/target/xilinx/constraints/cheshire.xdc +++ b/target/xilinx/constraints/cheshire.xdc @@ -97,9 +97,12 @@ set_false_path -hold -to [get_ports uart_tx_o] # CDCs # ######## -# cdc_fifo_gray: Disable hold checks, limit datapath delay and bus skew -set_property KEEP_HIERARCHY SOFT [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*i_sync] -set_false_path -hold -through [get_pins -of_objects [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*]] -through [get_pins -of_objects [get_cells i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*]] - +# Disable hold checks +set_property KEEP_HIERARCHY SOFT [get_cells -hier -filter {ORIG_REF_NAME=="sync" || REF_NAME=="sync"}] +# src false path set_false_path -hold -through [get_pins -of_objects [get_cells -hier -filter {ORIG_REF_NAME == axi_cdc_src || REF_NAME == axi_cdc_src}] -filter {NAME =~ *async*}] +# dst false path set_false_path -hold -through [get_pins -of_objects [get_cells -hier -filter {ORIG_REF_NAME == axi_cdc_dst || REF_NAME == axi_cdc_dst}] -filter {NAME =~ *async*}] + +# Limit datapath delay +# [see in board.xdc] diff --git a/target/xilinx/constraints/genesys2.xdc b/target/xilinx/constraints/genesys2.xdc index 8387ec19..281442ef 100644 --- a/target/xilinx/constraints/genesys2.xdc +++ b/target/xilinx/constraints/genesys2.xdc @@ -14,19 +14,30 @@ set_property CLOCK_BUFFER_TYPE NONE $all_in_mux # Sys clock # ############# -create_clock -period 5 -name sys_clk [get_pins u_ibufg_sys_clk/O] +# 200 MHz ref clock +set SYS_TCK 5 +create_clock -period $SYS_TCK -name sys_clk [get_pins u_ibufg_sys_clk/O] set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_pins u_ibufg_sys_clk/O] set_clock_groups -name sys_clk_async -asynchronous -group {sys_clk} - ############# # Mig clock # ############# -set MIG_RST [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk_sync_rst] -create_clock -period 5 -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +# Dram axi clock : ??? +set MIG_TCK 5 +set MIG_RST [get_pins i_dram_wrapper/i_dram/dram_rst_o] +create_clock -period $MIG_TCK -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/ui_clk] +set_clock_groups -name dram_async -asynchronous -group {dram_axi_clk} set_false_path -hold -through $MIG_RST -set_max_delay -through $MIG_RST 5 +set_max_delay -through $MIG_RST $MIG_TCK + +######## +# CDCs # +######## + +set_max_delay -through [get_nets -of_objects [get_cells i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*] -filter {NAME=~*async*}] $MIG_TCK +set_max_delay -datapath -from [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_dst_*/*i_sync/reg*/D] $FPGA_TCK ####### # VGA # diff --git a/target/xilinx/constraints/vcu128.xdc b/target/xilinx/constraints/vcu128.xdc index 6458d0cb..03e40ff7 100644 --- a/target/xilinx/constraints/vcu128.xdc +++ b/target/xilinx/constraints/vcu128.xdc @@ -6,7 +6,9 @@ # Sys clock # ############# -create_clock -period 10 -name sys_clk [get_pins u_ibufg_sys_clk/O] +# 100 MHz ref clock +set SYS_TCK 10 +create_clock -period $SYS_TCK -name sys_clk [get_pins u_ibufg_sys_clk/O] set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_pins u_ibufg_sys_clk/O] set_clock_groups -name sys_clk_async -asynchronous -group {sys_clk} @@ -14,14 +16,20 @@ set_clock_groups -name sys_clk_async -asynchronous -group {sys_clk} # Mig clock # ############# +# Dram axi clock : 833ps * 4 +set MIG_TCK 3.332 set MIG_RST [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk_sync_rst] -#create_clock -period 10 -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +create_clock -period $MIG_TCK -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +set_clock_groups -name dram_async -asynchronous -group {dram_axi_clk} set_false_path -hold -through $MIG_RST -set_max_delay -through $MIG_RST 10 +set_max_delay -through $MIG_RST $MIG_TCK -set_max_delay -datapath -from [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_dst_*/*i_sync/reg*/D] $FPGA_TCK -set_max_delay -datapath -from [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_dram_wrapper/i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/i_spill_register/spill_register_flushable_i/*reg*/D] $FPGA_TCK +######## +# CDCs # +######## +set_max_delay -through [get_nets -of_objects [get_cells i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*] -filter {NAME=~*async*}] $MIG_TCK +set_max_delay -datapath -from [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_dst_*/*i_sync/reg*/D] $FPGA_TCK ################################################################################# diff --git a/target/xilinx/constraints/zcu102.xdc b/target/xilinx/constraints/zcu102.xdc index 955d7720..c60b72cd 100644 --- a/target/xilinx/constraints/zcu102.xdc +++ b/target/xilinx/constraints/zcu102.xdc @@ -6,7 +6,9 @@ # Sys clock # ############# -create_clock -period 3.333 -name sys_clk [get_pins u_ibufg_sys_clk/O] +# 300 MHz ref clock +set SYS_TCK 3.332 +create_clock -period $SYS_TCK -name sys_clk [get_pins u_ibufg_sys_clk/O] set_property CLOCK_DEDICATED_ROUTE BACKBONE [get_pins u_ibufg_sys_clk/O] set_clock_groups -name sys_clk_async -asynchronous -group {sys_clk} @@ -14,10 +16,21 @@ set_clock_groups -name sys_clk_async -asynchronous -group {sys_clk} # Mig clock # ############# +# Dram axi clock : 833ps * 4 +set MIG_TCK 3.332 set MIG_RST [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk_sync_rst] -create_clock -period 3.333 -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +create_clock -period $MIG_TCK -name dram_axi_clk [get_pins i_dram_wrapper/i_dram/c0_ddr4_ui_clk] +set_clock_groups -name dram_async -asynchronous -group {dram_axi_clk} set_false_path -hold -through $MIG_RST -set_max_delay -through $MIG_RST 3.333 +set_max_delay -through $MIG_RST $MIG_TCK + +######## +# CDCs # +######## + +set_max_delay -through [get_nets -of_objects [get_cells i_dram_wrapper/gen_cdc.i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*] -filter {NAME=~*async*}] $MIG_TCK +set_max_delay -datapath -from [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_*/*reg*/C] -to [get_pins i_axi_cdc_mig/i_axi_cdc_*/i_cdc_fifo_gray_dst_*/*i_sync/reg*/D] $FPGA_TCK + ################################################################################# diff --git a/target/xilinx/scripts/run.tcl b/target/xilinx/scripts/run.tcl index db064783..29b28162 100644 --- a/target/xilinx/scripts/run.tcl +++ b/target/xilinx/scripts/run.tcl @@ -94,6 +94,11 @@ if ($DEBUG) { write_debug_probes -force probes.ltx } +# Incremental implementation +if {[info exists $::env(ROUTED_DCP)] && [file exists $::env(ROUTED_DCP)]} { + set_property incremental_checkpoint $ $::env(ROUTED_DCP) [get_runs impl_1] +} + # Implementation launch_runs impl_1 wait_on_run impl_1 @@ -112,7 +117,7 @@ if {[info exists ::env(CHECK_TIMING)] && $::env(CHECK_TIMING)==1} { # Output Verilog netlist + SDC for timing simulation write_verilog -force -mode funcsim out/${project}_funcsim.v write_verilog -force -mode timesim out/${project}_timesim.v -write_sdf -force out/${project}_timesim.sdf +# write_sdf -force out/${project}_timesim.sdf # Reports exec mkdir -p reports/ diff --git a/target/xilinx/src/cheshire_top_xilinx.sv b/target/xilinx/src/cheshire_top_xilinx.sv index 574eb61a..03423da9 100644 --- a/target/xilinx/src/cheshire_top_xilinx.sv +++ b/target/xilinx/src/cheshire_top_xilinx.sv @@ -48,11 +48,11 @@ module cheshire_top_xilinx `endif `ifdef USE_SD - input logic sd_cd_i, - output logic sd_cmd_o, - inout wire [3:0] sd_d_io, - output logic sd_reset_o, - output logic sd_sclk_o, + input logic sd_cd_i, // Card Detect + output logic sd_cmd_o, + inout wire [3:0] sd_d_io, + output logic sd_reset_o, + output logic sd_sclk_o, `endif `ifdef USE_FAN @@ -62,12 +62,7 @@ module cheshire_top_xilinx `ifdef USE_QSPI `ifndef USE_STARTUPE3 - output logic qspi_clk, - input logic qspi_dq0, - input logic qspi_dq1, - input logic qspi_dq2, - input logic qspi_dq3, - output logic qspi_cs_b, + // TODO: off-chip qspi interface `endif // USE_STARTUPE3 `endif // USE_QSPI @@ -361,17 +356,15 @@ module cheshire_top_xilinx // SPI Adaption // ////////////////// - logic spi_sck_soc; - logic [1:0] spi_cs_soc; - logic [3:0] spi_sd_soc_out; - logic [3:0] spi_sd_soc_in; + (* mark_debug = "true" *) logic spi_sck_soc; + (* mark_debug = "true" *) logic [1:0] spi_cs_soc; + (* mark_debug = "true" *) logic [3:0] spi_sd_soc_out; + (* mark_debug = "true" *) logic [3:0] spi_sd_soc_in; + + (* mark_debug = "true" *) logic spi_sck_en; + (* mark_debug = "true" *) logic [1:0] spi_cs_en; + (* mark_debug = "true" *) logic [3:0] spi_sd_en; - logic spi_sck_en; - logic [1:0] spi_cs_en; - logic [3:0] spi_sd_en; - logic spi_sck_en_n; - logic [1:0] spi_cs_en_n; - logic [3:0] spi_sd_en_n; ////////////////// // SD // @@ -401,24 +394,24 @@ module cheshire_top_xilinx ////////////////// `ifdef USE_QSPI - logic qspi_clk; - logic qspi_clk_ts; - logic [3:0] qspi_dqi; - logic [3:0] qspi_dqo_ts; - logic [3:0] qspi_dqo; - logic [SpihNumCs-1:0] qspi_cs_b; - logic [SpihNumCs-1:0] qspi_cs_b_ts; + (* mark_debug = "true" *) logic qspi_clk; + (* mark_debug = "true" *) logic qspi_clk_ts; + (* mark_debug = "true" *) logic [3:0] qspi_dqi; + (* mark_debug = "true" *) logic [3:0] qspi_dqo_ts; + (* mark_debug = "true" *) logic [3:0] qspi_dqo; + (* mark_debug = "true" *) logic [SpihNumCs-1:0] qspi_cs_b; + (* mark_debug = "true" *) logic [SpihNumCs-1:0] qspi_cs_b_ts; assign qspi_clk = spi_sck_soc; assign qspi_cs_b = spi_cs_soc; assign qspi_dqo = spi_sd_soc_out; assign spi_sd_soc_in = qspi_dqi; // Tristate - Enable - assign qspi_clk_ts = ~(spi_sck_en); - assign qspi_cs_b_ts = ~(spi_cs_en); - assign qspi_dqo_ts = ~(spi_sd_en); + assign qspi_clk_ts = ~spi_sck_en; + assign qspi_cs_b_ts = ~spi_cs_en; + assign qspi_dqo_ts = ~spi_sd_en; - // On VCU128, SPI ports are not directly available + // On VCU128/ZCU102, SPI ports are not directly available `ifdef USE_STARTUPE3 STARTUPE3 #( .PROG_USR("FALSE"), @@ -444,9 +437,7 @@ module cheshire_top_xilinx .USRDONETS (1'b1) ); `else - assign qspi_clk_o = qspi_clk; - assign qspi_dqi = qspi_dq_i; - assign qspi_cs_b_o = qspi_cs_b; + // TODO: off-chip qspi interface `endif // USE_STARTUPE3 `endif // USE_QSPI diff --git a/target/xilinx/src/dram_wrapper.sv b/target/xilinx/src/dram_wrapper.sv index 2c7fb4d3..56c0f4e2 100644 --- a/target/xilinx/src/dram_wrapper.sv +++ b/target/xilinx/src/dram_wrapper.sv @@ -32,8 +32,8 @@ module dram_wrapper #( `DDR3_INTF `endif // Dram axi interface - (* mark_debug = "true" *) input axi_soc_req_t soc_req_i, - (* mark_debug = "true" *) output axi_soc_resp_t soc_rsp_o + input axi_soc_req_t soc_req_i, + output axi_soc_resp_t soc_rsp_o ); //////////////////////////////////// diff --git a/target/xilinx/xilinx.mk b/target/xilinx/xilinx.mk index bd048cf6..129c0385 100644 --- a/target/xilinx/xilinx.mk +++ b/target/xilinx/xilinx.mk @@ -10,7 +10,6 @@ CHS_XIL_DIR ?= $(CHS_ROOT)/target/xilinx VIVADO ?= vitis-2020.2 vivado PROJECT ?= cheshire -BOARD ?= vcu128 ip-dir := $(CHS_XIL_DIR)/xilinx # Select board specific variables @@ -32,6 +31,9 @@ ifeq ($(BOARD),zcu102) XILINX_PART ?= xczu9eg-ffvb1156-2-e XILINX_BOARD ?= xilinx.com:zcu102:part0:3.4 ips-names := xlnx_mig_ddr4 xlnx_clk_wiz xlnx_vio + ifeq ($(INT_JTAG),1) + xilinx_targs += -t bscane + endif endif # Location of ip outputs @@ -55,7 +57,9 @@ VIVADOENV ?= PROJECT=$(PROJECT) \ HOST=$(XILINX_HOST) \ FPGA_PATH=$(FPGA_PATH) \ BIT=$(bit) \ - IP_PATHS="$(foreach ip-name,$(ips-names),xilinx/$(ip-name)/$(ip-name).srcs/sources_1/ip/$(ip-name)/$(ip-name).xci)" + IP_PATHS="$(foreach ip-name,$(ips-names),xilinx/$(ip-name)/$(ip-name).srcs/sources_1/ip/$(ip-name)/$(ip-name).xci)" \ + ROUTED_DCP=$(ROUTED_DCP) \ + CHECK_TIMING=$(CHECK_TIMING) MODE ?= gui VIVADOFLAGS ?= -nojournal -mode $(MODE) @@ -72,6 +76,7 @@ $(bit): $(ips) $(CHS_XIL_DIR)/scripts/add_sources.tcl cd $(CHS_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/prologue.tcl -source scripts/run.tcl cp $(CHS_XIL_DIR)/$(PROJECT).runs/impl_1/*.bit $(out) cp $(CHS_XIL_DIR)/$(PROJECT).runs/impl_1/*.ltx $(out) + cp $(CHS_XIL_DIR)/$(PROJECT).runs/impl_1/*.dcp $(out) # Generate ips %.xci: @@ -105,4 +110,4 @@ chs-xil-flash: $(CHS_SW_DIR)/boot/linux.gpt.bin $(CHS_XIL_DIR)/scripts/add_sources.tcl: Bender.yml $(BENDER) script vivado $(xilinx_targs) > $@ -.PHONY: chs-xil-gui chs-xil-program chs-xil-clean chs-xil-rebuild-top chs-xil-all \ No newline at end of file +.PHONY: chs-xil-gui chs-xil-program chs-xil-clean chs-xil-rebuild-top chs-xil-all