Skip to content

Commit

Permalink
Add zyboz7 FPGA port
Browse files Browse the repository at this point in the history
  • Loading branch information
micprog committed May 27, 2024
1 parent b26229e commit 6b83575
Show file tree
Hide file tree
Showing 23 changed files with 1,122 additions and 0 deletions.
13 changes: 13 additions & 0 deletions target/fpga/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
22 changes: 22 additions & 0 deletions target/fpga/pulpissimo-zyboz7/.gitignore
Original file line number Diff line number Diff line change
@@ -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
41 changes: 41 additions & 0 deletions target/fpga/pulpissimo-zyboz7/Makefile
Original file line number Diff line number Diff line change
@@ -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}'
94 changes: 94 additions & 0 deletions target/fpga/pulpissimo-zyboz7/README.md
Original file line number Diff line number Diff line change
@@ -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 |
143 changes: 143 additions & 0 deletions target/fpga/pulpissimo-zyboz7/constraints/zyboz7.xdc
Original file line number Diff line number Diff line change
@@ -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]
7 changes: 7 additions & 0 deletions target/fpga/pulpissimo-zyboz7/fpga-settings.mk
Original file line number Diff line number Diff line change
@@ -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)
21 changes: 21 additions & 0 deletions target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/.gitignore
Original file line number Diff line number Diff line change
@@ -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

32 changes: 32 additions & 0 deletions target/fpga/pulpissimo-zyboz7/ips/xilinx_clk_mngr/Makefile
Original file line number Diff line number Diff line change
@@ -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}'
Loading

0 comments on commit 6b83575

Please sign in to comment.