Skip to content

Commit

Permalink
target/xilinx: Add option to only elaborate the design
Browse files Browse the repository at this point in the history
  • Loading branch information
alex96295 authored and CyrilKoe committed Oct 3, 2023
1 parent 864d628 commit d4c10d7
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 99 deletions.
206 changes: 109 additions & 97 deletions target/xilinx/scripts/run.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#
# Author: Florian Zaruba <[email protected]>

if {![info exists ELABORATION_ONLY]} {set ELABORATION_ONLY 0}

# Contraints files selection
switch $::env(BOARD) {
"genesys2" - "kc705" - "vc707" - "vcu128" - "zcu102" {
Expand Down Expand Up @@ -44,103 +46,113 @@ set_property top ${project}_top_xilinx [current_fileset]

update_compile_order -fileset sources_1

# Runtime optimized due to the low frequency (20MHz)
set_property strategy Flow_RuntimeOptimized [get_runs synth_1]
set_property strategy Flow_RuntimeOptimized [get_runs impl_1]

set_property XPM_LIBRARIES XPM_MEMORY [current_project]

synth_design -rtl -name rtl_1 -sfcu

set_property STEPS.SYNTH_DESIGN.ARGS.RETIMING true [get_runs synth_1]
# Enable sfcu due to package conflicts
set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} -value {-sfcu} -objects [get_runs synth_1]

# Synthesis
launch_runs synth_1
wait_on_run synth_1
open_run synth_1 -name synth_1

exec mkdir -p reports/
exec rm -rf reports/*

check_timing -verbose -file reports/$project.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/$project.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/$project.timing.rpt
report_utilization -hierarchical -file reports/$project.utilization.rpt
report_cdc -file reports/$project.cdc.rpt
report_clock_interaction -file reports/$project.clock_interaction.rpt

# Instantiate ILA
set DEBUG [llength [get_nets -hier -filter {MARK_DEBUG == 1}]]
if ($DEBUG) {
# Create core
puts "Creating debug core..."
create_debug_core u_ila_0 ila
set_property -dict "ALL_PROBE_SAME_MU true ALL_PROBE_SAME_MU_CNT 4 C_ADV_TRIGGER true C_DATA_DEPTH 16384 \
C_EN_STRG_QUAL true C_INPUT_PIPE_STAGES 0 C_TRIGIN_EN false C_TRIGOUT_EN false" [get_debug_cores u_ila_0]
## Clock
set_property port_width 1 [get_debug_ports u_ila_0/clk]
connect_debug_port u_ila_0/clk [get_nets soc_clk]
# Get nets to debug
set debugNets [lsort -dictionary [get_nets -hier -filter {MARK_DEBUG == 1}]]
set netNameLast ""
set probe_i 0
# Loop through all nets (add extra list element to ensure last net is processed)
foreach net [concat $debugNets {""}] {
# Remove trailing array index
regsub {\[[0-9]*\]$} $net {} netName
# Create probe after all signals with the same name have been collected
if {$netNameLast != $netName} {
if {$netNameLast != ""} {
puts "Creating probe $probe_i with width [llength $sigList] for signal '$netNameLast'"
# probe0 already exists, and does not need to be created
if {$probe_i != 0} {
create_debug_port u_ila_0 probe
}
set_property port_width [llength $sigList] [get_debug_ports u_ila_0/probe$probe_i]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe$probe_i]
connect_debug_port u_ila_0/probe$probe_i [get_nets $sigList]
incr probe_i
}
set sigList ""
}
lappend sigList $net
set netNameLast $netName
if {$ELABORATION_ONLY} {
set_property flow.runs.elaborate 1 [get_runs synth_1]
set_property flow.runs.synth 0 [get_runs synth_1]

launch_runs synth_1
wait_on_run synth_1

} else {

# Runtime optimized due to the low frequency (20MHz)
set_property strategy Flow_RuntimeOptimized [get_runs synth_1]
set_property strategy Flow_RuntimeOptimized [get_runs impl_1]

set_property XPM_LIBRARIES XPM_MEMORY [current_project]

synth_design -rtl -name rtl_1 -sfcu

set_property STEPS.SYNTH_DESIGN.ARGS.RETIMING true [get_runs synth_1]
# Enable sfcu due to package conflicts
set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} -value {-sfcu} -objects [get_runs synth_1]

# Synthesis
launch_runs synth_1
wait_on_run synth_1
open_run synth_1 -name synth_1

exec mkdir -p reports/
exec rm -rf reports/*

check_timing -verbose -file reports/$project.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/$project.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/$project.timing.rpt
report_utilization -hierarchical -file reports/$project.utilization.rpt
report_cdc -file reports/$project.cdc.rpt
report_clock_interaction -file reports/$project.clock_interaction.rpt

# Instantiate ILA
set DEBUG [llength [get_nets -hier -filter {MARK_DEBUG == 1}]]
if ($DEBUG) {
# Create core
puts "Creating debug core..."
create_debug_core u_ila_0 ila
set_property -dict "ALL_PROBE_SAME_MU true ALL_PROBE_SAME_MU_CNT 4 C_ADV_TRIGGER true C_DATA_DEPTH 16384 \
C_EN_STRG_QUAL true C_INPUT_PIPE_STAGES 0 C_TRIGIN_EN false C_TRIGOUT_EN false" [get_debug_cores u_ila_0]
## Clock
set_property port_width 1 [get_debug_ports u_ila_0/clk]
connect_debug_port u_ila_0/clk [get_nets soc_clk]
# Get nets to debug
set debugNets [lsort -dictionary [get_nets -hier -filter {MARK_DEBUG == 1}]]
set netNameLast ""
set probe_i 0
# Loop through all nets (add extra list element to ensure last net is processed)
foreach net [concat $debugNets {""}] {
# Remove trailing array index
regsub {\[[0-9]*\]$} $net {} netName
# Create probe after all signals with the same name have been collected
if {$netNameLast != $netName} {
if {$netNameLast != ""} {
puts "Creating probe $probe_i with width [llength $sigList] for signal '$netNameLast'"
# probe0 already exists, and does not need to be created
if {$probe_i != 0} {
create_debug_port u_ila_0 probe
}
set_property port_width [llength $sigList] [get_debug_ports u_ila_0/probe$probe_i]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe$probe_i]
connect_debug_port u_ila_0/probe$probe_i [get_nets $sigList]
incr probe_i
}
set sigList ""
}
lappend sigList $net
set netNameLast $netName
}
# Need to save save constraints before implementing the core
# set_property target_constrs_file cheshire.srcs/constrs_1/imports/constraints/$::env(BOARD).xdc [current_fileset -constrset]
save_constraints -force
implement_debug_core
write_debug_probes -force probes.ltx
}

# Implementation
launch_runs impl_1
wait_on_run impl_1
launch_runs impl_1 -to_step write_bitstream
wait_on_run impl_1

# Check timing constraints
open_run impl_1

set timingrep [report_timing_summary -no_header -no_detailed_paths -return_string]
if {[info exists ::env(CHECK_TIMING)] && $::env(CHECK_TIMING)==1} {
if {! [string match -nocase {*timing constraints are met*} $timingrep]} {
send_msg_id {USER 1-1} ERROR {Timing constraints were not met.}
return -code error
}
# Need to save save constraints before implementing the core
# set_property target_constrs_file cheshire.srcs/constrs_1/imports/constraints/$::env(BOARD).xdc [current_fileset -constrset]
save_constraints -force
implement_debug_core
write_debug_probes -force probes.ltx
}

# Implementation
launch_runs impl_1
wait_on_run impl_1
launch_runs impl_1 -to_step write_bitstream
wait_on_run impl_1

# Check timing constraints
open_run impl_1

set timingrep [report_timing_summary -no_header -no_detailed_paths -return_string]
if {[info exists ::env(CHECK_TIMING)] && $::env(CHECK_TIMING)==1} {
if {! [string match -nocase {*timing constraints are met*} $timingrep]} {
send_msg_id {USER 1-1} ERROR {Timing constraints were not met.}
return -code error
}

# Output Verilog netlist + SDC for timing simulation
write_verilog -force -mode funcsim out/${project}_funcsim.v
write_verilog -force -mode timesim out/${project}_timesim.v
write_sdf -force out/${project}_timesim.sdf

# Reports
exec mkdir -p reports/
exec rm -rf reports/*
check_timing -file reports/${project}.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/${project}.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/${project}.timing.rpt
report_utilization -hierarchical -file reports/${project}.utilization.rpt
}

# Output Verilog netlist + SDC for timing simulation
write_verilog -force -mode funcsim out/${project}_funcsim.v
write_verilog -force -mode timesim out/${project}_timesim.v
write_sdf -force out/${project}_timesim.sdf

# Reports
exec mkdir -p reports/
exec rm -rf reports/*
check_timing -file reports/${project}.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/${project}.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/${project}.timing.rpt
report_utilization -hierarchical -file reports/${project}.utilization.rpt
6 changes: 4 additions & 2 deletions target/xilinx/xilinx.mk
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ VIVADOENV ?= PROJECT=$(PROJECT) \
MODE ?= gui
VIVADOFLAGS ?= -nojournal -mode $(MODE) -source scripts/prologue.tcl

ELABORATION_ONLY ?= 0

car-xil-all: $(bit)

# Generate mcs from bitstream
Expand All @@ -61,8 +63,8 @@ $(mcs): $(bit)
# Compile bitstream
$(bit): $(ips) $(CAR_XIL_DIR)/scripts/add_sources.tcl
@mkdir -p $(out)
cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/run.tcl
cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/$(PROJECT)* $(out)
cd $(CAR_XIL_DIR) && $(VIVADOENV) $(VIVADO) $(VIVADOFLAGS) -source scripts/run.tcl -tclargs $(ELABORATION_ONLY)
[ $(ELABORATION_ONLY) -eq 0 ] && cp $(CAR_XIL_DIR)/$(PROJECT).runs/impl_1/$(PROJECT)* $(out)

# Generate ips
%.xci:
Expand Down

0 comments on commit d4c10d7

Please sign in to comment.