Skip to content

Commit cc5f77c

Browse files
committed
Added VMK180 example design
1 parent 25156a9 commit cc5f77c

32 files changed

+5272
-0
lines changed

example/VMK180/fpga/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Verilog PCIe VMK180 Example Design
2+
3+
## Introduction
4+
5+
This example design targets the Xilinx VMK180 FPGA board.
6+
7+
The design implements the PCIe AXI lite master module, the PCIe AXI master module, and the PCIe DMA module. A very simple Linux driver is included to test the FPGA design.
8+
9+
* FPGA: xcvm1802-vsva2197-2MP-e-S
10+
11+
## How to build
12+
13+
Run `make` to build. Ensure that the Xilinx Vivado components are in PATH.
14+
15+
Run `make` to build the driver. Ensure the headers for the running kernel are installed, otherwise the driver cannot be compiled.
16+
17+
## How to test
18+
19+
Run `make program` to program the VCU180 board with Vivado. Then load the driver with `insmod example.ko`. Check dmesg for the output.
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
###################################################################
2+
#
3+
# Xilinx Vivado FPGA Makefile
4+
#
5+
# Copyright (c) 2016 Alex Forencich
6+
# Copyright (c) 2025 Jonathan Drolet
7+
#
8+
###################################################################
9+
#
10+
# Parameters:
11+
# FPGA_TOP - Top module name
12+
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
13+
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
14+
# SYN_FILES - space-separated list of source files
15+
# INC_FILES - space-separated list of include files
16+
# XDC_FILES - space-separated list of timing constraint files
17+
# XCI_FILES - space-separated list of IP XCI files
18+
#
19+
# Example:
20+
#
21+
# FPGA_TOP = fpga
22+
# FPGA_FAMILY = VirtexUltrascale
23+
# FPGA_DEVICE = xcvu095-ffva2104-2-e
24+
# SYN_FILES = rtl/fpga.v
25+
# XDC_FILES = fpga.xdc
26+
# XCI_FILES = ip/pcspma.xci
27+
# include ../common/vivado.mk
28+
#
29+
###################################################################
30+
31+
# phony targets
32+
.PHONY: fpga vivado tmpclean clean distclean
33+
34+
# prevent make from deleting intermediate files and reports
35+
.PRECIOUS: %.xpr %.bit %.mcs %.prm
36+
.SECONDARY:
37+
38+
CONFIG ?= config.mk
39+
-include ../$(CONFIG)
40+
41+
SYN_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(SYN_FILES))) $(filter /% ./%,$(SYN_FILES))
42+
INC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(INC_FILES))) $(filter /% ./%,$(INC_FILES))
43+
XCI_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XCI_FILES))) $(filter /% ./%,$(XCI_FILES))
44+
IP_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(IP_TCL_FILES))) $(filter /% ./%,$(IP_TCL_FILES))
45+
CONFIG_TCL_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(CONFIG_TCL_FILES))) $(filter /% ./%,$(CONFIG_TCL_FILES))
46+
47+
ifdef XDC_FILES
48+
XDC_FILES_REL = $(patsubst %, ../%, $(filter-out /% ./%,$(XDC_FILES))) $(filter /% ./%,$(XDC_FILES))
49+
else
50+
XDC_FILES_REL = $(FPGA_TOP).xdc
51+
endif
52+
53+
###################################################################
54+
# Main Targets
55+
#
56+
# all: build everything
57+
# clean: remove output files and project files
58+
###################################################################
59+
60+
all: fpga
61+
62+
fpga: $(FPGA_TOP).pdi
63+
64+
vivado: $(FPGA_TOP).xpr
65+
vivado $(FPGA_TOP).xpr
66+
67+
tmpclean::
68+
-rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str *.bif *.rcdo *.rnpi gen_files static_files .Xil defines.v
69+
-rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_pdi.tcl
70+
71+
clean:: tmpclean
72+
-rm -rf *.pdi program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
73+
74+
distclean:: clean
75+
-rm -rf rev
76+
77+
###################################################################
78+
# Target implementations
79+
###################################################################
80+
81+
# Vivado project file
82+
create_project.tcl: Makefile $(XCI_FILES_REL) $(IP_TCL_FILES_REL)
83+
rm -rf defines.v
84+
touch defines.v
85+
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
86+
echo "create_project -force -part $(FPGA_PART) $(FPGA_TOP)" > $@
87+
echo "add_files -fileset sources_1 defines.v $(SYN_FILES_REL)" >> $@
88+
echo "add_files -fileset constrs_1 $(XDC_FILES_REL)" >> $@
89+
for x in $(XCI_FILES_REL); do echo "import_ip $$x" >> $@; done
90+
for x in $(IP_TCL_FILES_REL); do echo "source $$x" >> $@; done
91+
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
92+
93+
update_config.tcl: $(CONFIG_TCL_FILES_REL)
94+
echo "open_project -quiet $(FPGA_TOP).xpr" > $@
95+
for x in $(CONFIG_TCL_FILES_REL); do echo "source $$x" >> $@; done
96+
97+
$(FPGA_TOP).xpr: create_project.tcl update_config.tcl
98+
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
99+
100+
# synthesis run
101+
%.runs/synth_1/%.dcp: %.xpr $(SYN_FILES_REL) $(INC_FILES_REL) $(XDC_FILES_REL) $(CONFIG_TCL_FILES_REL)
102+
echo "open_project $*.xpr" > run_synth.tcl
103+
echo "reset_run synth_1" >> run_synth.tcl
104+
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
105+
echo "wait_on_run synth_1" >> run_synth.tcl
106+
vivado -nojournal -nolog -mode batch -source run_synth.tcl
107+
108+
# implementation run
109+
%.runs/impl_1/%_routed.dcp: %.runs/synth_1/%.dcp
110+
echo "open_project $*.xpr" > run_impl.tcl
111+
echo "reset_run impl_1" >> run_impl.tcl
112+
echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl
113+
echo "wait_on_run impl_1" >> run_impl.tcl
114+
vivado -nojournal -nolog -mode batch -source run_impl.tcl
115+
116+
# pdi file
117+
%.pdi: %.runs/impl_1/%_routed.dcp
118+
echo "open_project $*.xpr" > generate_pdi.tcl
119+
echo "open_run impl_1" >> generate_pdi.tcl
120+
echo "write_device_image -force $*.pdi" >> generate_pdi.tcl
121+
vivado -nojournal -nolog -mode batch -source generate_pdi.tcl
122+
mkdir -p rev
123+
EXT=pdi; COUNT=100; \
124+
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
125+
do COUNT=$$((COUNT+1)); done; \
126+
cp $@ rev/$*_rev$$COUNT.$$EXT; \
127+
echo "Output: rev/$*_rev$$COUNT.$$EXT";

example/VMK180/fpga/driver

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../common/driver/example/

example/VMK180/fpga/fpga.xdc

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# XDC constraints for the Xilinx VMK180 board
2+
# part: xcvm1802-vsva2197-2MP-e-S
3+
4+
5+
6+
# LEDs
7+
set_property -dict {LOC H34 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
8+
set_property -dict {LOC J33 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
9+
set_property -dict {LOC K36 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
10+
set_property -dict {LOC L35 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {led[3]}]
11+
12+
set_false_path -to [get_ports {led[*]}]
13+
set_output_delay 0 [get_ports {led[*]}]
14+
15+
# DIP switches
16+
set_property -dict {LOC J35 IOSTANDARD LVCMOS18} [get_ports {sw[0]}]
17+
set_property -dict {LOC J34 IOSTANDARD LVCMOS18} [get_ports {sw[1]}]
18+
set_property -dict {LOC H37 IOSTANDARD LVCMOS18} [get_ports {sw[2]}]
19+
set_property -dict {LOC H36 IOSTANDARD LVCMOS18} [get_ports {sw[3]}]
20+
21+
set_false_path -from [get_ports {sw[*]}]
22+
set_input_delay 0 [get_ports {sw[*]}]
23+
24+
# PCIe clock
25+
set_property -dict {LOC W39 } [get_ports pcie_clk0_p] ;# GTY_REFCLKP0_103
26+
set_property -dict {LOC W40 } [get_ports pcie_clk0_n] ;# GTY_REFCLKN0_103
27+
create_clock -period 10.000 -name pcie_clk [get_ports pcie_clk0_p]
28+
29+
# PCIe Interface
30+
set_property -dict {LOC AB46 } [get_ports {pcie_rx_p[0]}] ;# GTY_RXP0_103
31+
set_property -dict {LOC AB47 } [get_ports {pcie_rx_n[0]}] ;# GTY_RXN0_103
32+
set_property -dict {LOC AB41 } [get_ports {pcie_tx_p[0]}] ;# GTY_TXP0_103
33+
set_property -dict {LOC AB42 } [get_ports {pcie_tx_n[0]}] ;# GTY_TXN0_103
34+
set_property -dict {LOC AA44 } [get_ports {pcie_rx_p[1]}] ;# GTY_RXP2_103
35+
set_property -dict {LOC AA45 } [get_ports {pcie_rx_n[1]}] ;# GTY_RXN2_103
36+
set_property -dict {LOC Y41 } [get_ports {pcie_tx_p[1]}] ;# GTY_TXP2_103
37+
set_property -dict {LOC Y42 } [get_ports {pcie_tx_n[1]}] ;# GTY_TXN2_103
38+
set_property -dict {LOC Y46 } [get_ports {pcie_rx_p[2]}] ;# GTY_RXP2_103
39+
set_property -dict {LOC Y47 } [get_ports {pcie_rx_n[2]}] ;# GTY_RXN2_103
40+
set_property -dict {LOC V41 } [get_ports {pcie_tx_p[2]}] ;# GTY_TXN2_103
41+
set_property -dict {LOC V42 } [get_ports {pcie_tx_n[2]}] ;# GTY_TXN2_103
42+
set_property -dict {LOC W44 } [get_ports {pcie_rx_p[3]}] ;# GTY_RXN3_103
43+
set_property -dict {LOC W45 } [get_ports {pcie_rx_n[3]}] ;# GTY_RXN3_103
44+
set_property -dict {LOC U43 } [get_ports {pcie_tx_p[3]}] ;# GTY_TXN3_103
45+
set_property -dict {LOC U44 } [get_ports {pcie_tx_n[3]}] ;# GTY_TXN3_103
46+
set_property -dict {LOC V46 } [get_ports {pcie_rx_p[4]}] ;# GTY_RXN4_104
47+
set_property -dict {LOC V47 } [get_ports {pcie_rx_n[4]}] ;# GTY_RXN4_104
48+
set_property -dict {LOC T41 } [get_ports {pcie_tx_p[4]}] ;# GTY_TXN4_104
49+
set_property -dict {LOC T42 } [get_ports {pcie_tx_n[4]}] ;# GTY_TXN4_104
50+
set_property -dict {LOC T46 } [get_ports {pcie_rx_p[5]}] ;# GTY_RXN5_104
51+
set_property -dict {LOC T47 } [get_ports {pcie_rx_n[5]}] ;# GTY_RXN5_104
52+
set_property -dict {LOC R43 } [get_ports {pcie_tx_p[5]}] ;# GTY_TXN5_104
53+
set_property -dict {LOC R44 } [get_ports {pcie_tx_n[5]}] ;# GTY_TXN5_104
54+
set_property -dict {LOC P46 } [get_ports {pcie_rx_p[6]}] ;# GTY_RXN6_104
55+
set_property -dict {LOC P47 } [get_ports {pcie_rx_n[6]}] ;# GTY_RXN6_104
56+
set_property -dict {LOC P41 } [get_ports {pcie_tx_p[6]}] ;# GTY_TXN6_104
57+
set_property -dict {LOC P42 } [get_ports {pcie_tx_n[6]}] ;# GTY_TXN6_104
58+
set_property -dict {LOC N44 } [get_ports {pcie_rx_p[7]}] ;# GTY_RXN7_104
59+
set_property -dict {LOC N45 } [get_ports {pcie_rx_n[7]}] ;# GTY_RXN7_104
60+
set_property -dict {LOC M41 } [get_ports {pcie_tx_p[7]}] ;# GTY_TXN7_104
61+
set_property -dict {LOC M42 } [get_ports {pcie_tx_n[7]}] ;# GTY_TXN7_104

example/VMK180/fpga/fpga/Makefile

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
# FPGA settings
3+
FPGA_PART = xcvm1802-vsva2197-2MP-e-S
4+
FPGA_TOP = fpga
5+
FPGA_ARCH = versalprime
6+
7+
# Files for synthesis
8+
SYN_FILES = rtl/fpga.v
9+
SYN_FILES += rtl/fpga_core.v
10+
SYN_FILES += rtl/debounce_switch.v
11+
SYN_FILES += rtl/sync_reset.v
12+
SYN_FILES += rtl/sync_signal.v
13+
SYN_FILES += rtl/common/example_core_pcie_us.v
14+
SYN_FILES += rtl/common/example_core_pcie.v
15+
SYN_FILES += rtl/common/example_core.v
16+
SYN_FILES += rtl/common/axi_ram.v
17+
SYN_FILES += lib/pcie/rtl/pcie_us_if.v
18+
SYN_FILES += lib/pcie/rtl/pcie_us_if_rc.v
19+
SYN_FILES += lib/pcie/rtl/pcie_us_if_rq.v
20+
SYN_FILES += lib/pcie/rtl/pcie_us_if_cq.v
21+
SYN_FILES += lib/pcie/rtl/pcie_us_if_cc.v
22+
SYN_FILES += lib/pcie/rtl/pcie_us_cfg.v
23+
SYN_FILES += lib/pcie/rtl/pcie_axil_master.v
24+
SYN_FILES += lib/pcie/rtl/pcie_axi_master.v
25+
SYN_FILES += lib/pcie/rtl/pcie_axi_master_rd.v
26+
SYN_FILES += lib/pcie/rtl/pcie_axi_master_wr.v
27+
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux_bar.v
28+
SYN_FILES += lib/pcie/rtl/pcie_tlp_demux.v
29+
SYN_FILES += lib/pcie/rtl/pcie_tlp_mux.v
30+
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo.v
31+
SYN_FILES += lib/pcie/rtl/pcie_tlp_fifo_raw.v
32+
SYN_FILES += lib/pcie/rtl/pcie_msix.v
33+
SYN_FILES += lib/pcie/rtl/dma_if_pcie.v
34+
SYN_FILES += lib/pcie/rtl/dma_if_pcie_rd.v
35+
SYN_FILES += lib/pcie/rtl/dma_if_pcie_wr.v
36+
SYN_FILES += lib/pcie/rtl/dma_psdpram.v
37+
SYN_FILES += lib/pcie/rtl/priority_encoder.v
38+
SYN_FILES += lib/pcie/rtl/pulse_merge.v
39+
40+
# XDC files
41+
XDC_FILES = fpga.xdc
42+
43+
# IP
44+
IP_TCL_FILES = ip/versal_cips.tcl
45+
46+
include ../common/vivado.mk
47+
48+
program: $(FPGA_TOP).pdi
49+
echo "open_hw_manager" > program.tcl
50+
echo "connect_hw_server -url 172.30.0.49:3121 -allow_non_jtag" >> program.tcl
51+
echo "current_hw_target [get_hw_targets */xilinx_tcf/Xilinx/127.0.0.1:2542]" >> program.tcl
52+
echo "set_property PARAM.FREQUENCY 10000000 [get_hw_targets */xilinx_tcf/Xilinx/127.0.0.1:2542]" >> program.tcl
53+
echo "open_hw_target" >> program.tcl
54+
echo "current_hw_device [get_hw_devices xcvm1802_1]" >> program.tcl
55+
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
56+
echo "set_property PROGRAM.FILE {$(FPGA_TOP).pdi} [current_hw_device]" >> program.tcl
57+
echo "program_hw_devices [current_hw_device]" >> program.tcl
58+
echo "exit" >> program.tcl
59+
vivado -nojournal -nolog -mode batch -source program.tcl

0 commit comments

Comments
 (0)