diff --git a/target/fpga/Makefile b/target/fpga/Makefile index 0d630891..17bfeab8 100644 --- a/target/fpga/Makefile +++ b/target/fpga/Makefile @@ -119,3 +119,16 @@ clean_zcu102: $(MAKE) -C $(PULPISSIMO_FPGA_ROOT)/pulpissimo-zcu102 clean rm -f $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zcu102.bit rm -f $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zcu102.bin + +## Generates the bistream for the Zybo Z7 +zyboz7: $(PULPISSIMO_FPGA_ROOT)/pulpissimo/tcl/generated/compile.tcl + $(MAKE) -C $(PULPISSIMO_FPGA_ROOT)/pulpissimo-zyboz7 all + cp $(PULPISSIMO_FPGA_ROOT)/pulpissimo-zyboz7/pulpissimo-zyboz7.runs/impl_1/xilinx_pulpissimo.bit $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zyboz7.bit + cp $(PULPISSIMO_FPGA_ROOT)/pulpissimo-zyboz7/pulpissimo-zyboz7.runs/impl_1/xilinx_pulpissimo.bin $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zyboz7.bin + @echo "Bitstream generation for Zybo Z7 finished. The bitstream Configuration Memory File was copied to ./pulpissimo_zyboz7.bit and ./pulpissimo_zyboz7.bin" + +## Removes all bitstreams, *.log files and vivado related files (rm -rf vivado*) for the ZedBoard. +clean_zyboz7: + $(MAKE) -C $(PULPISSIMO_FPGA_ROOT)/pulpissimo-zyboz7 clean + rm -f $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zyboz7.bit + rm -f $(PULPISSIMO_FPGA_ROOT)/pulpissimo_zyboz7.bin diff --git a/target/fpga/pulpissimo-zyboz7/.gitignore b/target/fpga/pulpissimo-zyboz7/.gitignore new file mode 100644 index 00000000..58cd8944 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/.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-nexys_video/**/pulpissimo.bit + +**/xdc/constraints.xdc diff --git a/target/fpga/pulpissimo-zyboz7/Makefile b/target/fpga/pulpissimo-zyboz7/Makefile new file mode 100644 index 00000000..e3917cad --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/Makefile @@ -0,0 +1,41 @@ +include fpga-settings.mk + +PROJECT:=pulpissimo-$(BOARD) +VIVADO ?= vivado + +.DEFAULT_GOAL:=help + +.PHONY: help all gui ips clean-ips clk clean-clk clean + +#Make sure BENDER environment variable is available for subprocesses in Make +export BENDER + +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 ## Synthesizes necessary xilinx IP + +clean-ips: clean-clk ## Clean all IPs + +clk: ## Synthesizes the Xilinx Clocking Manager IPs + $(MAKE) -C ips/xilinx_clk_mngr all + $(MAKE) -C ips/xilinx_slow_clk_mngr all + +clean-clk: ## Removes all Clocking Wizard IP outputs + $(MAKE) -C ips/xilinx_clk_mngr clean + $(MAKE) -C ips/xilinx_slow_clk_mngr clean + +clean: clean-ips ## 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* + +download: ## Download the bitstream into the FPGA + $(VIVADO) -mode batch -source tcl/download_bitstream.tcl -tclargs $(PROJECT).runs/impl_1/xilinx_pulpissimo.bit pulpissimo_$(BOARD).bit + +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/target/fpga/pulpissimo-zyboz7/README.md b/target/fpga/pulpissimo-zyboz7/README.md new file mode 100644 index 00000000..728bdb2c --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/README.md @@ -0,0 +1,94 @@ +# PULPissimo on the ZyboZ7 +[\[Documentation\]](https://digilent.com/reference/programmable-logic/zybo-z7/start) + +## Bitstream Generation +In the `fpga` folder, run +```Shell +make zyboz7 +``` +which will generate `pulpissimo_zyboz7.bit`. + +## Bitstream Download +To download this bitstream into the FPGA connect the PROG USB header, turn the board on and run +```Shell +make -C pulpissimo-zyboz7 download +``` + +TODO + + +## Default Frequencies + +By default the clock generating IPs are synthesized from the 100 MHz input (IC17 via Y9) to provide the following frequencies to PULPissimo. +The SoC Frequency is fed into all peripherals as `periph_clk_i`. + +| Clock Domain | Frequency | +|----------------|-----------| +| Core Frequency | 20 MHz | +| SoC Frequency | 10 MHz | + + +## Peripherals +If in doubt please review constraint file for current peripheral mapping in `constraints/zedboard.xdc`. + +### Reset Button +The BTNC is connected as reset button. + +### JTAG +Since there is no way of connecting the RISC-V core to the on-board FTDI USB JTAG programmer you have to attach an external device PMOD A to do so. + +| JTAG Signal | PMOD Pin | +|-------------|----------| +| TMS | JA1 | +| TDI | JA2 | +| TDO | JA3 | +| TCK | JA4 | +| GND | JA5 | +| VCC (trgt) | JA6 | + +The directory holding this README contains OpenOCD configuration files for some known-working adapters. +The commands below are to be executed from within the `fpga` directory. + +#### Digilent HS-2 + +The HS-2 uses the same FTDI chip as the ZedBoard's JTAG port. +So to make it work change the serial number in provided +`openocd-zedboard-hs2.cfg` if you want to have it connected simultaneously with ZedBoard. If you have +Vivado running remember to disconnect the target and close HW Manager before attempting to use OpenOCD. +Otherwise there will be an error about target being busy. + +```Shell +$OPENOCD/bin/openocd -f pulpissimo-zedboard/openocd-zedboard-hs2.cfg +``` + +#### Altera USB Blaster + +After connecting the adapter with 6 jumper wires, simply run: + +```Shell +$OPENOCD/bin/openocd -f pulpissimo-zedboard/openocd-zedboard-usbblaster.cfg +``` + +### UART + +There are UART pins connected to the same PMOD as the JTAG signals (PMOD A), which are utilized by the stdio driver of the PULP SDK (e.g., for the hello example). +The following list depicts the signals (from the FPGA's point of view). + +| UART Signal | PMOD Pin | +|-------------|----------| +| RXD | JA7 | +| TXD | JA8 | +| RTS | JA9 | +| CTS | JA10 | +| GND | JA11 | + +### I2C + +Two pairs of I2C signals are available on PMOD B: + +| Signal | PMOD Pin | +|-----------|----------| +| I2C0_SCL | JB1 | +| I2C0_SDA | JB2 | +| I2C1_SCL | JB3 | +| I2C1_SDA | JB4 | diff --git a/target/fpga/pulpissimo-zyboz7/constraints/zyboz7.xdc b/target/fpga/pulpissimo-zyboz7/constraints/zyboz7.xdc new file mode 100644 index 00000000..dcb80074 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/constraints/zyboz7.xdc @@ -0,0 +1,143 @@ +####################################### +# _______ _ _ # +# |__ __(_) (_) # +# | | _ _ __ ___ _ _ __ __ _ # +# | | | | '_ ` _ \| | '_ \ / _` | # +# | | | | | | | | | | | | | (_| | # +# |_| |_|_| |_| |_|_|_| |_|\__, | # +# __/ | # +# |___/ # +####################################### + + +#Create constraint for the clock input of the ZyboZ7 +create_clock -period 8.000 -name ref_clk_i [get_ports ref_clk_i] +set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets ref_clk] + +## 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 i_pulpissimo/i_padframe/i_pulpissimo_pads/i_all_pads/i_all_pads_pads/i_pad_jtag_tck/O] + + +# 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_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 -datapath_only -from [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/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/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/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/i_soc_domain/i_pulp_soc/i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_pulpissimo/i_soc_domain/i_pulp_soc/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] +set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets pad_reset_n_IBUF] + +set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets i_pulpissimo/i_clock_gen/i_slow_clk_div/i_clk_mux/clk_o] +set_property CLOCK_DEDICATED_ROUTE ANY_CMT_COLUMN [get_nets i_pulpissimo/i_clock_gen/i_slow_clk_mngr/inst/clk_out1] + +# increase MTBF +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim0/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim1/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim2/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_adv_timer/u_tim3/u_in_stage/r_ls_clk_sync_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_apb_timer_unit/s_ref_clk*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/soc_peripherals_i/i_ref_clk_sync/i_pulp_sync/r_reg_reg*] +set_property ASYNC_REG true [get_cells i_pulpissimo/i_soc_domain/i_pulp_soc/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/i_clock_gen/slow_clk_o]] \ + -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out1]] + +# Create asynchronous clock group between Per Clock 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/i_clock_gen/i_clk_manager/clk_out1]] \ + -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out2]] + +# Create asynchronous clock group between JTAG TCK and SoC clock. +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] \ + -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out1]] + +# Create asynchronous clock group between JTAG TCK and per clock. +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] \ + -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/i_clk_manager/clk_out2]] + +# Create asynchronous clock group between slow clock and JTAG TCK. +set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins i_pulpissimo/i_clock_gen/slow_clk_o]] \ + -group [get_clocks -of_objects [get_pins i_pulpissimo/pad_jtag_tck]] + +############################################################# +# _____ ____ _____ _ _ _ # +# |_ _/ __ \ / ____| | | | | (_) # +# | || | | |_____| (___ ___| |_| |_ _ _ __ __ _ ___ # +# | || | | |______\___ \ / _ \ __| __| | '_ \ / _` / __| # +# _| || |__| | ____) | __/ |_| |_| | | | | (_| \__ \ # +# |_____\____/ |_____/ \___|\__|\__|_|_| |_|\__, |___/ # +# __/ | # +# |___/ # +############################################################# + +## Sys clock +set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports ref_clk_i] + +## Reset +set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports pad_reset] + +## Buttons +set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports btn1_i] +set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS33} [get_ports btn2_i] +set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports btn3_i] + +## PMOD JE +set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tms] +set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdi] +set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tdo] +set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports pad_jtag_tck] +set_property -dict {PACKAGE_PIN V13 IOSTANDARD LVCMOS33} [get_ports pad_uart_rx] +set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports pad_uart_tx] +set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports pad_uart_rts] +set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports pad_uart_cts] + +## PMOD JB +set_property -dict {PACKAGE_PIN V8 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_1] +set_property -dict {PACKAGE_PIN W8 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_2] +set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_3] +set_property -dict {PACKAGE_PIN V7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_4] +set_property -dict {PACKAGE_PIN Y7 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_7] +set_property -dict {PACKAGE_PIN Y6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_8] +set_property -dict {PACKAGE_PIN V6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_9] +set_property -dict {PACKAGE_PIN W6 IOSTANDARD LVCMOS33} [get_ports pad_pmodb_10] + +## LEDs +set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports led0_o] +set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33} [get_ports led1_o] +set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33} [get_ports led2_o] +set_property -dict {PACKAGE_PIN D18 IOSTANDARD LVCMOS33} [get_ports led3_o] + +## PMOD JC +set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_1] +set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_2] +set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_3] +set_property -dict {PACKAGE_PIN T10 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_4] +set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_7] +set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_8] +set_property -dict {PACKAGE_PIN T12 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_9] +set_property -dict {PACKAGE_PIN U12 IOSTANDARD LVCMOS33} [get_ports pad_pmodc_10] + +## PMOD JD +set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports pad_pmodd_1] +set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports test_clk_o] +set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports obs1_o] +set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVCMOS33} [get_ports obs2_o] + +## Switches +set_property -dict {PACKAGE_PIN G15 IOSTANDARD LVCMOS33} [get_ports switch0_i] +set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports switch1_i] +set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVCMOS33} [get_ports switch2_i] +set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports switch3_i] diff --git a/target/fpga/pulpissimo-zyboz7/fpga-settings.mk b/target/fpga/pulpissimo-zyboz7/fpga-settings.mk new file mode 100644 index 00000000..3e8d6c2a --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/fpga-settings.mk @@ -0,0 +1,7 @@ +export BOARD=zyboz7 +export XILINX_PART=xc7z020clg400-1 +export XILINX_BOARD=digilentinc.com:zybo-z7-20:part0:1.0 +export FC_CLK_PERIOD_NS=62.5 +export PER_CLK_PERIOD_NS=100 +export SLOW_CLK_PERIOD_NS=30517 +$(info Setting environment variables for $(BOARD) board) diff --git a/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/.gitignore b/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/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/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/Makefile b/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/Makefile new file mode 100644 index 00000000..08068a69 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/Makefile @@ -0,0 +1,32 @@ +PROJECT:=xilinx_clk_mngr +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl +MODE=batch + +include ../../fpga-settings.mk + +.DEFAULT_GOAL:=help + +.PHONY: help all gui clean + +all: MODE=batch ## Create and synthesize the IP in batch mode. + +gui: MODE=gui ## Create and synthesize the IP in GUI mode. + +all gui: $(PROJECT).xpr + +$(PROJECT).xpr: ../../fpga-settings.mk tcl/run.tcl + $(MAKE) clean + $(VIVADO) -mode $(MODE) -source tcl/run.tcl + +clean: ## Remove all build products + 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/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/tcl/run.tcl b/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/tcl/run.tcl new file mode 100644 index 00000000..3eb741e2 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/tcl/run.tcl @@ -0,0 +1,38 @@ +source ../../tcl/common.tcl + +# 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 $XILINX_BOARD [current_project] + +create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName + +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} \ + 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] + +create_ip_run [get_ips $ipName] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/.gitignore b/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/.gitignore new file mode 100644 index 00000000..5099fe9c --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/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/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/Makefile b/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/Makefile new file mode 100644 index 00000000..67d6d935 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/Makefile @@ -0,0 +1,32 @@ +PROJECT:=xilinx_slow_clk_mngr +VIVADO ?= vivado +VIVADOFLAGS ?= -nojournal -mode batch -source scripts/prologue.tcl +MODE=batch + +include ../../fpga-settings.mk + +.DEFAULT_GOAL:=help + +.PHONY: help all gui clean + +all: MODE=batch ## Create and synthesize the IP in batch mode. + +gui: MODE=gui ## Create and synthesize the IP in GUI mode. + +all gui: $(PROJECT).xpr + +$(PROJECT).xpr: ../../fpga-settings.mk tcl/run.tcl + $(MAKE) clean + $(VIVADO) -mode $(MODE) -source tcl/run.tcl + +clean: ## Remove all build products + 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/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/tcl/run.tcl b/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/tcl/run.tcl new file mode 100644 index 00000000..8d5b9d6b --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/ips/xilinx_slow_clk_mngr/tcl/run.tcl @@ -0,0 +1,34 @@ +source ../../tcl/common.tcl + +# 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 30517 +} + +# Multiply frequency by 256 as there is a clock divider (by 256) after the +# slow_clk_mngr since the MMCMs do not support clocks slower then 4.69 MHz. +set SLOW_CLK_FREQ_MHZ [expr 1000 * 256 / $SLOW_CLK_PERIOD_NS] + +set ipName xilinx_slow_clk_mngr + +create_project $ipName . -part $partNumber +set_property board_part $XILINX_BOARD [current_project] + +create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName + +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} \ + CONFIG.RESET_TYPE {ACTIVE_LOW} \ + CONFIG.CLKIN1_JITTER_PS {50.0} \ + CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \ + CONFIG.RESET_PORT {resetn} \ + ] [get_ips $ipName] + + +create_ip_run [get_ips $ipName] +launch_run -jobs 8 ${ipName}_synth_1 +wait_on_run ${ipName}_synth_1 diff --git a/target/fpga/pulpissimo-zyboz7/rtl/cv32e40p_clock_gate_xilinx.sv b/target/fpga/pulpissimo-zyboz7/rtl/cv32e40p_clock_gate_xilinx.sv new file mode 100644 index 00000000..5e44ef56 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/rtl/cv32e40p_clock_gate_xilinx.sv @@ -0,0 +1,25 @@ +// Copyright 2022 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 cv32e40p_clock_gate ( + input logic clk_i, + input logic en_i, + input logic scan_cg_en_i, + output logic clk_o +); + + pulp_clock_gating i_pulp_clock_gating ( + .clk_i, + .en_i, + .test_en_i (scan_cg_en_i), + .clk_o + ); + +endmodule diff --git a/target/fpga/pulpissimo-zyboz7/rtl/fpga_bootrom.sv b/target/fpga/pulpissimo-zyboz7/rtl/fpga_bootrom.sv new file mode 100644 index 00000000..79d78b3f --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/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/target/fpga/pulpissimo-zyboz7/rtl/fpga_clk_gen.sv b/target/fpga/pulpissimo-zyboz7/rtl/fpga_clk_gen.sv new file mode 100644 index 00000000..0a53727c --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/rtl/fpga_clk_gen.sv @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// 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; + + always_comb begin + soc_cfg_ack_o = 1'b0; + per_cfg_ack_o = 1'b0; + cluster_cfg_ack_o = 1'b0; + if (soc_cfg_req_i) begin + soc_cfg_ack_o = 1'b1; + end + if (per_cfg_req_i) begin + per_cfg_ack_o = 1'b1; + end + if (cluster_cfg_req_i) begin + cluster_cfg_ack_o = 1'b1; + end + end + + assign soc_cfg_r_data_o = (soc_cfg_add_i == 2'b00 ? 32'hbeef0001 : (soc_cfg_add_i == 2'b01 ? 32'hbeef0003 : (soc_cfg_add_i == 2'b00 ? 32'hbeef0005 : 32'hbeef0007))); + assign per_cfg_r_data_o = 32'hdeadda7a; + +endmodule : fpga_clk_gen diff --git a/target/fpga/pulpissimo-zyboz7/rtl/fpga_slow_clk_gen.sv b/target/fpga/pulpissimo-zyboz7/rtl/fpga_slow_clk_gen.sv new file mode 100644 index 00000000..f3db58f4 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/rtl/fpga_slow_clk_gen.sv @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// 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 + #( + parameter CLK_DIV_VALUE = 256 //The xilinx_slow_clk_mngr is supposed to + //generate an 8.3886MHz clock. We need to divide it + //by 256 to arrive to a 32.768kHz clock + ) + (input logic ref_clk_i, + input logic rst_ni, + output logic slow_clk_o + ); + + + + localparam COUNTER_WIDTH = $clog2(CLK_DIV_VALUE); + + + //Create clock divider using BUFGCE cells as the PLL/MMCM cannot generate clocks + //slower than 4.69 MHz and we need 32.768kHz + + logic [COUNTER_WIDTH-1:0] clk_counter_d, clk_counter_q; + logic clock_gate_en; + + logic intermmediate_clock; + + xilinx_slow_clk_mngr i_slow_clk_mngr + ( + .resetn(rst_ni), + .clk_in1(ref_clk_i), + .clk_out1(intermmediate_clock) + ); + + + + always_comb begin + if (clk_counter_q == CLK_DIV_VALUE-1) begin + clk_counter_d = '0; + clock_gate_en = 1'b1; + end else begin + clk_counter_d = clk_counter_q + 1; + clock_gate_en = 1'b0; + end + end + + always_ff @(posedge intermmediate_clock, negedge rst_ni) begin + if (!rst_ni) begin + clk_counter_q <= '0; + end else begin + clk_counter_q <= clk_counter_d; + end + end + + BUFGCE i_clock_gate + ( + .I(intermmediate_clock), + .CE(clock_gate_en), + .O(slow_clk_o) + ); + +endmodule : fpga_slow_clk_gen diff --git a/target/fpga/pulpissimo-zyboz7/rtl/pad_functional_xilinx.sv b/target/fpga/pulpissimo-zyboz7/rtl/pad_functional_xilinx.sv new file mode 100644 index 00000000..a3ca1cde --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/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/target/fpga/pulpissimo-zyboz7/rtl/pulp_clock_gating_xilinx.sv b/target/fpga/pulpissimo-zyboz7/rtl/pulp_clock_gating_xilinx.sv new file mode 100644 index 00000000..e4974dae --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/rtl/pulp_clock_gating_xilinx.sv @@ -0,0 +1,27 @@ +// 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 + ); + logic clk_en; + + // Use a latch based clock gate instead of BUFGCE. Otherwise we quickly run out of BUFGCTRL cells on the FPGAs. + always_latch begin + if (clk_i == 1'b0) clk_en <= en_i | test_en_i; + end + + assign clk_o = clk_i & clk_en; + +endmodule diff --git a/target/fpga/pulpissimo-zyboz7/rtl/xilinx_pulpissimo.v b/target/fpga/pulpissimo-zyboz7/rtl/xilinx_pulpissimo.v new file mode 100644 index 00000000..dd314c62 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/rtl/xilinx_pulpissimo.v @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------- +// Title : PULPissimo Verilog Wrapper +//----------------------------------------------------------------------------- +// File : xilinx_pulpissimo.v +// Author : Manuel Eggimann +// : Marek PikuĊ‚a +// Created : 08.10.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_i, + input wire pad_reset, + + output wire test_clk_o, + output wire obs1_o, + output wire obs2_o, + + // PMOD JE + inout wire pad_jtag_tck, + inout wire pad_jtag_tdi, + inout wire pad_jtag_tdo, + inout wire pad_jtag_tms, + + // PMOD JE + inout wire pad_uart_rx, + inout wire pad_uart_tx, + inout wire pad_uart_rts, + inout wire pad_uart_cts, + + inout wire led0_o, + inout wire led1_o, + inout wire led2_o, + inout wire led3_o, + + inout wire switch0_i, + inout wire switch1_i, + inout wire switch2_i, + inout wire switch3_i, + + // PMOD JC + inout wire pad_pmodc_1, + inout wire pad_pmodc_2, + inout wire pad_pmodc_3, + inout wire pad_pmodc_4, + inout wire pad_pmodc_7, + inout wire pad_pmodc_8, + inout wire pad_pmodc_9, + inout wire pad_pmodc_10, + + inout wire btn1_i, + inout wire btn2_i, + inout wire btn3_i, + + // PMOD JD + inout wire pad_pmodd_1, + + // PMOD JB + inout wire pad_pmodb_1, + inout wire pad_pmodb_2, + inout wire pad_pmodb_3, + inout wire pad_pmodb_4, + inout wire pad_pmodb_7, + inout wire pad_pmodb_8, + inout wire pad_pmodb_9, + inout wire pad_pmodb_10 +); + + localparam CORE_TYPE = 0; // 0 for RISCY, 1 for IBEX RV32IMC (formerly ZERORISCY), 2 for IBEX RV32EC (formerly MICRORISCY) + localparam USE_FPU = 1; + localparam USE_HWPE = 0; + + wire ref_clk_int; + wire rst_n; + assign rst_n = ~pad_reset; + + // Input clock buffer + BUFG i_sysclk_bufg ( + .I(ref_clk_i), + .O(ref_clk_int) + ); + + + // PULPissimo instance + pulpissimo #( + .CORE_TYPE(CORE_TYPE), + .USE_FPU(USE_FPU), + .USE_HWPE(USE_HWPE) + ) i_pulpissimo ( + .pad_ref_clk ( ref_clk_int ), + .pad_reset_n ( rst_n ), + .pad_clk_byp_en ( 1'b0 ), + + .pad_bootsel0 ( ), + .pad_bootsel1 ( ), + + .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_trstn ( ), // Tied to 1 in run.tcl + + .pad_hyper_csn ( ), + .pad_hyper_reset_n ( ), + .pad_hyper_ck ( ), + .pad_hyper_ckn ( ), + .pad_hyper_dq ( ), + .pad_hyper_rwds ( ), + + .pad_io ( { + pad_pmodd_1, // io_31 + pad_pmodc_10, // io_30 + pad_pmodc_9, // io_29 + pad_pmodc_8, // io_28 + pad_pmodc_7, // io_27 + pad_pmodc_4, // io_26 + pad_pmodc_3, // io_25 + pad_pmodc_2, // io_24 + pad_pmodc_1, // io_23 + pad_pmodb_10, // io_22 + pad_pmodb_9, // io_21 + pad_pmodb_8, // io_20 + pad_pmodb_7, // io_19 + pad_pmodb_4, // io_18 + pad_pmodb_3, // io_17 + pad_pmodb_2, // io_16 + pad_pmodb_1, // io_15 + switch3_i, // io_14 + switch2_i, // io_13 + switch1_i, // io_12 + switch0_i, // io_11 + btn3_i, // io_10 + btn2_i, // io_09 + btn1_i, // io_08 + led3_o, // io_07 + led2_o, // io_06 + led1_o, // io_05 + led0_o, // io_04 + pad_uart_rts, // io_03 + pad_uart_cts, // io_02 + pad_uart_rx, // io_01 + pad_uart_tx // io_00 + } ) + ); + +endmodule diff --git a/target/fpga/pulpissimo-zyboz7/tcl/.gitignore b/target/fpga/pulpissimo-zyboz7/tcl/.gitignore new file mode 100644 index 00000000..587a0fa6 --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/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/target/fpga/pulpissimo-zyboz7/tcl/common.tcl b/target/fpga/pulpissimo-zyboz7/tcl/common.tcl new file mode 100644 index 00000000..c90d8f6b --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/tcl/common.tcl @@ -0,0 +1,30 @@ +# detect board +if [info exists ::env(BOARD)] { + set BOARD $::env(BOARD) +} else { + puts "BOARD is not defined. Please include 'fpga-settings.mk' in your Makefile to setup necessary environment variables." + exit +} +if [info exists ::env(XILINX_BOARD)] { + set XILINX_BOARD $::env(XILINX_BOARD) +} +set partNumber $::env(XILINX_PART) + +# 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" + +# Set number of CPUs, default to 4 if system's getconf doesn't work +set CPUS [exec getconf _NPROCESSORS_ONLN] +if { ![info exists CPUS] } { + set CPUS 4 +} diff --git a/target/fpga/pulpissimo-zyboz7/tcl/download_bitstream.tcl b/target/fpga/pulpissimo-zyboz7/tcl/download_bitstream.tcl new file mode 100644 index 00000000..dab88c5f --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/tcl/download_bitstream.tcl @@ -0,0 +1,10 @@ +# required argument: path to bitstream file +open_hw_manager +connect_hw_server +open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost:*]] 0] +set device [lindex [get_hw_devices] 1] +set_property PROGRAM.FILE [lindex $argv 0] $device +set_property PROBES.FILE {} $device +# set_property FULL_PROBES.FILE {} $device +program_hw_devices $device +exit diff --git a/target/fpga/pulpissimo-zyboz7/tcl/run.tcl b/target/fpga/pulpissimo-zyboz7/tcl/run.tcl new file mode 100644 index 00000000..c19033ed --- /dev/null +++ b/target/fpga/pulpissimo-zyboz7/tcl/run.tcl @@ -0,0 +1,113 @@ +source tcl/common.tcl + +set PROJECT pulpissimo-$BOARD +set RTL ../../../rtl +set IPS ../../../ips +set CONSTRS constraints + +# create project +create_project $PROJECT . -force -part $::env(XILINX_PART) +set_property board_part $XILINX_BOARD [current_project] + +# Add sources +source ../pulpissimo/tcl/add_sources.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 +# remove_file $IPS/riscv/rtl/riscv_ex_stage.sv + +# Set Verilog Defines. +set DEFINES "FPGA_TARGET_XILINX=1 PULP_FPGA_EMUL=1 AXI4_XCHECK_OFF=1" +if { $BOARD == "zyboz7" } { + set DEFINES "$DEFINES ZYBOZ7=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/xilinx_clk_mngr.srcs/sources_1/ip/xilinx_clk_mngr/xilinx_clk_mngr.xci +read_ip $FPGA_IPS/xilinx_slow_clk_mngr/xilinx_slow_clk_mngr.srcs/sources_1/ip/xilinx_slow_clk_mngr/xilinx_slow_clk_mngr.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_bootrom.sv +add_files -norecurse $FPGA_RTL/pad_functional_xilinx.sv +add_files -norecurse $FPGA_RTL/pulp_clock_gating_xilinx.sv +add_files -norecurse $FPGA_RTL/cv32e40p_clock_gate_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/$BOARD.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 $CPUS +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) +# Disconnect the nets and connect them to ground to avoid issues in optimization +remove_cell i_pulpissimo/i_padframe/i_pulpissimo_pads/i_all_pads/i_all_pads_pads/i_pad_bootsel* +disconnect_net -objects [get_nets i_pulpissimo/i_soc_domain/bootsel_i*] +connect_net -objects [get_nets i_pulpissimo/i_soc_domain/bootsel_i*] -net i_pulpissimo/ + +remove_cell i_pulpissimo/i_padframe/i_pulpissimo_pads/i_all_pads/i_all_pads_pads/i_pad_hyper* +disconnect_net -objects [get_nets i_pulpissimo/i_soc_domain/pad_to_hyper_i*] +connect_net -objects [get_nets i_pulpissimo/i_soc_domain/pad_to_hyper_i*] -net i_pulpissimo/ + +remove_cell i_pulpissimo/i_padframe/i_pulpissimo_pads/i_all_pads/i_all_pads_pads/i_pad_jtag_trst* +disconnect_net -objects [get_nets i_pulpissimo/i_soc_domain/jtag_trst_ni] +connect_net -objects [get_nets i_pulpissimo/i_soc_domain/jtag_trst_ni] -net i_pulpissimo/ + + +# 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] + +launch_runs impl_1 -jobs $CPUS +wait_on_run impl_1 +launch_runs impl_1 -jobs $CPUS -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