From bed1db467a8b2778b468fbbae12825b5827f1a64 Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Thu, 25 Jul 2019 15:26:58 +0200 Subject: [PATCH 1/8] ZCU104: Add board target (copy from genesys2) --- fpga/.gitignore | 2 + fpga/Makefile | 15 +- fpga/pulpissimo-zcu104/.gitignore | 22 ++ fpga/pulpissimo-zcu104/Makefile | 44 ++++ fpga/pulpissimo-zcu104/constraints/zcu104.xdc | 213 ++++++++++++++++++ fpga/pulpissimo-zcu104/elf_run.gdb | 4 + fpga/pulpissimo-zcu104/elf_run.sh | 17 ++ fpga/pulpissimo-zcu104/fpga-settings.mk | 12 + .../ips/xilinx_clk_mngr/.gitignore | 21 ++ .../ips/xilinx_clk_mngr/Makefile | 30 +++ .../ips/xilinx_clk_mngr/tcl/run.tcl | 49 ++++ .../ips/xilinx_interleaved_ram/.gitignore | 21 ++ .../ips/xilinx_interleaved_ram/Makefile | 30 +++ .../ips/xilinx_interleaved_ram/tcl/run.tcl | 38 ++++ .../ips/xilinx_private_ram/.gitignore | 21 ++ .../ips/xilinx_private_ram/Makefile | 30 +++ .../ips/xilinx_private_ram/tcl/run.tcl | 38 ++++ .../ips/xilinx_slow_clk_mngr/.gitignore | 21 ++ .../ips/xilinx_slow_clk_mngr/Makefile | 30 +++ .../ips/xilinx_slow_clk_mngr/tcl/run.tcl | 44 ++++ fpga/pulpissimo-zcu104/openocd-zcu104.cfg | 46 ++++ fpga/pulpissimo-zcu104/rtl/fpga_bootrom.sv | 36 +++ fpga/pulpissimo-zcu104/rtl/fpga_clk_gen.sv | 74 ++++++ .../rtl/fpga_interleaved_ram.sv | 57 +++++ .../pulpissimo-zcu104/rtl/fpga_private_ram.sv | 57 +++++ .../rtl/fpga_slow_clk_gen.sv | 37 +++ .../rtl/pad_functional_xilinx.sv | 48 ++++ .../rtl/pulp_clock_gating_xilinx.sv | 21 ++ .../pulpissimo-zcu104/rtl/xilinx_pulpissimo.v | 148 ++++++++++++ fpga/pulpissimo-zcu104/tcl/.gitignore | 6 + fpga/pulpissimo-zcu104/tcl/messages.tcl | 13 ++ fpga/pulpissimo-zcu104/tcl/run.tcl | 132 +++++++++++ 32 files changed, 1375 insertions(+), 2 deletions(-) create mode 100644 fpga/pulpissimo-zcu104/.gitignore create mode 100644 fpga/pulpissimo-zcu104/Makefile create mode 100644 fpga/pulpissimo-zcu104/constraints/zcu104.xdc create mode 100644 fpga/pulpissimo-zcu104/elf_run.gdb create mode 100755 fpga/pulpissimo-zcu104/elf_run.sh create mode 100644 fpga/pulpissimo-zcu104/fpga-settings.mk create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/.gitignore create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/Makefile create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/.gitignore create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/Makefile create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/tcl/run.tcl create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_private_ram/.gitignore create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_private_ram/Makefile create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_private_ram/tcl/run.tcl create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/.gitignore create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/Makefile create mode 100644 fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl create mode 100644 fpga/pulpissimo-zcu104/openocd-zcu104.cfg create mode 100644 fpga/pulpissimo-zcu104/rtl/fpga_bootrom.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/fpga_clk_gen.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/fpga_interleaved_ram.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/fpga_private_ram.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/fpga_slow_clk_gen.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/pad_functional_xilinx.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/pulp_clock_gating_xilinx.sv create mode 100644 fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v create mode 100644 fpga/pulpissimo-zcu104/tcl/.gitignore create mode 100644 fpga/pulpissimo-zcu104/tcl/messages.tcl create mode 100644 fpga/pulpissimo-zcu104/tcl/run.tcl diff --git a/fpga/.gitignore b/fpga/.gitignore index e97d6170..c764b3a0 100644 --- a/fpga/.gitignore +++ b/fpga/.gitignore @@ -1,3 +1,5 @@ pulpissimo/* pulpissimo_genesys2.bin pulpissimo_genesys2.bit +pulpissimo_zcu104.bin +pulpissimo_zcu104.bit diff --git a/fpga/Makefile b/fpga/Makefile index 520776ca..16c1c5a2 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -1,8 +1,8 @@ .DEFAULT_GOAL:=help -all: genesys2 ## Generates the bitstream for all supported boards board. +all: genesys2 zcu104 ## Generates the bitstream for all supported boards board. -clean_all: clean_genesys2 ## Removes synthesis output and bitstreams for all boards. +clean_all: clean_genesys2 clean_zcu104 ## Removes synthesis output and bitstreams for all boards. genesys2: ## Generates the bistream for the genesys2 board cd pulpissimo-genesys2; make all @@ -15,6 +15,17 @@ clean_genesys2: ## Removes all bitstreams, *.log files and vivado related files rm -f pulpissimo_genesys2.bit rm -f pulpissimo_genesys2.bin +zcu104: ## Generates the bistream for the zcu104 board + cd pulpissimo-zcu104; make all + cp pulpissimo-zcu104/pulpissimo_zcu104.runs/impl_1/xilinx_pulpissimo.bit pulpissimo_zcu104.bit + cp pulpissimo-zcu104/pulpissimo_zcu104.runs/impl_1/xilinx_pulpissimo.bin pulpissimo_zcu104.bin + @echo "Bitstream generation for zcu104 board finished. The bitstream Configuration Memory File was copied to ./pulpissimo_zcu104.bit and ./pulpissimo_zcu104.bin" + +clean_zcu104: ## Removes all bitstreams, *.log files and vivado related files (rm -rf vivado*) for the zcu104 board. + cd pulpissimo-zcu104; make clean + rm -f pulpissimo_zcu104.bit + rm -f pulpissimo_zcu104.bin + help: ## Show this help message @echo "PULPissimo on FPGA" @echo "" diff --git a/fpga/pulpissimo-zcu104/.gitignore b/fpga/pulpissimo-zcu104/.gitignore new file mode 100644 index 00000000..3f35710f --- /dev/null +++ b/fpga/pulpissimo-zcu104/.gitignore @@ -0,0 +1,22 @@ +#Ignore vivado project files generated by the tcl script +**/.Xil/* +**/reports/* +**/*.cache/* +**/*.hw/* +**/*.ip_user_files/* +**/*.runs/* +**/*.sim/* +**/*.srcs/* +*.edf +*.xpr +*.jou +*.log + +.cxl.* + +*_stub.v +gmon.out + +/pulpissimo/**/pulpissimo.bit + +**/xdc/constraints.xdc diff --git a/fpga/pulpissimo-zcu104/Makefile b/fpga/pulpissimo-zcu104/Makefile new file mode 100644 index 00000000..83eb5390 --- /dev/null +++ b/fpga/pulpissimo-zcu104/Makefile @@ -0,0 +1,44 @@ +PROJECT:=pulpissimo_zcu104 +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl + +include fpga-settings.mk + +.DEFAULT_GOAL:=help + +.PHONY: help + +all: ips ## Generate the bitstream for pulpissimo with vivado in batch mode. The vivado invocation command may be overriden with the env variable VIVADO. + $(VIVADO) -mode batch -source tcl/run.tcl + +gui: ips ## Generates the bitstream for pulpissimo with vivado in GUI mode. The vivado invocation command may be overriden with the env variable VIVADO. + $(VIVADO) -mode gui -source tcl/run.tcl & + +ips: clk ram ## Synthesizes necessary xilinx IP + +clean-ips: clean-clk clean-ram ## Clean all IPs + +clk: ## Synthesizes the Xilinx Clocking Manager IPs + cd ips/xilinx_clk_mngr; make clean all + cd ips/xilinx_slow_clk_mngr; make clean all + +clean-clk: ## Removes all Clocking Wizard IP outputs + cd ips/xilinx_clk_mngr; make clean + cd ips/xilinx_slow_clk_mngr; make clean + +ram: ## Synthesizes the Xilinx Block Memory Generator IPs for PULPissimo's L2 Ram + cd ips/xilinx_interleaved_ram; make clean all + cd ips/xilinx_private_ram; make clean all + +clean-ram: ## Removes all Block Ram IP outputs related to l2 ram + cd ips/xilinx_interleaved_ram; make clean + cd ips/xilinx_private_ram; make clean + +clean: ## Removes all bitstreams, *.log files and vivado related files (rm -rf vivado*) + rm -rf ${PROJECT}.*[^'bit'] + rm -rf ${PROJECT}.*[^'bin'] + rm -rf *.log + rm -rf vivado* + +help: + @grep -E -h '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc new file mode 100644 index 00000000..2c24722c --- /dev/null +++ b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc @@ -0,0 +1,213 @@ +####################################### +# _______ _ _ # +# |__ __(_) (_) # +# | | _ _ __ ___ _ _ __ __ _ # +# | | | | '_ ` _ \| | '_ \ / _` | # +# | | | | | | | | | | | | | (_| | # +# |_| |_|_| |_| |_|_|_| |_|\__, | # +# __/ | # +# |___/ # +####################################### + + +#Create constraint for the clock input of the zcu104 board +create_clock -period 5.000 -name ref_clk [get_ports ref_clk_p] + +#I2S and CAM interface are not used in this FPGA port. Set constraints to +#disable the clock +set_case_analysis 0 i_pulpissimo/safe_domain_i/cam_pclk_o +set_case_analysis 0 i_pulpissimo/safe_domain_i/i2s_slave_sck_o +#set_input_jitter tck 1.000 + +## JTAG +create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports pad_jtag_tck] +set_input_jitter tck 1.000 + + +# minimize routing delay +set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tdi] +set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tms] +set_output_delay -clock tck 5.000 [get_ports pad_jtag_tdo] +set_false_path -from [get_ports pad_jtag_trst] + +set_max_delay -to [get_ports pad_jtag_tdo] 20.000 +set_max_delay -from [get_ports pad_jtag_tms] 20.000 +set_max_delay -from [get_ports pad_jtag_tdi] 20.000 +set_max_delay -from [get_ports pad_jtag_trst] 20.000 + +set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 20.000 +set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 20.000 +set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_src/ack_src_q_reg/D] 20.000 + + +# reset signal +set_false_path -from [get_ports pad_reset_n] + +# Set ASYNC_REG attribute for ff synchronizers to place them closer together and +# increase MTBF +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/apb_adv_timer_i/u_tim0/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/apb_adv_timer_i/u_tim1/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/apb_adv_timer_i/u_tim2/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/apb_adv_timer_i/u_tim3/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/i_apb_timer_unit/s_ref_clk*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/i_ref_clk_sync/i_pulp_sync/r_reg_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_peripherals_i/u_evnt_gen/r_ls_sync_reg*] + +# Create asynchronous clock group between slow-clk and SoC clock. Those clocks +# are considered asynchronously and proper synchronization regs are in place +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/safe_domain_i/i_slow_clk_gen/i_slow_clk_mngr/inst/mmcm_adv_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_clk_rst_gen/i_fpga_clk_gen/i_clk_manager/inst/mmcm_adv_inst/CLKOUT0]] + + +############################################################# +# _____ ____ _____ _ _ _ # +# |_ _/ __ \ / ____| | | | | (_) # +# | || | | |_____| (___ ___| |_| |_ _ _ __ __ _ ___ # +# | || | | |______\___ \ / _ \ __| __| | '_ \ / _` / __| # +# _| || |__| | ____) | __/ |_| |_| | | | | (_| \__ \ # +# |_____\____/ |_____/ \___|\__|\__|_|_| |_|\__, |___/ # +# __/ | # +# |___/ # +############################################################# + +## Sys clock +set_property -dict {PACKAGE_PIN AD11 IOSTANDARD LVDS} [get_ports ref_clk_n] +set_property -dict {PACKAGE_PIN AD12 IOSTANDARD LVDS} [get_ports ref_clk_p] + + +## Buttons +set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS33} [get_ports pad_reset_n] +set_property -dict {PACKAGE_PIN E18 IOSTANDARD LVCMOS12} [get_ports btnc_i] +set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS12} [get_ports btnd_i] +set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS12} [get_ports btnl_i] +set_property -dict {PACKAGE_PIN C19 IOSTANDARD LVCMOS12} [get_ports btnr_i] +set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS12} [get_ports btnu_i] + +## To use FTDI FT2232 JTAG +set_property -dict {PACKAGE_PIN Y29 IOSTANDARD LVCMOS33} [get_ports pad_jtag_trst] +set_property -dict {PACKAGE_PIN AD27 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tck] +set_property -dict {PACKAGE_PIN W27 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdi] +set_property -dict {PACKAGE_PIN W28 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdo] +set_property -dict {PACKAGE_PIN W29 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tms] + +## UART +set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS33} [get_ports pad_uart_tx] +set_property -dict {PACKAGE_PIN Y20 IOSTANDARD LVCMOS33} [get_ports pad_uart_rx] + +## LEDs +set_property -dict {PACKAGE_PIN T28 IOSTANDARD LVCMOS33} [get_ports led0_o] +set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports led1_o] +set_property -dict {PACKAGE_PIN U30 IOSTANDARD LVCMOS33} [get_ports led2_o] +set_property -dict {PACKAGE_PIN U29 IOSTANDARD LVCMOS33} [get_ports led3_o] +#set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports ] +#set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS33} [get_ports ] +#set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS33} [get_ports ] +#set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS33} [get_ports ] + +## Switches +set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS12} [get_ports switch0_i] +set_property -dict {PACKAGE_PIN G25 IOSTANDARD LVCMOS12} [get_ports switch1_i] +#set_property -dict {PACKAGE_PIN H24 IOSTANDARD LVCMOS12} [get_ports {}] +# set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS12} [get_ports {}] +# set_property -dict {PACKAGE_PIN N19 IOSTANDARD LVCMOS12} [get_ports {}] +# set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS12} [get_ports {}] +# set_property -dict {PACKAGE_PIN P26 IOSTANDARD LVCMOS33} [get_ports {}] +# set_property -dict {PACKAGE_PIN P27 IOSTANDARD LVCMOS33} [get_ports {}] + +## I2C Bus +set_property -dict {PACKAGE_PIN AE30 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_scl] +set_property -dict {PACKAGE_PIN AF30 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_sda] + +## QSPI Flash +set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVCMOS33} [get_ports pad_spim_csn0] +#set_property -dict { PACKAGE_PIN P24 IOSTANDARD LVCMOS33 } [get_ports { pad_spim_sdio0 }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_d[0] +set_property -dict {PACKAGE_PIN R25 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio1] +set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio2] +set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio3] + + +## OLED Display +set_property -dict {PACKAGE_PIN AC17 IOSTANDARD LVCMOS18} [get_ports oled_dc_o] +set_property -dict {PACKAGE_PIN AB17 IOSTANDARD LVCMOS18} [get_ports oled_rst_o] +set_property -dict {PACKAGE_PIN AF17 IOSTANDARD LVCMOS18} [get_ports oled_spim_sck_o] +set_property -dict {PACKAGE_PIN Y15 IOSTANDARD LVCMOS18} [get_ports oled_spim_mosi_o] +set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS33} [get_ports oled_vbat_o] +set_property -dict {PACKAGE_PIN AG17 IOSTANDARD LVCMOS18} [get_ports oled_vdd_o] + + +############################################# +## SD Card +############################################# +#set_property -dict { PACKAGE_PIN P28 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L8N_T1_D12_14 Sch=sd_cd +set_property -dict {PACKAGE_PIN R29 IOSTANDARD LVCMOS33} [get_ports pad_sdio_cmd] +set_property -dict {PACKAGE_PIN R26 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data0] +set_property -dict {PACKAGE_PIN R30 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data1] +set_property -dict {PACKAGE_PIN P29 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data2] +set_property -dict {PACKAGE_PIN T30 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data3] +set_property -dict {PACKAGE_PIN AE24 IOSTANDARD LVCMOS33} [get_ports sdio_reset_o] +set_property -dict {PACKAGE_PIN R28 IOSTANDARD LVCMOS33} [get_ports pad_sdio_clk] + + + +# set_property -dict {PACKAGE_PIN R28 IOSTANDARD LVCMOS33} [get_ports spi_clk_o] +# set_property -dict {PACKAGE_PIN T30 IOSTANDARD LVCMOS33} [get_ports spi_ss] +# set_property -dict {PACKAGE_PIN R26 IOSTANDARD LVCMOS33} [get_ports spi_miso] +# set_property -dict {PACKAGE_PIN R29 IOSTANDARD LVCMOS33} [get_ports spi_mosi] +# set_property -dict { PACKAGE_PIN P28 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L8N_T1_D12_14 Sch=sd_cd +# set_property -dict { PACKAGE_PIN R29 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L7N_T1_D10_14 Sch=sd_cmd +# set_property -dict { PACKAGE_PIN R26 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L10N_T1_D15_14 Sch=sd_dat[0] +# set_property -dict { PACKAGE_PIN R30 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L9P_T1_DQS_14 Sch=sd_dat[1] +# set_property -dict { PACKAGE_PIN P29 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L7P_T1_D09_14 Sch=sd_dat[2] +# set_property -dict { PACKAGE_PIN T30 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L9N_T1_DQS_D13_14 Sch=sd_dat[3] +# set_property -dict { PACKAGE_PIN AE24 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L12N_T1_MRCC_12 Sch=sd_reset +# set_property -dict { PACKAGE_PIN R28 IOSTANDARD LVCMOS33 } [get_ports { sd_clk }]; #IO_L11P_T1_SRCC_14 Sch=sd_sclk + +# create_generated_clock -name sd_fast_clk -source [get_pins clk_mmcm/sd_sys_clk] -divide_by 2 [get_pins chipset_impl/piton_sd_top/sdc_controller/clock_divider0/fast_clk_reg/Q] +# create_generated_clock -name sd_slow_clk -source [get_pins clk_mmcm/sd_sys_clk] -divide_by 200 [get_pins chipset_impl/piton_sd_top/sdc_controller/clock_divider0/slow_clk_reg/Q] +# create_generated_clock -name sd_clk_out -source [get_pins sd_clk_oddr/C] -divide_by 1 -add -master_clock sd_fast_clk [get_ports sd_clk_out] +# create_generated_clock -name sd_clk_out_1 -source [get_pins sd_clk_oddr/C] -divide_by 1 -add -master_clock sd_slow_clk [get_ports sd_clk_out] + +# create_clock -period 40.000 -name VIRTUAL_sd_fast_clk -waveform {0.000 20.000} +# create_clock -period 4000.000 -name VIRTUAL_sd_slow_clk -waveform {0.000 2000.000} + +# set_output_delay -clock [get_clocks sd_clk_out] -min -add_delay 5.000 [get_ports {sd_dat[*]}] +# set_output_delay -clock [get_clocks sd_clk_out] -max -add_delay 15.000 [get_ports {sd_dat[*]}] +# set_output_delay -clock [get_clocks sd_clk_out_1] -min -add_delay 5.000 [get_ports {sd_dat[*]}] +# set_output_delay -clock [get_clocks sd_clk_out_1] -max -add_delay 1500.000 [get_ports {sd_dat[*]}] +# set_output_delay -clock [get_clocks sd_clk_out] -min -add_delay 5.000 [get_ports sd_cmd] +# set_output_delay -clock [get_clocks sd_clk_out] -max -add_delay 15.000 [get_ports sd_cmd] +# set_output_delay -clock [get_clocks sd_clk_out_1] -min -add_delay 5.000 [get_ports sd_cmd] +# set_output_delay -clock [get_clocks sd_clk_out_1] -max -add_delay 1500.000 [get_ports sd_cmd] +# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -min -add_delay 20.000 [get_ports {sd_dat[*]}] +# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -max -add_delay 35.000 [get_ports {sd_dat[*]}] +# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -min -add_delay 2000.000 [get_ports {sd_dat[*]}] +# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -max -add_delay 3500.000 [get_ports {sd_dat[*]}] +# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -min -add_delay 20.000 [get_ports sd_cmd] +# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -max -add_delay 35.000 [get_ports sd_cmd] +# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -min -add_delay 2000.000 [get_ports sd_cmd] +# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -max -add_delay 3500.000 [get_ports sd_cmd] +# set_clock_groups -physically_exclusive -group [get_clocks -include_generated_clocks sd_clk_out] -group [get_clocks -include_generated_clocks sd_clk_out_1] +# set_clock_groups -logically_exclusive -group [get_clocks -include_generated_clocks {VIRTUAL_sd_fast_clk sd_fast_clk}] -group [get_clocks -include_generated_clocks {sd_slow_clk VIRTUAL_sd_slow_clk}] +# set_clock_groups -asynchronous -group [get_clocks [list [get_clocks -of_objects [get_pins clk_mmcm/chipset_clk]]]] -group [get_clocks -filter { NAME =~ "*sd*" }] + +## PMOD Header JD +#set_property -dict {PACKAGE_PIN V27 IOSTANDARD LVCMOS33} [get_ports { jd[0]}] +#set_property -dict {PACKAGE_PIN Y30 IOSTANDARD LVCMOS33} [get_ports { jd[1]}] +#set_property -dict { PACKAGE_PIN V24 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L23N_T3_A02_D18_14 Sch=jd[3] +#set_property -dict { PACKAGE_PIN W22 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L24N_T3_A00_D16_14 Sch=jd[4] +#set_property -dict { PACKAGE_PIN U24 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L23P_T3_A03_D19_14 Sch=jd[7] +#set_property -dict { PACKAGE_PIN Y26 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L1P_T0_13 Sch=jd[8] +#set_property -dict { PACKAGE_PIN V22 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L22N_T3_A04_D20_14 Sch=jd[9] +#set_property -dict { PACKAGE_PIN W21 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L24P_T3_A01_D17_14 Sch=jd[10]## PMOD Header JD +#set_property -dict { PACKAGE_PIN V27 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L16N_T2_A15_D31_14 Sch=jd[1] +#set_property -dict { PACKAGE_PIN Y30 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L8P_T1_13 Sch=jd[2] +#set_property -dict { PACKAGE_PIN V24 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L23N_T3_A02_D18_14 Sch=jd[3] +#set_property -dict { PACKAGE_PIN W22 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L24N_T3_A00_D16_14 Sch=jd[4] +#set_property -dict { PACKAGE_PIN U24 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L23P_T3_A03_D19_14 Sch=jd[7] +#set_property -dict { PACKAGE_PIN Y26 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L1P_T0_13 Sch=jd[8] +#set_property -dict { PACKAGE_PIN V22 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L22N_T3_A04_D20_14 Sch=jd[9] +#set_property -dict { PACKAGE_PIN W21 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L24P_T3_A01_D17_14 Sch=jd[10] + + +# Quad SPI flash +set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] + diff --git a/fpga/pulpissimo-zcu104/elf_run.gdb b/fpga/pulpissimo-zcu104/elf_run.gdb new file mode 100644 index 00000000..cba53bd0 --- /dev/null +++ b/fpga/pulpissimo-zcu104/elf_run.gdb @@ -0,0 +1,4 @@ +target remote localhost:3333 +monitor reset halt +load +continue \ No newline at end of file diff --git a/fpga/pulpissimo-zcu104/elf_run.sh b/fpga/pulpissimo-zcu104/elf_run.sh new file mode 100755 index 00000000..9bd74f6a --- /dev/null +++ b/fpga/pulpissimo-zcu104/elf_run.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +trap "exit" INT TERM +trap "kill 0" EXIT + + +SCRIPTDIR=$(dirname $0) +UART_TTY=${PULP_ZCU104_UART_TTY:=/dev/ttyUSB0} +UART_BAUDRATE=${PULP_ZCU104_UART_BAUDRATE:=115200} + +#Execute gdb and connect to openocd via pipe +$OPENOCD/bin/openocd -f $SCRIPTDIR/openocd-zcu104.cfg & +$PULP_RISCV_GCC_TOOLCHAIN_CI/bin/riscv32-unknown-elf-gdb -x $SCRIPTDIR/elf_run.gdb $1 & +sleep 3 +minicom -D $UART_TTY -b $UART_BAUDRATE + + diff --git a/fpga/pulpissimo-zcu104/fpga-settings.mk b/fpga/pulpissimo-zcu104/fpga-settings.mk new file mode 100644 index 00000000..f9c6c8b6 --- /dev/null +++ b/fpga/pulpissimo-zcu104/fpga-settings.mk @@ -0,0 +1,12 @@ +export BOARD=zcu104 +export XILINX_PART=xczu7ev-ffvc1156-2-e +export XILINX_BOARD=xilinx.com:zcu104:part0:1.1 +export FC_CLK_PERIOD_NS=50 +export PER_CLK_PERIOD_NS=100 +export SLOW_CLK_PERIOD_NS=100 +#Must also change the localparam 'L2_BANK_SIZE' in pulp_soc.sv accordingly +export INTERLEAVED_BANK_SIZE=28672 +#Must also change the localparam 'L2_BANK_SIZE_PRI' in pulp_soc.sv accordingly +export PRIVATE_BANK_SIZE=8192 +$(info Setting environment variables for $(BOARD) board) + diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/.gitignore b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/.gitignore @@ -0,0 +1,21 @@ +#Ignore vivado project files generated by the tcl script +**/.Xil/* +**/reports/* +**/*.cache/* +**/*.hw/* +**/*.ip_user_files/* +**/*.runs/* +**/*.sim/* +**/*.srcs/* +*.edf +*.xpr +*.jou +*.log + +.cxl.* + +*ip + +*_stub.v +gmon.out + diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/Makefile b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/Makefile new file mode 100644 index 00000000..9e4e616c --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/Makefile @@ -0,0 +1,30 @@ +PROJECT:=xilinx_clk_mngr +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl + +.DEFAULT_GOAL:=help + +.PHONY: help + +all: ## Create and synthesize the IP in batch mode. + $(VIVADO) -mode batch -source tcl/run.tcl + mkdir -p ip + cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/. + cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/. + +gui: ## Create and synthesize the IP in GUI mode. + $(VIVADO) -mode gui -source tcl/run.tcl & + +clean: ## Remove all build products + rm -rf ip/* + mkdir -p ip + rm -rf ${PROJECT}.* + rm -rf component.xml + rm -rf vivado*.jou + rm -rf vivado*.log + rm -rf vivado*.str + rm -rf xgui + rm -rf .Xil + +help: ## Shows this help message + @grep -E -h '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl new file mode 100644 index 00000000..0ae49ff0 --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl @@ -0,0 +1,49 @@ +set partNumber $::env(XILINX_PART) + +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + error "BOARD is not defined. Please source the sourceme.sh file." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set boardName $::env(XILINX_BOARD) +} + +# detect target clock +if [info exists ::env(FC_CLK_PERIOD_NS)] { + set FC_CLK_PERIOD_NS $::env(FC_CLK_PERIOD_NS) +} else { + set FC_CLK_PERIOD_NS 10.000 +} +if [info exists ::env(PER_CLK_PERIOD_NS)] { + set PER_CLK_PERIOD_NS $::env(PER_CLK_PERIOD_NS) +} else { + set PER_CLK_PERIOD_NS 20.000 +} + + +set FC_CLK_FREQ_MHZ [expr 1000 / $FC_CLK_PERIOD_NS] +set PER_CLK_FREQ_MHZ [expr 1000 / $PER_CLK_PERIOD_NS] + +set ipName xilinx_clk_mngr + +create_project $ipName . -part $partNumber +set_property board_part $boardName [current_project] + +create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName + +set_property -dict [eval list CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.NUM_OUT_CLKS {2} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.RESET_PORT {resetn} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {$FC_CLK_FREQ_MHZ} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {$PER_CLK_FREQ_MHZ} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + ] [get_ips $ipName] + +generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/.gitignore b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/.gitignore @@ -0,0 +1,21 @@ +#Ignore vivado project files generated by the tcl script +**/.Xil/* +**/reports/* +**/*.cache/* +**/*.hw/* +**/*.ip_user_files/* +**/*.runs/* +**/*.sim/* +**/*.srcs/* +*.edf +*.xpr +*.jou +*.log + +.cxl.* + +*ip + +*_stub.v +gmon.out + diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/Makefile b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/Makefile new file mode 100644 index 00000000..a45f840a --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/Makefile @@ -0,0 +1,30 @@ +PROJECT:=xilinx_interleaved_ram +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl + +.DEFAULT_GOAL:=help + +.PHONY: help + +all: ## Create and synthesize the IP in batch mode. + $(VIVADO) -mode batch -source tcl/run.tcl + mkdir -p ip + cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/. + cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/. + +gui: ## Create and synthesize the IP in GUI mode. + $(VIVADO) -mode gui -source tcl/run.tcl & + +clean: ## Remove all build products + rm -rf ip/* + mkdir -p ip + rm -rf ${PROJECT}.* + rm -rf component.xml + rm -rf vivado*.jou + rm -rf vivado*.log + rm -rf vivado*.str + rm -rf xgui + rm -rf .Xil + +help: ## Shows this help message + @grep -E -h '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/tcl/run.tcl new file mode 100644 index 00000000..a2e84f23 --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_interleaved_ram/tcl/run.tcl @@ -0,0 +1,38 @@ +set partNumber $::env(XILINX_PART) + +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + error "BOARD is not defined. Please source the sourceme.sh file." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set boardName $::env(XILINX_BOARD) +} + +# detect target ram size +if [info exists ::env(INTERLEAVED_BANK_SIZE)] { + set INTERLEAVED_BANK_SIZE $::env(INTERLEAVED_BANK_SIZE) +} else { + set INTERLEAVED_BANK_SIZE 4096 +} + +set ipName xilinx_interleaved_ram + +create_project $ipName . -part $partNumber +set_property board_part $boardName [current_project] + +create_ip -name blk_mem_gen -vendor xilinx.com -library ip -module_name $ipName + +set_property -dict [eval list CONFIG.Use_Byte_Write_Enable {true} \ + CONFIG.Byte_Size {8} \ + CONFIG.Write_Width_A {32} \ + CONFIG.Write_Depth_A {$INTERLEAVED_BANK_SIZE} \ + CONFIG.Read_Width_A {32} \ + CONFIG.Register_PortA_Output_of_Memory_Primitives {false} \ + ] [get_ips $ipName] + +generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/.gitignore b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/.gitignore @@ -0,0 +1,21 @@ +#Ignore vivado project files generated by the tcl script +**/.Xil/* +**/reports/* +**/*.cache/* +**/*.hw/* +**/*.ip_user_files/* +**/*.runs/* +**/*.sim/* +**/*.srcs/* +*.edf +*.xpr +*.jou +*.log + +.cxl.* + +*ip + +*_stub.v +gmon.out + diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/Makefile b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/Makefile new file mode 100644 index 00000000..b0b7741e --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/Makefile @@ -0,0 +1,30 @@ +PROJECT:=xilinx_private_ram +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl + +.DEFAULT_GOAL:=help + +.PHONY: help + +all: ## Create and synthesize the IP in batch mode. + $(VIVADO) -mode batch -source tcl/run.tcl + mkdir -p ip + cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/. + cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/. + +gui: ## Create and synthesize the IP in GUI mode. + $(VIVADO) -mode gui -source tcl/run.tcl & + +clean: ## Remove all build products + rm -rf ip/* + mkdir -p ip + rm -rf ${PROJECT}.* + rm -rf component.xml + rm -rf vivado*.jou + rm -rf vivado*.log + rm -rf vivado*.str + rm -rf xgui + rm -rf .Xil + +help: ## Shows this help message + @grep -E -h '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/tcl/run.tcl new file mode 100644 index 00000000..78493b37 --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_private_ram/tcl/run.tcl @@ -0,0 +1,38 @@ +set partNumber $::env(XILINX_PART) + +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + error "BOARD is not defined. Please source the sourceme.sh file." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set boardName $::env(XILINX_BOARD) +} + +# detect target ram size +if [info exists ::env(PRIVATE_BANK_SIZE)] { + set PRIVATE_BANK_SIZE $::env(PRIVATE_BANK_SIZE) +} else { + set PRIVATE_BANK_SIZE 4096 +} + +set ipName xilinx_private_ram + +create_project $ipName . -part $partNumber +set_property board_part $boardName [current_project] + +create_ip -name blk_mem_gen -vendor xilinx.com -library ip -module_name $ipName + +set_property -dict [eval list CONFIG.Use_Byte_Write_Enable {true} \ + CONFIG.Byte_Size {8} \ + CONFIG.Write_Width_A {32} \ + CONFIG.Write_Depth_A {$PRIVATE_BANK_SIZE} \ + CONFIG.Read_Width_A {32} \ + CONFIG.Register_PortA_Output_of_Memory_Primitives {false} \ + ] [get_ips $ipName] + +generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/.gitignore b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/.gitignore @@ -0,0 +1,21 @@ +#Ignore vivado project files generated by the tcl script +**/.Xil/* +**/reports/* +**/*.cache/* +**/*.hw/* +**/*.ip_user_files/* +**/*.runs/* +**/*.sim/* +**/*.srcs/* +*.edf +*.xpr +*.jou +*.log + +.cxl.* + +*ip + +*_stub.v +gmon.out + diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/Makefile b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/Makefile new file mode 100644 index 00000000..3709d058 --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/Makefile @@ -0,0 +1,30 @@ +PROJECT:=xilinx_slow_clk_mngr +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl + +.DEFAULT_GOAL:=help + +.PHONY: help + +all: ## Create and synthesize the IP in batch mode. + $(VIVADO) -mode batch -source tcl/run.tcl + mkdir -p ip + cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/. + cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/. + +gui: ## Create and synthesize the IP in GUI mode. + $(VIVADO) -mode gui -source tcl/run.tcl & + +clean: ## Remove all build products + rm -rf ip/* + mkdir -p ip + rm -rf ${PROJECT}.* + rm -rf component.xml + rm -rf vivado*.jou + rm -rf vivado*.log + rm -rf vivado*.str + rm -rf xgui + rm -rf .Xil + +help: ## Shows this help message + @grep -E -h '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl new file mode 100644 index 00000000..346bb3d9 --- /dev/null +++ b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl @@ -0,0 +1,44 @@ +set partNumber $::env(XILINX_PART) + +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + error "BOARD is not defined. Please source the sourceme.sh file." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set boardName $::env(XILINX_BOARD) +} + +# detect target clock +if [info exists ::env(SLOW_CLK_PERIOD_NS)] { + set SLOW_CLK_PERIOD_NS $::env(SLOW_CLK_PERIOD_NS) +} else { + set SLOW_CLK_PERIOD_NS 10.000 +} + + +set SLOW_CLK_FREQ_MHZ [expr 1000 / $SLOW_CLK_PERIOD_NS] + +set ipName xilinx_slow_clk_mngr + +create_project $ipName . -part $partNumber +set_property board_part $boardName [current_project] + +create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName + +set_property -dict [eval list CONFIG.PRIM_IN_FREQ {200.000} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {$SLOW_CLK_FREQ_MHZ} \ + CONFIG.USE_SAFE_CLOCK_STARTUP {true} \ + CONFIG.USE_LOCKED {false} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \ + CONFIG.RESET_PORT {resetn} \ + ] [get_ips $ipName] + + +generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/fpga/pulpissimo-zcu104/openocd-zcu104.cfg b/fpga/pulpissimo-zcu104/openocd-zcu104.cfg new file mode 100644 index 00000000..b0de8583 --- /dev/null +++ b/fpga/pulpissimo-zcu104/openocd-zcu104.cfg @@ -0,0 +1,46 @@ +adapter_khz 1000 + +interface ftdi +ftdi_vid_pid 0x0403 0x6010 + +# Channel 1 is taken by Xilinx JTAG +ftdi_channel 0 + +# links: +# http://openocd.org/doc-release/html/Debug-Adapter-Configuration.html +# +# Bit MPSSE FT2232 JTAG Type Description +# Bit0 TCK ADBUS0 TCK Out Clock Signal Output +# Bit1 TDI ADBUS1 TDI Out Serial Data Out +# Bit2 TDO ADBUS2 TDO In Serial Data In +# Bit3 TMS ADBUS3 TMS Out Select Signal Out +# Bit4 GPIOL0 ADBUS4 nTRST In/Out General Purpose I/O +# this corresponds to the following in/out layout, with TMS initially set to 1 +ftdi_layout_init 0x0018 0x001b +# we only have to specify nTRST, the others are assigned correctly by default +ftdi_layout_signal nTRST -ndata 0x0010 + +set _CHIPNAME riscv + +jtag newtap $_CHIPNAME unknown0 -irlen 5 -expected-id 0x10102001 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0x3e0 + +gdb_report_data_abort enable +gdb_report_register_access_error enable + +riscv set_reset_timeout_sec 120 +riscv set_command_timeout_sec 120 + +# prefer to use sba for system bus access +riscv set_prefer_sba on + +# dump jtag chain +scan_chain + + +init +halt +echo "Ready for Remote Connections" diff --git a/fpga/pulpissimo-zcu104/rtl/fpga_bootrom.sv b/fpga/pulpissimo-zcu104/rtl/fpga_bootrom.sv new file mode 100644 index 00000000..79d78b3f --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/fpga_bootrom.sv @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// Title : FPGA Bootrom for PULPissimo +//----------------------------------------------------------------------------- +// File : fpga_bootrom.sv +// Author : Manuel Eggimann +// Created : 29.05.2019 +//----------------------------------------------------------------------------- +// Description : +// Mockup bootrom that keeps returning jal x0,0 to trap the core in an infinite +// loop until the debug module takes over control. +//----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. +//----------------------------------------------------------------------------- + + +module fpga_bootrom + #( + parameter ADDR_WIDTH=32, + parameter DATA_WIDTH=32 + ) + ( + input logic CLK, + input logic CEN, + input logic [ADDR_WIDTH-1:0] A, + output logic [DATA_WIDTH-1:0] Q + ); + assign Q = 32'h0000006f; //jal x0,0 +endmodule : fpga_bootrom diff --git a/fpga/pulpissimo-zcu104/rtl/fpga_clk_gen.sv b/fpga/pulpissimo-zcu104/rtl/fpga_clk_gen.sv new file mode 100644 index 00000000..2ad9a8eb --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/fpga_clk_gen.sv @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// Title : FPGA CLK Gen for PULPissimo +// ----------------------------------------------------------------------------- +// File : fpga_clk_gen.sv Author : Manuel Eggimann +// Created : 17.05.2019 +// ----------------------------------------------------------------------------- +// Description : Instantiates Xilinx clocking wizard IP to generate 2 output +// clocks. Currently, the clock is not dynamicly reconfigurable and all +// configuration requests are acknowledged without any effect. +// ----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna Copyright and +// related rights are licensed under the Solderpad Hardware License, Version +// 0.51 (the "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law or +// agreed to in writing, software, hardware and materials distributed under this +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. See the License for the specific +// language governing permissions and limitations under the License. +// ----------------------------------------------------------------------------- + + +module fpga_clk_gen ( + input logic ref_clk_i, + input logic rstn_glob_i, + input logic test_mode_i, + input logic shift_enable_i, + output logic soc_clk_o, + output logic per_clk_o, + output logic cluster_clk_o, + output logic soc_cfg_lock_o, + input logic soc_cfg_req_i, + output logic soc_cfg_ack_o, + input logic [1:0] soc_cfg_add_i, + input logic [31:0] soc_cfg_data_i, + output logic [31:0] soc_cfg_r_data_o, + input logic soc_cfg_wrn_i, + output logic per_cfg_lock_o, + input logic per_cfg_req_i, + output logic per_cfg_ack_o, + input logic [1:0] per_cfg_add_i, + input logic [31:0] per_cfg_data_i, + output logic [31:0] per_cfg_r_data_o, + input logic per_cfg_wrn_i, + output logic cluster_cfg_lock_o, + input logic cluster_cfg_req_i, + output logic cluster_cfg_ack_o, + input logic [1:0] cluster_cfg_add_i, + input logic [31:0] cluster_cfg_data_i, + output logic [31:0] cluster_cfg_r_data_o, + input logic cluster_cfg_wrn_i + ); + + logic s_locked; + + xilinx_clk_mngr i_clk_manager + ( + .resetn(rstn_glob_i), + .clk_in1(ref_clk_i), + .clk_out1(soc_clk_o), + .clk_out2(per_clk_o), + .locked(s_locked) + ); + + assign soc_cfg_lock_o = s_locked; + assign per_cfg_lock_o = s_locked; + + assign soc_cfg_ack_o = 1'b1; //Always acknowledge without doing anything for now + assign per_cfg_ack_o = 1'b1; + + assign soc_cfg_r_data_o = 32'hdeadda7a; + assign per_cfg_r_data_o = 32'hdeadda7a; + +endmodule : fpga_clk_gen diff --git a/fpga/pulpissimo-zcu104/rtl/fpga_interleaved_ram.sv b/fpga/pulpissimo-zcu104/rtl/fpga_interleaved_ram.sv new file mode 100644 index 00000000..7d52e5d8 --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/fpga_interleaved_ram.sv @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Title : FPGA Interleaved RAM Bank for PULPissimo +// ----------------------------------------------------------------------------- +// File : fpga_interleaved_ram.sv Author : Manuel Eggimann +// Created : 20.05.2019 +// ----------------------------------------------------------------------------- +// Description : Instantiated block ram generator IP to replace the SRAM banks +// in the interleaved region of L2. Since Xilinx LogicoreIP are not customizable +// via parameters, the bank size selected in l2_ram_multibank must match the one +// used in the TCL script for IP generation. +// ----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna Copyright and +// related rights are licensed under the Solderpad Hardware License, Version +// 0.51 (the "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law or +// agreed to in writing, software, hardware and materials distributed under this +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. See the License for the specific +// language governing permissions and limitations under the License. +// ----------------------------------------------------------------------------- + +module fpga_interleaved_ram + #( + parameter ADDR_WIDTH=12 + ) ( + input logic clk_i, + input logic rst_ni, + input logic csn_i, + input logic wen_i, + input logic [3:0] be_i, + input logic [ADDR_WIDTH-1:0] addr_i, + input logic [31:0] wdata_i, + output logic [31:0] rdata_o + ); + + logic [3:0] wea; + + always_comb begin + if (wen_i == 1'b0) begin + wea = be_i; + end else begin + wea = '0; + end + end + + xilinx_interleaved_ram i_xilinx_interleaved_ram + ( + .clka(clk_i), + .ena(~csn_i), + .wea(wea), + .addra(addr_i), + .dina(wdata_i), + .douta(rdata_o) + ); + +endmodule : fpga_interleaved_ram diff --git a/fpga/pulpissimo-zcu104/rtl/fpga_private_ram.sv b/fpga/pulpissimo-zcu104/rtl/fpga_private_ram.sv new file mode 100644 index 00000000..05244931 --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/fpga_private_ram.sv @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// Title : FPGA Private RAM Bank for PULPissimo +// ----------------------------------------------------------------------------- +// File : fpga_private_ram.sv Author : Manuel Eggimann +// Created : 20.05.2019 +// ----------------------------------------------------------------------------- +// Description : Instantiated block ram generator IP to replace the SRAM banks +// in the private region of L2. Since Xilinx LogicoreIP are not customizable +// via parameters, the bank size selected in l2_ram_multibank must match the one +// used in the TCL script for IP generation. +// ----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna Copyright and +// related rights are licensed under the Solderpad Hardware License, Version +// 0.51 (the "License"); you may not use this file except in compliance with the +// License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law or +// agreed to in writing, software, hardware and materials distributed under this +// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +// OF ANY KIND, either express or implied. See the License for the specific +// language governing permissions and limitations under the License. +// ----------------------------------------------------------------------------- + +module fpga_private_ram + #( + parameter ADDR_WIDTH=12 + ) ( + input logic clk_i, + input logic rst_ni, + input logic csn_i, + input logic wen_i, + input logic [3:0] be_i, + input logic [ADDR_WIDTH-1:0] addr_i, + input logic [31:0] wdata_i, + output logic [31:0] rdata_o + ); + + logic [3:0] wea; + + always_comb begin + if (wen_i == 1'b0) begin + wea = be_i; + end else begin + wea = '0; + end + end + + xilinx_private_ram i_xilinx_private_ram + ( + .clka(clk_i), + .ena(~csn_i), + .wea(wea), + .addra(addr_i), + .dina(wdata_i), + .douta(rdata_o) + ); + +endmodule : fpga_private_ram diff --git a/fpga/pulpissimo-zcu104/rtl/fpga_slow_clk_gen.sv b/fpga/pulpissimo-zcu104/rtl/fpga_slow_clk_gen.sv new file mode 100644 index 00000000..e76953fd --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/fpga_slow_clk_gen.sv @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Title : FPGA slow clk generator for PULPissimo +//----------------------------------------------------------------------------- +// File : fpga_slow_clk_gen.sv +// Author : Manuel Eggimann +// Created : 20.05.2019 +//----------------------------------------------------------------------------- +// Description : Instantiates Xilinx Clocking Wizard IP to generate the slow_clk +// signal since for certain boards the available clock sources are to fast to +// use directly. +//----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. +//----------------------------------------------------------------------------- + + +module fpga_slow_clk_gen + (input logic ref_clk_i, + input logic rst_ni, + output logic slow_clk_o + ); + + xilinx_slow_clk_mngr i_slow_clk_mngr + ( + .resetn(rst_ni), + .clk_in1(ref_clk_i), + .clk_out1(slow_clk_o) + ); + +endmodule : fpga_slow_clk_gen diff --git a/fpga/pulpissimo-zcu104/rtl/pad_functional_xilinx.sv b/fpga/pulpissimo-zcu104/rtl/pad_functional_xilinx.sv new file mode 100644 index 00000000..a3ca1cde --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/pad_functional_xilinx.sv @@ -0,0 +1,48 @@ +// Copyright 2018 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + + +module pad_functional_pd +( + input logic OEN, + input logic I, + output logic O, + input logic PEN, + inout logic PAD +); + + (* PULLDOWN = "YES" *) + IOBUF iobuf_i ( + .T ( OEN ), + .I ( I ), + .O ( O ), + .IO( PAD ) + ); + +endmodule + +module pad_functional_pu +( + input logic OEN, + input logic I, + output logic O, + input logic PEN, + inout logic PAD +); + + (* PULLUP = "YES" *) + IOBUF iobuf_i ( + .T ( OEN ), + .I ( I ), + .O ( O ), + .IO( PAD ) + ); + +endmodule \ No newline at end of file diff --git a/fpga/pulpissimo-zcu104/rtl/pulp_clock_gating_xilinx.sv b/fpga/pulpissimo-zcu104/rtl/pulp_clock_gating_xilinx.sv new file mode 100644 index 00000000..1e2db2d1 --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/pulp_clock_gating_xilinx.sv @@ -0,0 +1,21 @@ +// Copyright 2018 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +module pulp_clock_gating + ( + input logic clk_i, + input logic en_i, + input logic test_en_i, + output logic clk_o + ); + + assign clk_o = clk_i; + +endmodule diff --git a/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v b/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v new file mode 100644 index 00000000..fba78e52 --- /dev/null +++ b/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v @@ -0,0 +1,148 @@ +//----------------------------------------------------------------------------- +// Title : PULPissimo Verilog Wrapper +//----------------------------------------------------------------------------- +// File : xilinx_pulpissimo.v +// Author : Manuel Eggimann +// Created : 21.05.2019 +//----------------------------------------------------------------------------- +// Description : +// Verilog Wrapper of PULPissimo to use the module within Xilinx IP integrator. +//----------------------------------------------------------------------------- +// Copyright (C) 2013-2019 ETH Zurich, University of Bologna +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. +//----------------------------------------------------------------------------- + +module xilinx_pulpissimo + ( + input wire ref_clk_p, + input wire ref_clk_n, + +// inout wire pad_spim_sdio0, + inout wire pad_spim_sdio1, + inout wire pad_spim_sdio2, + inout wire pad_spim_sdio3, + inout wire pad_spim_csn0, + inout wire pad_spim_sck, + + inout wire pad_uart_rx, + inout wire pad_uart_tx, + + inout wire led0_o, //Mapped to spim_csn1 + inout wire led1_o, //Mapped to cam_pclk + inout wire led2_o, //Mapped to cam_hsync + inout wire led3_o, //Mapped to cam_data0 + + inout wire switch0_i, //Mapped to cam_data1 + inout wire switch1_i, //Mapped to cam_data2 + + inout wire btnc_i, //Mapped to cam_data3 + inout wire btnd_i, //Mapped to cam_data4 + inout wire btnl_i, //Mapped to cam_data5 + inout wire btnr_i, //Mapped to cam_data6 + inout wire btnu_i, //Mapped to cam_data7 + + inout wire oled_spim_sck_o, //Mapped to spim_sck + inout wire oled_spim_mosi_o, //Mapped to spim_sdio0 + inout wire oled_rst_o, //Mapped to i2s0_sck + inout wire oled_dc_o, //Mapped to i2s0_ws + inout wire oled_vbat_o, // Mapped to i2s0_sdi + inout wire oled_vdd_o, // Mapped to i2s1_sdi + + inout wire sdio_reset_o, //Reset signal for SD card need to be driven low to + //power the onboard sd-card. Mapped to cam_vsync. + inout wire pad_sdio_clk, + inout wire pad_sdio_cmd, + inout wire pad_sdio_data0, + inout wire pad_sdio_data1, + inout wire pad_sdio_data2, + inout wire pad_sdio_data3, + + inout wire pad_i2c0_sda, + inout wire pad_i2c0_scl, + + input wire pad_reset_n, + inout wire pad_bootsel, + + input wire pad_jtag_tck, + input wire pad_jtag_tdi, + output wire pad_jtag_tdo, + input wire pad_jtag_tms, + input wire pad_jtag_trst + ); + + localparam CORE_TYPE = 0; // 0 for RISCY, 1 for ZERORISCY, 2 for MICRORISCY + localparam USE_FPU = 1; + localparam USE_HWPE = 0; + + wire ref_clk; + + + //Differential to single ended clock conversion + IBUFGDS + #( + .IOSTANDARD("LVDS"), + .DIFF_TERM("FALSE"), + .IBUF_LOW_PWR("FALSE")) + i_sysclk_iobuf + ( + .I(ref_clk_p), + .IB(ref_clk_n), + .O(ref_clk) + ); + + pulpissimo + #(.CORE_TYPE(CORE_TYPE), + .USE_FPU(USE_FPU), + .USE_HWPE(USE_HWPE) + ) i_pulpissimo + ( + .pad_spim_sdio0(oled_spim_mosi_o), + .pad_spim_sdio1(pad_spim_sdio1), + .pad_spim_sdio2(pad_spim_sdio2), + .pad_spim_sdio3(pad_spim_sdio3), + .pad_spim_csn0(pad_spim_csn0), + .pad_spim_csn1(led0_o), + .pad_spim_sck(oled_spim_sck_o), + .pad_uart_rx(pad_uart_rx), + .pad_uart_tx(pad_uart_tx), + .pad_cam_pclk(led1_o), + .pad_cam_hsync(led2_o), + .pad_cam_data0(led3_o), + .pad_cam_data1(switch0_i), + .pad_cam_data2(switch1_i), + .pad_cam_data3(btnc_i), + .pad_cam_data4(btnd_i), + .pad_cam_data5(btnl_i), + .pad_cam_data6(btnr_i), + .pad_cam_data7(btnu_i), + .pad_cam_vsync(sdio_reset_o), + .pad_sdio_clk(pad_sdio_clk), + .pad_sdio_cmd(pad_sdio_cmd), + .pad_sdio_data0(pad_sdio_data0), + .pad_sdio_data1(pad_sdio_data1), + .pad_sdio_data2(pad_sdio_data2), + .pad_sdio_data3(pad_sdio_data3), + .pad_i2c0_sda(pad_i2c0_sda), + .pad_i2c0_scl(pad_i2c0_scl), + .pad_i2s0_sck(oled_rst_o), + .pad_i2s0_ws(oled_dc_o), + .pad_i2s0_sdi(oled_vbat_o), + .pad_i2s1_sdi(oled_vdd_o), + .pad_reset_n(pad_reset_n), + .pad_jtag_tck(pad_jtag_tck), + .pad_jtag_tdi(pad_jtag_tdi), + .pad_jtag_tdo(pad_jtag_tdo), + .pad_jtag_tms(pad_jtag_tms), + .pad_jtag_trst(pad_jtag_trst), + .pad_xtal_in(ref_clk), + .pad_bootsel() + ); + +endmodule diff --git a/fpga/pulpissimo-zcu104/tcl/.gitignore b/fpga/pulpissimo-zcu104/tcl/.gitignore new file mode 100644 index 00000000..587a0fa6 --- /dev/null +++ b/fpga/pulpissimo-zcu104/tcl/.gitignore @@ -0,0 +1,6 @@ +#Ignore tcl files generated by ipstools +ips_add_files.tcl +ips_inc_dirs.tcl +ips_src_files.tcl +rtl_add_files.tcl +rtl_src_files.tcl \ No newline at end of file diff --git a/fpga/pulpissimo-zcu104/tcl/messages.tcl b/fpga/pulpissimo-zcu104/tcl/messages.tcl new file mode 100644 index 00000000..e8bfaf90 --- /dev/null +++ b/fpga/pulpissimo-zcu104/tcl/messages.tcl @@ -0,0 +1,13 @@ +# sets up Vivado messages in a more sensible way + +set_msg_config -id {[Synth 8-3352]} -new_severity "critical warning" +set_msg_config -id {[Synth 8-350]} -new_severity "critical warning" +set_msg_config -id {[Synth 8-2490]} -new_severity "warning" +set_msg_config -id {[Synth 8-2306]} -new_severity "info" +set_msg_config -id {[Synth 8-3331]} -new_severity "critical warning" +set_msg_config -id {[Synth 8-3332]} -new_severity "info" +set_msg_config -id {[Synth 8-2715]} -new_severity "error" +set_msg_config -id {[Opt 31-35]} -new_severity "info" +set_msg_config -id {[Opt 31-32]} -new_severity "info" +set_msg_config -id {[Shape Builder 18-119]} -new_severity "warning" +set_msg_config -id {[Filemgmt 20-742]} -new_severity "error" diff --git a/fpga/pulpissimo-zcu104/tcl/run.tcl b/fpga/pulpissimo-zcu104/tcl/run.tcl new file mode 100644 index 00000000..7cc92776 --- /dev/null +++ b/fpga/pulpissimo-zcu104/tcl/run.tcl @@ -0,0 +1,132 @@ +set project pulpissimo_zcu104 +set RTL ../../../rtl +set IPS ../../../ips +set CONSTRS constraints + + +# detect board +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + puts "Please execute 'source ../sourceme.sh first before you start vivado in order to setup necessary environment variables." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set XILINX_BOARD $::env(XILINX_BOARD) +} + +# create project +create_project $project . -force -part $::env(XILINX_PART) +set_property board_part $XILINX_BOARD [current_project] + +# set up meaningfull errors +source tcl/messages.tcl + +# set up includes +source ../pulpissimo/tcl/ips_inc_dirs.tcl +set_property include_dirs $INCLUDE_DIRS [current_fileset] +set_property include_dirs $INCLUDE_DIRS [current_fileset -simset] + +# setup and add IP source files +source ../pulpissimo/tcl/ips_src_files.tcl +source ../pulpissimo/tcl/ips_add_files.tcl + +# setup and add RTL source files +source ../pulpissimo/tcl/rtl_src_files.tcl +source ../pulpissimo/tcl/rtl_add_files.tcl + +# Override IPSApprox default variables +set FPGA_RTL rtl +set FPGA_IPS ips + +# remove duplicate incompatible modules +remove_files $IPS/pulp_soc/rtl/components/axi_slice_dc_slave_wrap.sv +remove_file $IPS/pulp_soc/rtl/components/axi_slice_dc_master_wrap.sv +remove_file $IPS/tech_cells_generic/pad_functional_xilinx.sv + +# Set Verilog Defines. +set DEFINES "FPGA_TARGET_XILINX=1 PULP_FPGA_EMUL=1 AXI4_XCHECK_OFF=1" +if { $BOARD == "zcu104" } { + set DEFINES "$DEFINES ZCU104=1" +} +set_property verilog_define $DEFINES [current_fileset] + +# detect target clock +if [info exists ::env(FC_CLK_PERIOD_NS)] { + set FC_CLK_PERIOD_NS $::env(FC_CLK_PERIOD_NS) +} else { + set FC_CLK_PERIOD_NS 10.000 +} +set CLK_HALFPERIOD_NS [expr ${FC_CLK_PERIOD_NS} / 2.0] + +# Add toplevel wrapper +add_files -norecurse $FPGA_RTL/xilinx_pulpissimo.v + +# Add Xilinx IPs +read_ip $FPGA_IPS/xilinx_clk_mngr/ip/xilinx_clk_mngr.xci +read_ip $FPGA_IPS/xilinx_slow_clk_mngr/ip/xilinx_slow_clk_mngr.xci +read_ip $FPGA_IPS/xilinx_interleaved_ram/ip/xilinx_interleaved_ram.xci +read_ip $FPGA_IPS/xilinx_private_ram/ip/xilinx_private_ram.xci + +# Add wrappers and xilinx specific techcells +add_files -norecurse $FPGA_RTL/fpga_clk_gen.sv +add_files -norecurse $FPGA_RTL/fpga_slow_clk_gen.sv +add_files -norecurse $FPGA_RTL/fpga_interleaved_ram.sv +add_files -norecurse $FPGA_RTL/fpga_private_ram.sv +add_files -norecurse $FPGA_RTL/fpga_bootrom.sv +add_files -norecurse $FPGA_RTL/pad_functional_xilinx.sv +add_files -norecurse $FPGA_RTL/pulp_clock_gating_xilinx.sv + + +# set pulpissimo as top +set_property top xilinx_pulpissimo [current_fileset]; # + +# needed only if used in batch mode +update_compile_order -fileset sources_1 + +# Add constraints +add_files -fileset constrs_1 -norecurse $CONSTRS/zcu104.xdc + +# Elaborate design +synth_design -rtl -name rtl_1 -sfcu;# sfcu -> run synthesis in single file compilation unit mode + + + +# launch synthesis +set_property STEPS.SYNTH_DESIGN.ARGS.FLATTEN_HIERARCHY none [get_runs synth_1] +set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} -value -sfcu -objects [get_runs synth_1] ;# Use single file compilation unit mode to prevent issues with import pkg::* statements in the codebase +launch_runs synth_1 -jobs 8 +wait_on_run synth_1 +open_run synth_1 -name netlist_1 +set_property needs_refresh false [get_runs synth_1] + +# Remove unused IOBUF cells in padframe (they are not optimized away since the +# pad driver also drives the input creating a datapath from pad_xy_o to pad_xy_i +# ) +remove_cell i_pulpissimo/pad_frame_i/padinst_bootsel + + +# Launch Implementation + +# set for RuntimeOptimized implementation +set_property "steps.opt_design.args.directive" "RuntimeOptimized" [get_runs impl_1] +set_property "steps.place_design.args.directive" "RuntimeOptimized" [get_runs impl_1] +set_property "steps.route_design.args.directive" "RuntimeOptimized" [get_runs impl_1] + +set_property STEPS.WRITE_BITSTREAM.ARGS.BIN_FILE true [get_runs impl_1] +set_property config_mode SPIx4 [current_design] + +launch_runs impl_1 -jobs 8 +wait_on_run impl_1 +launch_runs impl_1 -to_step write_bitstream +wait_on_run impl_1 + +open_run impl_1 + +# Generate reports +exec mkdir -p reports/ +exec rm -rf reports/* +check_timing -file reports/${project}.check_timing.rpt +report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/${project}.timing_WORST_100.rpt +report_timing -nworst 1 -delay_type max -sort_by group -file reports/${project}.timing.rpt +report_utilization -hierarchical -file reports/${project}.utilization.rpt From cb2e1440d71d4a6982a1697e632879a476c38181 Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Wed, 31 Jul 2019 10:29:11 +0200 Subject: [PATCH 2/8] ZCU104: IO constraints --- fpga/pulpissimo-zcu104/constraints/zcu104.xdc | 178 +++++------------- .../pulpissimo-zcu104/rtl/xilinx_pulpissimo.v | 107 +++++------ 2 files changed, 97 insertions(+), 188 deletions(-) diff --git a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc index 2c24722c..66f26762 100644 --- a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc +++ b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc @@ -28,12 +28,10 @@ set_input_jitter tck 1.000 set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tdi] set_input_delay -clock tck -clock_fall 5.000 [get_ports pad_jtag_tms] set_output_delay -clock tck 5.000 [get_ports pad_jtag_tdo] -set_false_path -from [get_ports pad_jtag_trst] set_max_delay -to [get_ports pad_jtag_tdo] 20.000 set_max_delay -from [get_ports pad_jtag_tms] 20.000 set_max_delay -from [get_ports pad_jtag_tdi] 20.000 -set_max_delay -from [get_ports pad_jtag_trst] 20.000 set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 20.000 set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 20.000 @@ -41,7 +39,7 @@ set_max_delay -datapath_only -from [get_pins i_pulpissimo/soc_domain_i/pulp_soc_ # reset signal -set_false_path -from [get_ports pad_reset_n] +set_false_path -from [get_ports pad_reset] # Set ASYNC_REG attribute for ff synchronizers to place them closer together and # increase MTBF @@ -70,144 +68,60 @@ set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpis ############################################################# ## Sys clock -set_property -dict {PACKAGE_PIN AD11 IOSTANDARD LVDS} [get_ports ref_clk_n] -set_property -dict {PACKAGE_PIN AD12 IOSTANDARD LVDS} [get_ports ref_clk_p] +set_property -dict {PACKAGE_PIN E23 IOSTANDARD LVDS} [get_ports ref_clk_n] +set_property -dict {PACKAGE_PIN F23 IOSTANDARD LVDS} [get_ports ref_clk_p] +## Reset +set_property -dict {PACKAGE_PIN M11 IOSTANDARD LVCMOS33} [get_ports pad_reset] ## Buttons -set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS33} [get_ports pad_reset_n] -set_property -dict {PACKAGE_PIN E18 IOSTANDARD LVCMOS12} [get_ports btnc_i] -set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS12} [get_ports btnd_i] -set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS12} [get_ports btnl_i] -set_property -dict {PACKAGE_PIN C19 IOSTANDARD LVCMOS12} [get_ports btnr_i] -set_property -dict {PACKAGE_PIN B19 IOSTANDARD LVCMOS12} [get_ports btnu_i] - -## To use FTDI FT2232 JTAG -set_property -dict {PACKAGE_PIN Y29 IOSTANDARD LVCMOS33} [get_ports pad_jtag_trst] -set_property -dict {PACKAGE_PIN AD27 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tck] -set_property -dict {PACKAGE_PIN W27 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdi] -set_property -dict {PACKAGE_PIN W28 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdo] -set_property -dict {PACKAGE_PIN W29 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tms] +set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports btn0_i] +set_property -dict {PACKAGE_PIN C4 IOSTANDARD LVCMOS33} [get_ports btn1_i] +set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports btn2_i] +set_property -dict {PACKAGE_PIN C3 IOSTANDARD LVCMOS33} [get_ports btn3_i] + +## PMOD 0 +set_property -dict {PACKAGE_PIN G8 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tms] +set_property -dict {PACKAGE_PIN H8 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdi] +set_property -dict {PACKAGE_PIN G7 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdo] +set_property -dict {PACKAGE_PIN H7 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tck] +set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports pad_pmod0_4] +set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports pad_pmod0_5] +set_property -dict {PACKAGE_PIN J6 IOSTANDARD LVCMOS33} [get_ports pad_pmod0_6] +set_property -dict {PACKAGE_PIN J7 IOSTANDARD LVCMOS33} [get_ports pad_pmod0_7] + +## PMOD 1 +set_property -dict {PACKAGE_PIN J9 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_0] +set_property -dict {PACKAGE_PIN K9 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_1] +set_property -dict {PACKAGE_PIN K8 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_2] +set_property -dict {PACKAGE_PIN L8 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_3] +set_property -dict {PACKAGE_PIN L10 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_4] +set_property -dict {PACKAGE_PIN M10 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_5] +set_property -dict {PACKAGE_PIN M8 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_6] +set_property -dict {PACKAGE_PIN M9 IOSTANDARD LVCMOS33} [get_ports pad_pmod1_7] ## UART -set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS33} [get_ports pad_uart_tx] -set_property -dict {PACKAGE_PIN Y20 IOSTANDARD LVCMOS33} [get_ports pad_uart_rx] +set_property -dict {PACKAGE_PIN A20 IOSTANDARD LVCMOS18} [get_ports pad_uart_rx] +set_property -dict {PACKAGE_PIN C19 IOSTANDARD LVCMOS18} [get_ports pad_uart_tx] +set_property -dict {PACKAGE_PIN C18 IOSTANDARD LVCMOS18} [get_ports pad_uart_rts] +set_property -dict {PACKAGE_PIN A19 IOSTANDARD LVCMOS18} [get_ports pad_uart_cts] ## LEDs -set_property -dict {PACKAGE_PIN T28 IOSTANDARD LVCMOS33} [get_ports led0_o] -set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports led1_o] -set_property -dict {PACKAGE_PIN U30 IOSTANDARD LVCMOS33} [get_ports led2_o] -set_property -dict {PACKAGE_PIN U29 IOSTANDARD LVCMOS33} [get_ports led3_o] -#set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports ] -#set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS33} [get_ports ] -#set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS33} [get_ports ] -#set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS33} [get_ports ] +set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports led0_o] +set_property -dict {PACKAGE_PIN D6 IOSTANDARD LVCMOS33} [get_ports led1_o] +set_property -dict {PACKAGE_PIN A5 IOSTANDARD LVCMOS33} [get_ports led2_o] +set_property -dict {PACKAGE_PIN B5 IOSTANDARD LVCMOS33} [get_ports led3_o] ## Switches -set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS12} [get_ports switch0_i] -set_property -dict {PACKAGE_PIN G25 IOSTANDARD LVCMOS12} [get_ports switch1_i] -#set_property -dict {PACKAGE_PIN H24 IOSTANDARD LVCMOS12} [get_ports {}] -# set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS12} [get_ports {}] -# set_property -dict {PACKAGE_PIN N19 IOSTANDARD LVCMOS12} [get_ports {}] -# set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS12} [get_ports {}] -# set_property -dict {PACKAGE_PIN P26 IOSTANDARD LVCMOS33} [get_ports {}] -# set_property -dict {PACKAGE_PIN P27 IOSTANDARD LVCMOS33} [get_ports {}] +set_property -dict {PACKAGE_PIN E4 IOSTANDARD LVCMOS33} [get_ports switch0_i] +set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports switch1_i] +set_property -dict {PACKAGE_PIN F5 IOSTANDARD LVCMOS33} [get_ports switch2_i] +set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports switch3_i] ## I2C Bus -set_property -dict {PACKAGE_PIN AE30 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_scl] -set_property -dict {PACKAGE_PIN AF30 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_sda] - -## QSPI Flash -set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVCMOS33} [get_ports pad_spim_csn0] -#set_property -dict { PACKAGE_PIN P24 IOSTANDARD LVCMOS33 } [get_ports { pad_spim_sdio0 }]; #IO_L1P_T0_D00_MOSI_14 Sch=qspi_d[0] -set_property -dict {PACKAGE_PIN R25 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio1] -set_property -dict {PACKAGE_PIN R20 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio2] -set_property -dict {PACKAGE_PIN R21 IOSTANDARD LVCMOS33} [get_ports pad_spim_sdio3] - - -## OLED Display -set_property -dict {PACKAGE_PIN AC17 IOSTANDARD LVCMOS18} [get_ports oled_dc_o] -set_property -dict {PACKAGE_PIN AB17 IOSTANDARD LVCMOS18} [get_ports oled_rst_o] -set_property -dict {PACKAGE_PIN AF17 IOSTANDARD LVCMOS18} [get_ports oled_spim_sck_o] -set_property -dict {PACKAGE_PIN Y15 IOSTANDARD LVCMOS18} [get_ports oled_spim_mosi_o] -set_property -dict {PACKAGE_PIN AB22 IOSTANDARD LVCMOS33} [get_ports oled_vbat_o] -set_property -dict {PACKAGE_PIN AG17 IOSTANDARD LVCMOS18} [get_ports oled_vdd_o] - - -############################################# -## SD Card -############################################# -#set_property -dict { PACKAGE_PIN P28 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L8N_T1_D12_14 Sch=sd_cd -set_property -dict {PACKAGE_PIN R29 IOSTANDARD LVCMOS33} [get_ports pad_sdio_cmd] -set_property -dict {PACKAGE_PIN R26 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data0] -set_property -dict {PACKAGE_PIN R30 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data1] -set_property -dict {PACKAGE_PIN P29 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data2] -set_property -dict {PACKAGE_PIN T30 IOSTANDARD LVCMOS33} [get_ports pad_sdio_data3] -set_property -dict {PACKAGE_PIN AE24 IOSTANDARD LVCMOS33} [get_ports sdio_reset_o] -set_property -dict {PACKAGE_PIN R28 IOSTANDARD LVCMOS33} [get_ports pad_sdio_clk] - - - -# set_property -dict {PACKAGE_PIN R28 IOSTANDARD LVCMOS33} [get_ports spi_clk_o] -# set_property -dict {PACKAGE_PIN T30 IOSTANDARD LVCMOS33} [get_ports spi_ss] -# set_property -dict {PACKAGE_PIN R26 IOSTANDARD LVCMOS33} [get_ports spi_miso] -# set_property -dict {PACKAGE_PIN R29 IOSTANDARD LVCMOS33} [get_ports spi_mosi] -# set_property -dict { PACKAGE_PIN P28 IOSTANDARD LVCMOS33 } [get_ports { sd_cd }]; #IO_L8N_T1_D12_14 Sch=sd_cd -# set_property -dict { PACKAGE_PIN R29 IOSTANDARD LVCMOS33 } [get_ports { sd_cmd }]; #IO_L7N_T1_D10_14 Sch=sd_cmd -# set_property -dict { PACKAGE_PIN R26 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[0] }]; #IO_L10N_T1_D15_14 Sch=sd_dat[0] -# set_property -dict { PACKAGE_PIN R30 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[1] }]; #IO_L9P_T1_DQS_14 Sch=sd_dat[1] -# set_property -dict { PACKAGE_PIN P29 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[2] }]; #IO_L7P_T1_D09_14 Sch=sd_dat[2] -# set_property -dict { PACKAGE_PIN T30 IOSTANDARD LVCMOS33 } [get_ports { sd_dat[3] }]; #IO_L9N_T1_DQS_D13_14 Sch=sd_dat[3] -# set_property -dict { PACKAGE_PIN AE24 IOSTANDARD LVCMOS33 } [get_ports { sd_reset }]; #IO_L12N_T1_MRCC_12 Sch=sd_reset -# set_property -dict { PACKAGE_PIN R28 IOSTANDARD LVCMOS33 } [get_ports { sd_clk }]; #IO_L11P_T1_SRCC_14 Sch=sd_sclk - -# create_generated_clock -name sd_fast_clk -source [get_pins clk_mmcm/sd_sys_clk] -divide_by 2 [get_pins chipset_impl/piton_sd_top/sdc_controller/clock_divider0/fast_clk_reg/Q] -# create_generated_clock -name sd_slow_clk -source [get_pins clk_mmcm/sd_sys_clk] -divide_by 200 [get_pins chipset_impl/piton_sd_top/sdc_controller/clock_divider0/slow_clk_reg/Q] -# create_generated_clock -name sd_clk_out -source [get_pins sd_clk_oddr/C] -divide_by 1 -add -master_clock sd_fast_clk [get_ports sd_clk_out] -# create_generated_clock -name sd_clk_out_1 -source [get_pins sd_clk_oddr/C] -divide_by 1 -add -master_clock sd_slow_clk [get_ports sd_clk_out] - -# create_clock -period 40.000 -name VIRTUAL_sd_fast_clk -waveform {0.000 20.000} -# create_clock -period 4000.000 -name VIRTUAL_sd_slow_clk -waveform {0.000 2000.000} - -# set_output_delay -clock [get_clocks sd_clk_out] -min -add_delay 5.000 [get_ports {sd_dat[*]}] -# set_output_delay -clock [get_clocks sd_clk_out] -max -add_delay 15.000 [get_ports {sd_dat[*]}] -# set_output_delay -clock [get_clocks sd_clk_out_1] -min -add_delay 5.000 [get_ports {sd_dat[*]}] -# set_output_delay -clock [get_clocks sd_clk_out_1] -max -add_delay 1500.000 [get_ports {sd_dat[*]}] -# set_output_delay -clock [get_clocks sd_clk_out] -min -add_delay 5.000 [get_ports sd_cmd] -# set_output_delay -clock [get_clocks sd_clk_out] -max -add_delay 15.000 [get_ports sd_cmd] -# set_output_delay -clock [get_clocks sd_clk_out_1] -min -add_delay 5.000 [get_ports sd_cmd] -# set_output_delay -clock [get_clocks sd_clk_out_1] -max -add_delay 1500.000 [get_ports sd_cmd] -# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -min -add_delay 20.000 [get_ports {sd_dat[*]}] -# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -max -add_delay 35.000 [get_ports {sd_dat[*]}] -# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -min -add_delay 2000.000 [get_ports {sd_dat[*]}] -# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -max -add_delay 3500.000 [get_ports {sd_dat[*]}] -# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -min -add_delay 20.000 [get_ports sd_cmd] -# set_input_delay -clock [get_clocks VIRTUAL_sd_fast_clk] -max -add_delay 35.000 [get_ports sd_cmd] -# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -min -add_delay 2000.000 [get_ports sd_cmd] -# set_input_delay -clock [get_clocks VIRTUAL_sd_slow_clk] -max -add_delay 3500.000 [get_ports sd_cmd] -# set_clock_groups -physically_exclusive -group [get_clocks -include_generated_clocks sd_clk_out] -group [get_clocks -include_generated_clocks sd_clk_out_1] -# set_clock_groups -logically_exclusive -group [get_clocks -include_generated_clocks {VIRTUAL_sd_fast_clk sd_fast_clk}] -group [get_clocks -include_generated_clocks {sd_slow_clk VIRTUAL_sd_slow_clk}] -# set_clock_groups -asynchronous -group [get_clocks [list [get_clocks -of_objects [get_pins clk_mmcm/chipset_clk]]]] -group [get_clocks -filter { NAME =~ "*sd*" }] - -## PMOD Header JD -#set_property -dict {PACKAGE_PIN V27 IOSTANDARD LVCMOS33} [get_ports { jd[0]}] -#set_property -dict {PACKAGE_PIN Y30 IOSTANDARD LVCMOS33} [get_ports { jd[1]}] -#set_property -dict { PACKAGE_PIN V24 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L23N_T3_A02_D18_14 Sch=jd[3] -#set_property -dict { PACKAGE_PIN W22 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L24N_T3_A00_D16_14 Sch=jd[4] -#set_property -dict { PACKAGE_PIN U24 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L23P_T3_A03_D19_14 Sch=jd[7] -#set_property -dict { PACKAGE_PIN Y26 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L1P_T0_13 Sch=jd[8] -#set_property -dict { PACKAGE_PIN V22 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L22N_T3_A04_D20_14 Sch=jd[9] -#set_property -dict { PACKAGE_PIN W21 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L24P_T3_A01_D17_14 Sch=jd[10]## PMOD Header JD -#set_property -dict { PACKAGE_PIN V27 IOSTANDARD LVCMOS33 } [get_ports { jd[0] }]; #IO_L16N_T2_A15_D31_14 Sch=jd[1] -#set_property -dict { PACKAGE_PIN Y30 IOSTANDARD LVCMOS33 } [get_ports { jd[1] }]; #IO_L8P_T1_13 Sch=jd[2] -#set_property -dict { PACKAGE_PIN V24 IOSTANDARD LVCMOS33 } [get_ports { jd[2] }]; #IO_L23N_T3_A02_D18_14 Sch=jd[3] -#set_property -dict { PACKAGE_PIN W22 IOSTANDARD LVCMOS33 } [get_ports { jd[3] }]; #IO_L24N_T3_A00_D16_14 Sch=jd[4] -#set_property -dict { PACKAGE_PIN U24 IOSTANDARD LVCMOS33 } [get_ports { jd[4] }]; #IO_L23P_T3_A03_D19_14 Sch=jd[7] -#set_property -dict { PACKAGE_PIN Y26 IOSTANDARD LVCMOS33 } [get_ports { jd[5] }]; #IO_L1P_T0_13 Sch=jd[8] -#set_property -dict { PACKAGE_PIN V22 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L22N_T3_A04_D20_14 Sch=jd[9] -#set_property -dict { PACKAGE_PIN W21 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L24P_T3_A01_D17_14 Sch=jd[10] - - -# Quad SPI flash -set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] +set_property -dict {PACKAGE_PIN N12 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_scl] +set_property -dict {PACKAGE_PIN P12 IOSTANDARD LVCMOS33} [get_ports pad_i2c0_sda] +## HDMI CTL +set_property -dict {PACKAGE_PIN D1 IOSTANDARD LVCMOS33} [get_ports pad_hdmi_scl] +set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports pad_hdmi_sda] diff --git a/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v b/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v index fba78e52..629acd7b 100644 --- a/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v +++ b/fpga/pulpissimo-zcu104/rtl/xilinx_pulpissimo.v @@ -24,15 +24,10 @@ module xilinx_pulpissimo input wire ref_clk_p, input wire ref_clk_n, -// inout wire pad_spim_sdio0, - inout wire pad_spim_sdio1, - inout wire pad_spim_sdio2, - inout wire pad_spim_sdio3, - inout wire pad_spim_csn0, - inout wire pad_spim_sck, - inout wire pad_uart_rx, inout wire pad_uart_tx, + inout wire pad_uart_rts, //Mapped to spim_csn0 + inout wire pad_uart_cts, //Mapped to spim_sck inout wire led0_o, //Mapped to spim_csn1 inout wire led1_o, //Mapped to cam_pclk @@ -41,40 +36,40 @@ module xilinx_pulpissimo inout wire switch0_i, //Mapped to cam_data1 inout wire switch1_i, //Mapped to cam_data2 + inout wire switch2_i, //Mapped to cam_data7 + inout wire switch3_i, //Mapped to cam_vsync - inout wire btnc_i, //Mapped to cam_data3 - inout wire btnd_i, //Mapped to cam_data4 - inout wire btnl_i, //Mapped to cam_data5 - inout wire btnr_i, //Mapped to cam_data6 - inout wire btnu_i, //Mapped to cam_data7 - - inout wire oled_spim_sck_o, //Mapped to spim_sck - inout wire oled_spim_mosi_o, //Mapped to spim_sdio0 - inout wire oled_rst_o, //Mapped to i2s0_sck - inout wire oled_dc_o, //Mapped to i2s0_ws - inout wire oled_vbat_o, // Mapped to i2s0_sdi - inout wire oled_vdd_o, // Mapped to i2s1_sdi - - inout wire sdio_reset_o, //Reset signal for SD card need to be driven low to - //power the onboard sd-card. Mapped to cam_vsync. - inout wire pad_sdio_clk, - inout wire pad_sdio_cmd, - inout wire pad_sdio_data0, - inout wire pad_sdio_data1, - inout wire pad_sdio_data2, - inout wire pad_sdio_data3, + inout wire btn0_i, //Mapped to cam_data3 + inout wire btn1_i, //Mapped to cam_data4 + inout wire btn2_i, //Mapped to cam_data5 + inout wire btn3_i, //Mapped to cam_data6 inout wire pad_i2c0_sda, inout wire pad_i2c0_scl, - input wire pad_reset_n, - inout wire pad_bootsel, + inout wire pad_pmod0_4, //Mapped to spim_sdio0 + inout wire pad_pmod0_5, //Mapped to spim_sdio1 + inout wire pad_pmod0_6, //Mapped to spim_sdio2 + inout wire pad_pmod0_7, //Mapped to spim_sdio3 + + inout wire pad_pmod1_0, //Mapped to sdio_data0 + inout wire pad_pmod1_1, //Mapped to sdio_data1 + inout wire pad_pmod1_2, //Mapped to sdio_data2 + inout wire pad_pmod1_3, //Mapped to sdio_data3 + inout wire pad_pmod1_4, //Mapped to i2s0_sck + inout wire pad_pmod1_5, //Mapped to i2s0_ws + inout wire pad_pmod1_6, //Mapped to i2s0_sdi + inout wire pad_pmod1_7, //Mapped to i2s1_sdi + + inout wire pad_hdmi_scl, //Mapped to sdio_clk + inout wire pad_hdmi_sda, //Mapped to sdio_cmd + + input wire pad_reset, input wire pad_jtag_tck, input wire pad_jtag_tdi, output wire pad_jtag_tdo, - input wire pad_jtag_tms, - input wire pad_jtag_trst + input wire pad_jtag_tms ); localparam CORE_TYPE = 0; // 0 for RISCY, 1 for ZERORISCY, 2 for MICRORISCY @@ -103,13 +98,13 @@ module xilinx_pulpissimo .USE_HWPE(USE_HWPE) ) i_pulpissimo ( - .pad_spim_sdio0(oled_spim_mosi_o), - .pad_spim_sdio1(pad_spim_sdio1), - .pad_spim_sdio2(pad_spim_sdio2), - .pad_spim_sdio3(pad_spim_sdio3), - .pad_spim_csn0(pad_spim_csn0), + .pad_spim_sdio0(pad_pmod0_4), + .pad_spim_sdio1(pad_pmod0_5), + .pad_spim_sdio2(pad_pmod0_6), + .pad_spim_sdio3(pad_pmod0_7), + .pad_spim_csn0(pad_uart_rts), .pad_spim_csn1(led0_o), - .pad_spim_sck(oled_spim_sck_o), + .pad_spim_sck(pad_uart_cts), .pad_uart_rx(pad_uart_rx), .pad_uart_tx(pad_uart_tx), .pad_cam_pclk(led1_o), @@ -117,30 +112,30 @@ module xilinx_pulpissimo .pad_cam_data0(led3_o), .pad_cam_data1(switch0_i), .pad_cam_data2(switch1_i), - .pad_cam_data3(btnc_i), - .pad_cam_data4(btnd_i), - .pad_cam_data5(btnl_i), - .pad_cam_data6(btnr_i), - .pad_cam_data7(btnu_i), - .pad_cam_vsync(sdio_reset_o), - .pad_sdio_clk(pad_sdio_clk), - .pad_sdio_cmd(pad_sdio_cmd), - .pad_sdio_data0(pad_sdio_data0), - .pad_sdio_data1(pad_sdio_data1), - .pad_sdio_data2(pad_sdio_data2), - .pad_sdio_data3(pad_sdio_data3), + .pad_cam_data3(btn0_i), + .pad_cam_data4(btn1_i), + .pad_cam_data5(btn2_i), + .pad_cam_data6(btn3_i), + .pad_cam_data7(switch2_i), + .pad_cam_vsync(switch3_i), + .pad_sdio_clk(pad_hdmi_scl), + .pad_sdio_cmd(pad_hdmi_sda), + .pad_sdio_data0(pad_pmod1_0), + .pad_sdio_data1(pad_pmod1_1), + .pad_sdio_data2(pad_pmod1_2), + .pad_sdio_data3(pad_pmod1_3), .pad_i2c0_sda(pad_i2c0_sda), .pad_i2c0_scl(pad_i2c0_scl), - .pad_i2s0_sck(oled_rst_o), - .pad_i2s0_ws(oled_dc_o), - .pad_i2s0_sdi(oled_vbat_o), - .pad_i2s1_sdi(oled_vdd_o), - .pad_reset_n(pad_reset_n), + .pad_i2s0_sck(pad_pmod1_4), + .pad_i2s0_ws(pad_pmod1_5), + .pad_i2s0_sdi(pad_pmod1_6), + .pad_i2s1_sdi(pad_pmod1_7), + .pad_reset_n(~pad_reset), .pad_jtag_tck(pad_jtag_tck), .pad_jtag_tdi(pad_jtag_tdi), .pad_jtag_tdo(pad_jtag_tdo), .pad_jtag_tms(pad_jtag_tms), - .pad_jtag_trst(pad_jtag_trst), + .pad_jtag_trst(1'b1), .pad_xtal_in(ref_clk), .pad_bootsel() ); From cb00323bf4bab32c69e8c79c75a0d48b6098dd9d Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Wed, 31 Jul 2019 10:28:51 +0200 Subject: [PATCH 3/8] ZCU104: Timing constraints for 125MHz clock --- fpga/pulpissimo-zcu104/constraints/zcu104.xdc | 2 +- fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl | 2 +- fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc index 66f26762..c958ab8c 100644 --- a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc +++ b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc @@ -11,7 +11,7 @@ #Create constraint for the clock input of the zcu104 board -create_clock -period 5.000 -name ref_clk [get_ports ref_clk_p] +create_clock -period 8.000 -name ref_clk [get_ports ref_clk_p] #I2S and CAM interface are not used in this FPGA port. Set constraints to #disable the clock diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl index 0ae49ff0..2310e43b 100644 --- a/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl +++ b/fpga/pulpissimo-zcu104/ips/xilinx_clk_mngr/tcl/run.tcl @@ -33,7 +33,7 @@ set_property board_part $boardName [current_project] create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName -set_property -dict [eval list CONFIG.PRIM_IN_FREQ {200.000} \ +set_property -dict [eval list CONFIG.PRIM_IN_FREQ {125.000} \ CONFIG.NUM_OUT_CLKS {2} \ CONFIG.CLKOUT2_USED {true} \ CONFIG.RESET_TYPE {ACTIVE_LOW} \ diff --git a/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl index 346bb3d9..9837761f 100644 --- a/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl +++ b/fpga/pulpissimo-zcu104/ips/xilinx_slow_clk_mngr/tcl/run.tcl @@ -27,7 +27,7 @@ set_property board_part $boardName [current_project] create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName -set_property -dict [eval list CONFIG.PRIM_IN_FREQ {200.000} \ +set_property -dict [eval list CONFIG.PRIM_IN_FREQ {125.000} \ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {$SLOW_CLK_FREQ_MHZ} \ CONFIG.USE_SAFE_CLOCK_STARTUP {true} \ CONFIG.USE_LOCKED {false} \ From 20835f8c5d7b0d8c8cf4d9190fd8cc98d513489b Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Thu, 25 Jul 2019 16:02:01 +0200 Subject: [PATCH 4/8] ZCU104: Fix Vivado errors --- fpga/pulpissimo-zcu104/constraints/zcu104.xdc | 3 ++- fpga/pulpissimo-zcu104/tcl/run.tcl | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc index c958ab8c..7ce80166 100644 --- a/fpga/pulpissimo-zcu104/constraints/zcu104.xdc +++ b/fpga/pulpissimo-zcu104/constraints/zcu104.xdc @@ -22,6 +22,7 @@ set_case_analysis 0 i_pulpissimo/safe_domain_i/i2s_slave_sck_o ## JTAG create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports pad_jtag_tck] set_input_jitter tck 1.000 +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pad_jtag_tck_IBUF_inst/O] # minimize routing delay @@ -53,7 +54,7 @@ set_property ASYNC_REG true [get_cells i_pulpissimo/soc_domain_i/pulp_soc_i/soc_ # Create asynchronous clock group between slow-clk and SoC clock. Those clocks # are considered asynchronously and proper synchronization regs are in place -set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/safe_domain_i/i_slow_clk_gen/i_slow_clk_mngr/inst/mmcm_adv_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_clk_rst_gen/i_fpga_clk_gen/i_clk_manager/inst/mmcm_adv_inst/CLKOUT0]] +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/safe_domain_i/i_slow_clk_gen/slow_clk_o]] -group [get_clocks -of_objects [get_pins i_pulpissimo/soc_domain_i/pulp_soc_i/i_clk_rst_gen/i_fpga_clk_gen/soc_clk_o]] ############################################################# diff --git a/fpga/pulpissimo-zcu104/tcl/run.tcl b/fpga/pulpissimo-zcu104/tcl/run.tcl index 7cc92776..371e95b3 100644 --- a/fpga/pulpissimo-zcu104/tcl/run.tcl +++ b/fpga/pulpissimo-zcu104/tcl/run.tcl @@ -114,7 +114,6 @@ set_property "steps.place_design.args.directive" "RuntimeOptimized" [get_runs im set_property "steps.route_design.args.directive" "RuntimeOptimized" [get_runs impl_1] set_property STEPS.WRITE_BITSTREAM.ARGS.BIN_FILE true [get_runs impl_1] -set_property config_mode SPIx4 [current_design] launch_runs impl_1 -jobs 8 wait_on_run impl_1 From 44641bd826adc23c9fd1c55da91a1baae4063b19 Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Tue, 30 Jul 2019 15:44:03 +0200 Subject: [PATCH 5/8] ZCU104: Enable physical optimizations to fix hold time violations --- fpga/pulpissimo-zcu104/tcl/run.tcl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fpga/pulpissimo-zcu104/tcl/run.tcl b/fpga/pulpissimo-zcu104/tcl/run.tcl index 371e95b3..8d138a3b 100644 --- a/fpga/pulpissimo-zcu104/tcl/run.tcl +++ b/fpga/pulpissimo-zcu104/tcl/run.tcl @@ -112,6 +112,10 @@ remove_cell i_pulpissimo/pad_frame_i/padinst_bootsel set_property "steps.opt_design.args.directive" "RuntimeOptimized" [get_runs impl_1] set_property "steps.place_design.args.directive" "RuntimeOptimized" [get_runs impl_1] set_property "steps.route_design.args.directive" "RuntimeOptimized" [get_runs impl_1] +set_property "steps.phys_opt_design.args.is_enabled" true [get_runs impl_1] +set_property "steps.phys_opt_design.args.directive" "ExploreWithHoldFix" [get_runs impl_1] +set_property "steps.post_route_phys_opt_design.args.is_enabled" true [get_runs impl_1] +set_property "steps.post_route_phys_opt_design.args.directive" "ExploreWithAggressiveHoldFix" [get_runs impl_1] set_property STEPS.WRITE_BITSTREAM.ARGS.BIN_FILE true [get_runs impl_1] From 37ed25617e814ee7b0e2ede30697f3f098b8b914 Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Mon, 29 Jul 2019 12:07:48 +0200 Subject: [PATCH 6/8] ZCU104: OpenOCD script for Digilent JTAG-HS1 --- fpga/pulpissimo-zcu104/openocd-zcu104.cfg | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/fpga/pulpissimo-zcu104/openocd-zcu104.cfg b/fpga/pulpissimo-zcu104/openocd-zcu104.cfg index b0de8583..fc453400 100644 --- a/fpga/pulpissimo-zcu104/openocd-zcu104.cfg +++ b/fpga/pulpissimo-zcu104/openocd-zcu104.cfg @@ -1,24 +1,10 @@ adapter_khz 1000 +# Digilent JTAG-HS1 interface ftdi ftdi_vid_pid 0x0403 0x6010 - -# Channel 1 is taken by Xilinx JTAG ftdi_channel 0 - -# links: -# http://openocd.org/doc-release/html/Debug-Adapter-Configuration.html -# -# Bit MPSSE FT2232 JTAG Type Description -# Bit0 TCK ADBUS0 TCK Out Clock Signal Output -# Bit1 TDI ADBUS1 TDI Out Serial Data Out -# Bit2 TDO ADBUS2 TDO In Serial Data In -# Bit3 TMS ADBUS3 TMS Out Select Signal Out -# Bit4 GPIOL0 ADBUS4 nTRST In/Out General Purpose I/O -# this corresponds to the following in/out layout, with TMS initially set to 1 -ftdi_layout_init 0x0018 0x001b -# we only have to specify nTRST, the others are assigned correctly by default -ftdi_layout_signal nTRST -ndata 0x0010 +ftdi_layout_init 0x0088 0x008b set _CHIPNAME riscv From 160dd2d474c435e13caf347d2e99643e6f7945d5 Mon Sep 17 00:00:00 2001 From: Marco Widmer Date: Wed, 31 Jul 2019 10:37:47 +0200 Subject: [PATCH 7/8] ZCU104: Add readme --- fpga/pulpissimo-zcu104/README.md | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 fpga/pulpissimo-zcu104/README.md diff --git a/fpga/pulpissimo-zcu104/README.md b/fpga/pulpissimo-zcu104/README.md new file mode 100644 index 00000000..e1067e13 --- /dev/null +++ b/fpga/pulpissimo-zcu104/README.md @@ -0,0 +1,42 @@ +# PULPissimo on the Xilinx ZCU104 Board +[\[Datasheet\]](https://www.xilinx.com/support/documentation/boards_and_kits/zcu104/ug1267-zcu104-eval-bd.pdf) + +## Bitstream Generation +In the fpga folder, run +```Shell +make zcu104 +``` +which will generate `pulpissimo_zcu104.bit`. +Use Vivado to load it into the FPGA. + +## Peripherals +Most peripherals of are connected to the ARM processing system domain of the SoC and cannot be used from the programmable logic domain. +The peripherals available to PULPissimo are thus very limited. + +### Reset Button +The CPU RESET button (SW20) resets the RISC-V CPU. + +### UART +PULPissimo's UART port is mapped to Channel D of the FT4232HL chip. +When connecting the board to a computer using the USB/JTAG/UART micro-USB connector (J164), it is the last of the four detected serial devices. + +### JTAG +Unfortunately, only one channel of the FT4232HL chip is connected to the programmable logic domain. +Since we are using that channel for UART, the micro-USB connector on the board cannot be used to communicate with the RISC-V debug module over JTAG. +Instead, you need to connect a separate JTAG adapter to the GPIO port (PMOD0 header) of the board: + +| JTAG Signal | FPGA Port | J55 Pin | +|-------------|-----------|----------| +| tms | PMOD0_0 | Pin 1 | +| tdi | PMOD0_1 | Pin 3 | +| tdo | PMOD0_2 | Pin 5 | +| tck | PMOD0_3 | Pin 7 | +| gnd | GND | Pin 9 | +| vdd | 3V3 | Pin 11 | + +An OpenOCD configuration file for the Digilent JTAG-HS1 adapter is included. +To use it, run + +```Shell +$OPENOCD/bin/openocd -f pulpissimo/fpga/pulpissimo-zcu104/openocd-zcu104.cfg +``` From d99d7154f73e552cd55ef7747c7fb3f17334f1bc Mon Sep 17 00:00:00 2001 From: Manuel Eggimann Date: Tue, 6 Aug 2019 12:28:51 +0200 Subject: [PATCH 8/8] Changed READMEs related to FPGA and renamed openocd config files --- README.md | 102 +++++++++++------- fpga/pulpissimo-genesys2/README.md | 56 ++++++++++ fpga/pulpissimo-zcu104/README.md | 12 ++- ...g => openocd-zcu104-digilent-jtag-hs1.cfg} | 0 .../openocd-zcu104-olimex-arm-usb-ocd-h.cfg | 37 +++++++ 5 files changed, 169 insertions(+), 38 deletions(-) create mode 100644 fpga/pulpissimo-genesys2/README.md rename fpga/pulpissimo-zcu104/{openocd-zcu104.cfg => openocd-zcu104-digilent-jtag-hs1.cfg} (100%) create mode 100644 fpga/pulpissimo-zcu104/openocd-zcu104-olimex-arm-usb-ocd-h.cfg diff --git a/README.md b/README.md index 0c9d9144..7135c79d 100644 --- a/README.md +++ b/README.md @@ -171,31 +171,60 @@ More information is available in the documentation here: pulp-builder/install/do ## FPGA -PULPissimo has been implemented on FPGA for the Xilinx Genesys 2 board. -Follow the next steps to generate the bitstream and use it as an emulator of the microcontroller. +PULPissimo has been implemented on FPGA for the various Xilinx FPGA boards. -Go to the fpga folder and run +### Supported Boards +At the moment the following boards are supported: +* Digilent Genesys2 +* Xilinx ZCU104 + +In the release section you find precompiled bitstreams for all of the above +mentionied boards. If you want to use the latest development version PULPissimo +follow the section below to generate the bitstreams yourself. + +### Bitstream Generation +In order to generate the PULPissimo bitstream for a supported target FPGA board first generate the necessary synthesis include scripts by starting the `update-ips` script in the pulpissimo root directory: ```Shell -make help +./update-ips ``` -This lists a brief description of all available Make targets. +This will parse the ips_list.yml using the PULP IPApproX IP management tool to +generate tcl scripts for all the IPs used in the PULPissimo project. These files +are later on sourced by Vivado to generate the bitstream for PULPissimo. -In this tutorial we use the Digilent Genesys2 board which is the only one supported at the moment. +Now switch to the fpga subdirectory and start the apropriate make target to generate the bitstream: -Therefore, run +```Shell +cd fpga +make +``` +In order to show a list of all available board targets call: ```Shell -make genesys2 +make help ``` -in order to generate the PULPissimo bitstream for the GENESYS2 board. If your invocation command to start Vivado isn't `vivado` you can use the Make variable `VIVADO` to specify the right command (e.g. `make genesys2 VIVADO='vivado-2018.3 vivado'` for ETH CentOS machines.) -Boot from ROM is not available yet. The ROM will always return the `jal x0,0` to trap the core until the debug module takes over control and loads the programm into L2 memory. -Once the bitstream `pulpissimo_genesys2.bit` is generated in the fpga folder, you can open Vivado -`vivado` (we tried the 2018.3 version) and load the bitstream into the fpga or use the Configuration File (`pulpissimo_genesys2.bin`) to flash it to the on-board Configuration Memory. +This process might take a while. If everything goes well your fpga directory +should now contain two files: + +- `pulpissimo_.bit` the bitstream file for JTAG configuration of the FPGA. +- `pulpissimo_.bin` the binary configuration file to flash to a + non-volatile configuration memory. -In Vivado: + +If your invocation command to start Vivado isn't `vivado` you can use the Make +variable `VIVADO` to specify the right command (e.g. `make genesys2 +VIVADO='vivado-2018.3 vivado'` for ETH CentOS machines.) Boot from ROM is not +available yet. The ROM will always return the `jal x0,0` to trap the core until +the debug module takes over control and loads the programm into L2 memory. Once +the bitstream `pulpissimo_genesys2.bit` is generated in the fpga folder, you can +open Vivado `vivado` (we tried the 2018.3 version) and load the bitstream into +the fpga or use the Configuration File (`pulpissimo_genesys2.bin`) to flash it +to the on-board Configuration Memory. + +### Bitstream Flashing +Start Vivado then: ``` Open Hardware Manager @@ -205,34 +234,35 @@ Program device Now your FPGA is ready to emulate PULPissimo! +### Board Specific Information +Have a look at the board specific README.md files in +`fpga/pulpissimo-/README.md` for a description of peripheral +mappings and default clock frequencies. -To run or debug applications for the fpga you need to use a recent version of the PULP-SDK (commit id 3256fe7 or newer.'). Configure the SDK for the FPGA platform by running the following commands within the SDK's root directory: +### Compiling Applications for the FPGA Target +To run or debug applications for the FPGA you need to use a recent version of +the PULP-SDK (commit id 3256fe7 or newer.'). Configure the SDK for the FPGA +platform by running the following commands within the SDK's root directory: ```Shell source configs/pulpissimo.sh -source configs/fpgas/pulpissimo/genesys2.sh +source configs/fpgas/pulpissimo/.sh ``` If you updated the SDK don't forget to recompile the SDK and the dependencies. In order for the SDK to be able to configure clock dividers (e.g. the ones for the UART module) to the right values it needs to know which frequencies -PULPissimo is running at. If you didn't change anything in the synthesis script, the default frequencies are: - - -| Clock Domain | Default Frequency on Genesys2 board | -|----------------|-------------------------------------| -| Core Frequency | 20 MHz | -| SoC Frequency | 10 MHz | +PULPissimo is running at. You can find the default frequencies in the above +mentioned board specific README files. - -We need to override two weakly defined variables in our source code to configure the SDK to use these frequencies: +In our application we need to override two weakly defined variables in our source code to configure the SDK to use these frequencies: ```C #include #include -int __rt_fpga_fc_frequency = 20000000; -int __rt_fpga_periph_frequency = 10000000; +int __rt_fpga_fc_frequency = // e.g. 20000000 for 20MHz; +int __rt_fpga_periph_frequency = // e.g. 10000000 for 10MHz; int main() { @@ -257,21 +287,16 @@ make clean all This command builds the ELF binary with UART as the default io peripheral. The binary will be stored at `build/pulpissimo/[app_name]/[app_name]`. - ### GDB and OpenOCD In order to execute our application on the FPGA we need to load the binary into PULPissimo's L2 memory. To do so we can use OpenOCD in conjunction with GDB to communicate with the internal RISC-V debug module. -For the genesys2 board we need to connect two micro USB cables to the board: The -first cable connects to the JTAG port that is usually used for FPGA -configuration. Once the PULPissimo bitstream is written to the FPGA the same -port is used to let OpenOCD communicate with the RISC-V debug module within -PULPissimo. The second micro USB cable needs to be attached to the genesys2's -UART port to observe the output of the application's `printf` statements. +PULPissimo uses JTAG as a communication channel between OpenOCD and the Core. +Have a look at the board specific README file on how to connect your PC with +PULPissimo's JTAG port. - -Due to a long outstanding issue in the RISC-V openocd project (issue #359) the +Due to a long outstanding issue in the RISC-V OpenOCD project (issue #359) the riscv/riscv-openocd does not work with PULPissimo. However there is a small workaround that we incorporated in a patched version of openocd. If you have access to the artifactory server, the patched openocd binary is installed by @@ -300,12 +325,15 @@ source sourceme.sh && ./pulp-tools/bin/plpbuild checkout build --p openocd --std The SDK will automatically set the environment variable `OPENOCD` to the installation path of this patched version. -Launch openocd with the configuration file for the genesys2 board as an argument with: +Launch openocd with one of the provided or your own configuration file for the +target board as an argument. + +E.g.: ```Shell $OPENOCD/bin/openocd -f pulpissimo/fpga/pulpissimo-genesys2/openocd-genesys2.cfg ``` -In a seperate terminal launch gdb from your pulp_riscv_gcc installation passing the ELF file as an argument with: +In a seperate terminal launch gdb from your `pulp_riscv_gcc` installation passing the ELF file as an argument with: `$PULP_RISCV_GCC_TOOLCHAIN_CI/bin/riscv32-unknown-elf-gdb PATH_TO_YOUR_ELF_FILE` diff --git a/fpga/pulpissimo-genesys2/README.md b/fpga/pulpissimo-genesys2/README.md new file mode 100644 index 00000000..e8c7dc12 --- /dev/null +++ b/fpga/pulpissimo-genesys2/README.md @@ -0,0 +1,56 @@ +# PULPissimo on the Digilent Genesys2 Board +[\[Documentation\]](https://reference.digilentinc.com/reference/programmable-logic/genesys-2/start) + +## Bitstream Generation +In the fpga folder, run +```Shell +make genesys2 +``` +which will generate `pulpissimo_genesys2.bit`. +Use Vivado to load it into the FPGA. + +## Default SoC and Core Frequencies + +By default the clock generating IPs are synthesized to provide the following frequencies to PULPissimo: + +| Clock Domain | Default Frequency on Genesys2 board | +|----------------|-------------------------------------| +| Core Frequency | 20 MHz | +| SoC Frequency | 10 MHz | + + +## Peripherals +PULPissimo is connected to the following board peripherals: + + +| PULPissimo Pin | Mapped Board Peripheral | +|----------------|-----------------------------------------------------| +| `SPIM0` pins | QSPI Flash | +| `I2C0` pins | I2C Bus (connects to Board Current Measurement ICs) | +| `spim_csn1` | LED0 | +| `cam_pclk` | LED1 | +| `cam_hsync` | LED2 | +| `cam_data0` | LED3 | +| `cam_data1` | Switch 1 | +| `cam_data2` | Switch 2 | +| `cam_data3` | Button C | +| `cam_data4` | Button D | +| `cam_data5` | Button L | +| `cam_data6` | Button R | +| `cam_data7` | Button U | + +### Reset Button +The USER RESET button (BTN1) resets the RISC-V CPU. + +### UART +PULPissimo's UART port is mapped to the onboard FTDI FT232R USB-UART bridge and thus accessible through the UART micro-USB connector J15. + +### JTAG +PULPIssimo's JTAG plug is connected to Channel 0 of the onboard FTDI USB JTAG +programmer. Therefore we can attach OpenOCD withouth the need of an external +JTAG programmer. Just attach a micro-USB cable to the JTAG SW17 micro-USB connector and use the +provided OpenOCD configuration file: + +```Shell +$OPENOCD/bin/openocd -f pulpissimo/fpga/pulpissimo-genesys2/openocd-genesys2.cfg +``` diff --git a/fpga/pulpissimo-zcu104/README.md b/fpga/pulpissimo-zcu104/README.md index e1067e13..02aa1fb0 100644 --- a/fpga/pulpissimo-zcu104/README.md +++ b/fpga/pulpissimo-zcu104/README.md @@ -9,6 +9,16 @@ make zcu104 which will generate `pulpissimo_zcu104.bit`. Use Vivado to load it into the FPGA. +## Default SoC and Core Frequencies + +By default the clock generating IPs are synthesized to provide the following frequencies to PULPissimo: + +| Clock Domain | Default Frequency on ZCU104 board | +|----------------|------------------------------------| +| Core Frequency | 20 MHz | +| SoC Frequency | 10 MHz | + + ## Peripherals Most peripherals of are connected to the ARM processing system domain of the SoC and cannot be used from the programmable logic domain. The peripherals available to PULPissimo are thus very limited. @@ -38,5 +48,5 @@ An OpenOCD configuration file for the Digilent JTAG-HS1 adapter is included. To use it, run ```Shell -$OPENOCD/bin/openocd -f pulpissimo/fpga/pulpissimo-zcu104/openocd-zcu104.cfg +$OPENOCD/bin/openocd -f pulpissimo/home/meggiman/projects/pulp/pulpissimo/fpga/pulpissimo-zcu104/openocd-zcu104-digilent-jtag-hs1.cfg ``` diff --git a/fpga/pulpissimo-zcu104/openocd-zcu104.cfg b/fpga/pulpissimo-zcu104/openocd-zcu104-digilent-jtag-hs1.cfg similarity index 100% rename from fpga/pulpissimo-zcu104/openocd-zcu104.cfg rename to fpga/pulpissimo-zcu104/openocd-zcu104-digilent-jtag-hs1.cfg diff --git a/fpga/pulpissimo-zcu104/openocd-zcu104-olimex-arm-usb-ocd-h.cfg b/fpga/pulpissimo-zcu104/openocd-zcu104-olimex-arm-usb-ocd-h.cfg new file mode 100644 index 00000000..ba6bda27 --- /dev/null +++ b/fpga/pulpissimo-zcu104/openocd-zcu104-olimex-arm-usb-ocd-h.cfg @@ -0,0 +1,37 @@ +adapter_khz 1000 + +# Olimex ARM-USB-OCD-H +interface ftdi +ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" +ftdi_vid_pid 0x15ba 0x002b + +ftdi_layout_init 0x0908 0x0b1b +ftdi_layout_signal nSRST -oe 0x0200 +ftdi_layout_signal nTRST -data 0x0100 +ftdi_layout_signal LED -data 0x0800 + + +set _CHIPNAME riscv + +jtag newtap $_CHIPNAME unknown0 -irlen 5 -expected-id 0x10102001 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0x3e0 + +gdb_report_data_abort enable +gdb_report_register_access_error enable + +riscv set_reset_timeout_sec 120 +riscv set_command_timeout_sec 120 + +# prefer to use sba for system bus access +riscv set_prefer_sba on + +# dump jtag chain +scan_chain + + +init +halt +echo "Ready for Remote Connections"