Files
gps/targets/fpga/genesys2/flow/vivado/scripts/build.tcl
T
2026-07-12 11:01:51 +03:00

183 lines
6.8 KiB
Tcl

set script_dir [file dirname [file normalize [info script]]]
set fpga_dir [file normalize [file join $script_dir ../../..]]
set repo_dir [file normalize [file join $fpga_dir ../../..]]
set hardware_dir [file join $repo_dir hardware]
cd $repo_dir
set part_name "xc7k325tffg900-2"
set board_part "digilentinc.com:genesys2:part0:1.1"
set top_module "genesys2_rocket_top"
set out_dir [file join $fpga_dir out]
set generated_dir [file join $out_dir build generated]
set report_dir [file join $out_dir reports]
set bit_dir [file join $out_dir bitstream]
set checkpoint_dir [file join $out_dir build checkpoints]
file mkdir $generated_dir
file mkdir $report_dir
file mkdir $bit_dir
file mkdir $checkpoint_dir
set rocket_rtl_dir [file join $hardware_dir generated genesys2-soc-verilog]
set rocket_top [file join $rocket_rtl_dir VCU118RocketSystem.sv]
set rocket_filelist [file join $rocket_rtl_dir filelist.f]
set wrapper [file join $generated_dir ${top_module}.sv]
if {[info exists ::env(GPS_SYSTEM_DIR)] && [string trim $::env(GPS_SYSTEM_DIR)] ne ""} {
set gps_system_dir [file normalize $::env(GPS_SYSTEM_DIR)]
} else {
set gps_system_dir [file join $hardware_dir external gps rtl]
}
if {[info exists ::env(RF_INPUT_MODE)]} {
set rf_input_mode [string tolower [string trim $::env(RF_INPUT_MODE)]]
} else {
set rf_input_mode "pmod"
}
if {$rf_input_mode ni {"pmod" "generated" "ethernet"}} {
error "Unsupported Genesys2 RF_INPUT_MODE=$rf_input_mode. Use pmod, generated, or ethernet."
}
if {![file exists $rocket_filelist]} {
error "Rocket Verilog filelist not found: $rocket_filelist"
}
if {![file exists $rocket_top]} {
error "Rocket top Verilog not found: $rocket_top"
}
puts "Generating Genesys2 wrapper: $wrapper"
puts "Genesys2 RF input mode: $rf_input_mode"
exec python3 [file join $fpga_dir tools gen_genesys2_wrapper.py] \
--rocket-top $rocket_top \
--out $wrapper \
--rf-input-mode $rf_input_mode
set max_threads [string trim [exec nproc]]
puts "Using Vivado maxThreads=$max_threads"
set_param general.maxThreads $max_threads
set_part $part_name
if {[llength [get_board_parts -quiet $board_part]] != 0} {
set_property board_part $board_part [current_project]
}
proc apply_genesys2_async_clock_groups {} {
set fabric_clk [get_clocks -quiet pll_fabric_clk]
set gps_acq_clk [get_clocks -quiet pll_gps_acq_clk]
set gps_trck_clk [get_clocks -quiet pll_gps_trck_clk]
set gps_ref_clk [get_clocks -quiet pll_gps_ref_clk]
set gps_rf_clk [get_clocks -quiet {pll_gps_rf_exact_clk pmod_rf_clk}]
set eth_clk [get_clocks -quiet genesys2_eth_rxck]
if {[llength $fabric_clk] == 0 ||
[llength $gps_acq_clk] == 0 ||
[llength $gps_trck_clk] == 0 ||
[llength $gps_ref_clk] == 0 ||
[llength $gps_rf_clk] == 0} {
puts "Warning: not all Genesys2 async clock groups are available yet."
return
}
puts "Applying Genesys2 async clock groups."
set args [list -asynchronous \
-group $fabric_clk \
-group $gps_acq_clk \
-group $gps_trck_clk \
-group $gps_rf_clk]
if {[llength $eth_clk] != 0} {
lappend args -group $eth_clk
}
set_clock_groups {*}$args
}
set rocket_files {}
set fh [open $rocket_filelist r]
while {[gets $fh line] >= 0} {
set line [string trim $line]
if {$line eq ""} {
continue
}
set line [regsub {^\./} $line ""]
lappend rocket_files [file normalize [file join $rocket_rtl_dir $line]]
}
close $fh
puts "Reading Rocket Chip RTL..."
read_verilog -sv $rocket_files
read_verilog [file join $hardware_dir upstream rocket-chip src main resources vsrc plusarg_reader.v]
set gps_filelist [file join $hardware_dir external gps rtl filelist.f]
set gps_files {}
set gps_fh [open $gps_filelist r]
while {[gets $gps_fh rel] >= 0} {
set rel [string trim $rel]
if {$rel eq "" || [string match "#*" $rel]} {
continue
}
lappend gps_files [file join $gps_system_dir $rel]
}
close $gps_fh
puts "Reading GPS APB wrapper RTL from $gps_system_dir..."
set_property include_dirs [list [file join $gps_system_dir trck_src pulp_fifo]] [current_fileset]
read_verilog -sv $gps_files
puts "Reading Genesys2 shell RTL..."
set shell_files [list \
[file join $hardware_dir fpga vcu118 rtl axi4_ram_64.sv] \
[file join $hardware_dir fpga vcu118 rtl axi4_slave_tieoff_64.sv] \
[file join $hardware_dir fpga genesys2 rtl rocket_bscan_dmi_tunnel.sv] \
]
if {$rf_input_mode eq "ethernet"} {
puts "Reading Genesys2 Ethernet RF RTL..."
lappend shell_files \
[file join $hardware_dir fpga vcu118 rtl ethernet_rf eth_rf_async_fifo.sv] \
[file join $hardware_dir fpga vcu118 rtl ethernet_rf eth_rf_core.sv] \
[file join $hardware_dir fpga genesys2 rtl ethernet_rf eth_rf_genesys2.sv]
} else {
puts "Skipping Genesys2 Ethernet RF RTL for RF_INPUT_MODE=$rf_input_mode."
}
read_verilog -sv $shell_files
read_verilog -sv $wrapper
puts "Reading constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_rocket.xdc]
puts "Reading Genesys2 PMOD SPI constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_pmod_spi.xdc]
puts "Reading Genesys2 PMOD sensor IRQ constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_pmod_irq.xdc]
puts "Reading Genesys2 PMOD PPS constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_pmod_pps.xdc]
if {$rf_input_mode eq "pmod"} {
puts "Reading Genesys2 PMOD RF constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_pmod_rf.xdc]
} elseif {$rf_input_mode eq "ethernet"} {
puts "Reading Genesys2 Ethernet PHY constraints..."
read_xdc [file join $hardware_dir fpga genesys2 constraints genesys2_ethernet.xdc]
}
puts "Running synthesis for $part_name..."
synth_design -top $top_module -part $part_name -verilog_define SYNTHESIS
apply_genesys2_async_clock_groups
write_checkpoint -force [file join $checkpoint_dir post_synth.dcp]
report_utilization -hierarchical -file [file join $report_dir synth_utilization_hier.rpt]
report_utilization -file [file join $report_dir synth_utilization.rpt]
report_timing_summary -file [file join $report_dir synth_timing_summary.rpt]
puts "Running implementation..."
opt_design
write_checkpoint -force [file join $checkpoint_dir post_opt.dcp]
place_design
write_checkpoint -force [file join $checkpoint_dir post_place.dcp]
phys_opt_design -directive Explore
write_checkpoint -force [file join $checkpoint_dir post_phys_opt.dcp]
route_design
write_checkpoint -force [file join $checkpoint_dir post_route.dcp]
report_utilization -file [file join $report_dir route_utilization.rpt]
report_timing_summary -file [file join $report_dir route_timing_summary.rpt]
report_drc -file [file join $report_dir route_drc.rpt]
report_power -file [file join $report_dir route_power.rpt]
set bit_file [file join $bit_dir genesys2_rocket.bit]
puts "Writing bitstream: $bit_file"
write_bitstream -force $bit_file
puts "Genesys2 non-project flow complete."