183 lines
6.8 KiB
Tcl
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."
|