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."