Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/user/AutoMemories.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ into `$(RESULTS_DIR)/memories_inferred.json`, and

Synthesis (canonicalization) blackboxes the converted modules so the
liberty view wins over their behavioral bodies; floorplan through final
read the generated `.lib`/`.lef` alongside `ADDITIONAL_LIBS`/
`ADDITIONAL_LEFS`. Everything downstream keys off the files above —
nothing else passes between the generator and the flow. That file-based
handoff is what lets build systems (e.g. bazel-orfs) declare the
generated artifacts as ordinary stage outputs and transitive
dependencies of the remaining stages.
read the `<m>.lib`/`<m>.lef` of each module `blackboxes.txt` lists,
alongside `ADDITIONAL_LIBS`/`ADDITIONAL_LEFS`. Everything downstream keys
off the files above, by the names the lists give: a file in `memories/`
that no list names is not read, and a list that is missing stops the
step that reads it. Nothing else passes between the generator and the
flow. That file-based handoff is what lets build systems (e.g.
bazel-orfs) declare the generated artifacts as ordinary stage outputs
and transitive dependencies of the remaining stages.

Memories that are *not* converted stay in the netlist and synthesize to
flip-flops, like any other RTL.
Expand Down
7 changes: 7 additions & 0 deletions docs/user/FlowVariables.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ configuration file.
| <a name="FILL_CELLS"></a>FILL_CELLS| Fill cells are used to fill empty sites. If not set or empty, fill cell insertion is skipped.| |
| <a name="FILL_CONFIG"></a>FILL_CONFIG| JSON rule file for metal fill during chip finishing.| |
| <a name="FLOORPLAN_DEF"></a>FLOORPLAN_DEF| Use the DEF file to initialize floorplan. Mutually exclusive with FOOTPRINT or DIE_AREA/CORE_AREA or CORE_UTILIZATION.| |
| <a name="FLOW_INPUT_VARIANT"></a>FLOW_INPUT_VARIANT| Flow variant a stage reads the previous stage's result from, the .odb and the .sdc beside it. Defaults to FLOW_VARIANT. A variant forked off another sets it to that variant for the first stage it runs, then leaves it at the default: the shared stages run once, and the fork writes only its own results. A stage's later steps read the stage's own results. A stage stops when its input is in both variants. Not with AUTO_MEMORIES=1, whose memories are read from the variant that synthesised them.| |
| <a name="FLOW_VARIANT"></a>FLOW_VARIANT| Flow variant to use, used in the flow variant directory name.| base|
| <a name="FOOTPRINT"></a>FOOTPRINT| Custom footprint definition file for ICeWall-based floorplan initialization. Mutually exclusive with FLOORPLAN_DEF or DIE_AREA/CORE_AREA or CORE_UTILIZATION.| |
| <a name="FOOTPRINT_TCL"></a>FOOTPRINT_TCL| Specifies a Tcl script with custom footprint-related commands for floorplan setup.| |
Expand Down Expand Up @@ -421,6 +422,7 @@ configuration file.
- [CORE_UTILIZATION](#CORE_UTILIZATION)
- [DIE_AREA](#DIE_AREA)
- [FLOORPLAN_DEF](#FLOORPLAN_DEF)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [FOOTPRINT](#FOOTPRINT)
- [FOOTPRINT_TCL](#FOOTPRINT_TCL)
- [GLOBAL_CONNECT_TCL](#GLOBAL_CONNECT_TCL)
Expand Down Expand Up @@ -501,6 +503,7 @@ configuration file.
- [ENABLE_DPO](#ENABLE_DPO)
- [ENABLE_PLACE_REPAIR_TIMING](#ENABLE_PLACE_REPAIR_TIMING)
- [FLOORPLAN_DEF](#FLOORPLAN_DEF)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [GLOBAL_PLACEMENT_ARGS](#GLOBAL_PLACEMENT_ARGS)
- [GPL_KEEP_OVERFLOW](#GPL_KEEP_OVERFLOW)
- [GPL_PLACE_IOS](#GPL_PLACE_IOS)
Expand Down Expand Up @@ -545,6 +548,7 @@ configuration file.
- [CTS_SNAPSHOTS](#CTS_SNAPSHOTS)
- [DETAILED_METRICS](#DETAILED_METRICS)
- [DETAIL_PLACEMENT_ARGS](#DETAIL_PLACEMENT_ARGS)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [HOLD_SLACK_MARGIN](#HOLD_SLACK_MARGIN)
- [LEC_AUX_VERILOG_FILES](#LEC_AUX_VERILOG_FILES)
- [LEC_CHECK](#LEC_CHECK)
Expand Down Expand Up @@ -572,6 +576,7 @@ configuration file.
- [DETAILED_METRICS](#DETAILED_METRICS)
- [DETAIL_PLACEMENT_ARGS](#DETAIL_PLACEMENT_ARGS)
- [ENABLE_RESISTANCE_AWARE](#ENABLE_RESISTANCE_AWARE)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [GLOBAL_ROUTE_ARGS](#GLOBAL_ROUTE_ARGS)
- [GLOBAL_ROUTE_USE_CUGR](#GLOBAL_ROUTE_USE_CUGR)
- [GRT_SEED](#GRT_SEED)
Expand Down Expand Up @@ -607,6 +612,7 @@ configuration file.
- [DETAILED_ROUTE_END_ITERATION](#DETAILED_ROUTE_END_ITERATION)
- [DISABLE_VIA_GEN](#DISABLE_VIA_GEN)
- [FILL_CELLS](#FILL_CELLS)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [MATCH_CELL_FOOTPRINT](#MATCH_CELL_FOOTPRINT)
- [MAX_REPAIR_ANTENNAS_ITER_DRT](#MAX_REPAIR_ANTENNAS_ITER_DRT)
- [MAX_ROUTING_LAYER](#MAX_ROUTING_LAYER)
Expand All @@ -630,6 +636,7 @@ configuration file.

- [ADDITIONAL_GDS](#ADDITIONAL_GDS)
- [CDL_FILE](#CDL_FILE)
- [FLOW_INPUT_VARIANT](#FLOW_INPUT_VARIANT)
- [GDS_ALLOW_EMPTY](#GDS_ALLOW_EMPTY)
- [GND_NETS_VOLTAGES](#GND_NETS_VOLTAGES)
- [LEC_AUX_VERILOG_FILES](#LEC_AUX_VERILOG_FILES)
Expand Down
18 changes: 9 additions & 9 deletions flow/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ do-klayout:
--template $(KLAYOUT_TECH_FILE) \
--output $(OBJECTS_DIR)/klayout.lyt \
--lef-files $(OBJECTS_DIR)/klayout_tech.lef $(SC_LEF) $(ADDITIONAL_LEFS) \
$(if $(filter 1,$(AUTO_MEMORIES)),$(wildcard $(RESULTS_DIR)/memories/*.lef)) \
--map-files $(wildcard $(FLOW_HOME)/platforms/$(PLATFORM)/*map)
--map-files $(wildcard $(FLOW_HOME)/platforms/$(PLATFORM)/*map) \
$(if $(filter 1,$(AUTO_MEMORIES)),--blackboxes $(RESULTS_DIR)/memories/blackboxes.txt)

$(OBJECTS_DIR)/klayout_wrap.lyt: $(KLAYOUT_TECH_FILE) $(OBJECTS_DIR)/klayout_tech.lef
$(UNSET_AND_MAKE) do-klayout_wrap
Expand Down Expand Up @@ -452,7 +452,7 @@ endef
# ==============================================================================

# Custom target to go from synthesis to placement in a single OpenROAD run
$(eval $(call do-step,1_3_floorplan_to_place, $(RESULTS_DIR)/1_synth.odb,floorplan_to_place))
$(eval $(call do-step,1_3_floorplan_to_place, $(INPUT_RESULTS_DIR)/1_synth.odb,floorplan_to_place))

$(eval $(call OPEN_GUI_SHORTCUT,yosys,1_2_yosys.v))

Expand Down Expand Up @@ -488,7 +488,7 @@ ifneq ($(filter 1,$(LEC_CHECK) $(SEC_CHECK)),)
$(RESULTS_DIR)/1_synth_lec.v: | check-kepler-formal
endif

$(eval $(call do-step,2_1_floorplan,$(RESULTS_DIR)/1_synth.odb $(TECH_LEF) $(SC_LEF) $(ADDITIONAL_LEFS) $(FOOTPRINT) $(SIG_MAP_FILE) $(FOOTPRINT_TCL) $(LIB_FILES) $(IO_CONSTRAINTS),floorplan))
$(eval $(call do-step,2_1_floorplan,$(INPUT_RESULTS_DIR)/1_synth.odb $(TECH_LEF) $(SC_LEF) $(ADDITIONAL_LEFS) $(FOOTPRINT) $(SIG_MAP_FILE) $(FOOTPRINT_TCL) $(LIB_FILES) $(IO_CONSTRAINTS),floorplan))

# STEP 2: Macro Placement
#-------------------------------------------------------------------------------
Expand Down Expand Up @@ -526,7 +526,7 @@ place: $(RESULTS_DIR)/3_place.odb
# ==============================================================================
# STEP 1: Global placement without placed IOs, timing-driven, and routability-driven.
#-------------------------------------------------------------------------------
$(eval $(call do-step,3_1_place_gp_skip_io,$(RESULTS_DIR)/2_floorplan.odb $(LIB_FILES),global_place_skip_io))
$(eval $(call do-step,3_1_place_gp_skip_io,$(INPUT_RESULTS_DIR)/2_floorplan.odb $(LIB_FILES),global_place_skip_io))

$(eval $(call do-step,3_2_place_iop,$(RESULTS_DIR)/3_1_place_gp_skip_io.odb,io_placement))

Expand Down Expand Up @@ -580,7 +580,7 @@ ifeq ($(LEC_CHECK),1)
DO_STEP_DEPS_4_1_cts += check-kepler-formal
endif

$(eval $(call do-step,4_1_cts,$(RESULTS_DIR)/3_place.odb,cts))
$(eval $(call do-step,4_1_cts,$(INPUT_RESULTS_DIR)/3_place.odb,cts))

ifeq ($(LEC_CHECK),1)
$(RESULTS_DIR)/4_1_cts.odb: | check-kepler-formal
Expand Down Expand Up @@ -618,11 +618,11 @@ grt: $(RESULTS_DIR)/5_1_grt.odb

# STEP 1: Run global route
#-------------------------------------------------------------------------------
$(eval $(call do-step,5_1_grt,$(RESULTS_DIR)/4_cts.odb $(FASTROUTE_TCL) $(PRE_GLOBAL_ROUTE_TCL),global_route))
$(eval $(call do-step,5_1_grt,$(INPUT_RESULTS_DIR)/4_cts.odb $(FASTROUTE_TCL) $(PRE_GLOBAL_ROUTE_TCL),global_route))

# STEP 2: Run detailed route
#-------------------------------------------------------------------------------
$(eval $(call do-step,5_2_route,$(RESULTS_DIR)/5_1_grt.odb,detail_route))
$(eval $(call do-step,5_2_route,$(INPUT_RESULTS_DIR)/5_1_grt.odb,detail_route))

$(eval $(call do-step,5_3_fillcell,$(RESULTS_DIR)/5_2_route.odb,fillcell))

Expand Down Expand Up @@ -680,7 +680,7 @@ elapsed:
elapsed-all:
@$(PYTHON_EXE) $(UTILS_DIR)/genElapsedTime.py -d $(shell find $(WORK_HOME)/logs/$(PLATFORM)/*/*/ -type d)

$(eval $(call do-step,6_1_fill,$(RESULTS_DIR)/5_route.odb $(FILL_CONFIG),density_fill))
$(eval $(call do-step,6_1_fill,$(INPUT_RESULTS_DIR)/5_route.odb $(FILL_CONFIG),density_fill))

ifneq ($(filter 1,$(LEC_CHECK) $(SEC_CHECK)),)
DO_STEP_DEPS_6_report += check-kepler-formal
Expand Down
2 changes: 1 addition & 1 deletion flow/scripts/cts.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ utl::set_metrics_stage "cts__{}"
source $::env(SCRIPTS_DIR)/load.tcl
source $::env(SCRIPTS_DIR)/formal_check.tcl
erase_non_stage_variables cts
load_design 3_place.odb
load_stage_input 3_place.odb
source_step_tcl PRE CTS

# Clone clock tree inverters next to register loads
Expand Down
4 changes: 2 additions & 2 deletions flow/scripts/density_fill.tcl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source $::env(SCRIPTS_DIR)/load.tcl
erase_non_stage_variables final
load_design 5_route.odb
load_stage_input 5_route.odb
source_step_tcl PRE DENSITY_FILL

if { $::env(USE_FILL) } {
Expand All @@ -11,7 +11,7 @@ if { $::env(USE_FILL) } {
write_verilog $::env(RESULTS_DIR)/6_1_fill.v
orfs_write_db $::env(RESULTS_DIR)/6_1_fill.odb
} else {
orfs_copy_db $::env(RESULTS_DIR)/5_route.odb $::env(RESULTS_DIR)/6_1_fill.odb
orfs_copy_db $::env(INPUT_RESULTS_DIR)/5_route.odb $::env(RESULTS_DIR)/6_1_fill.odb
# There is no 5_route.v file to copy
}

Expand Down
2 changes: 1 addition & 1 deletion flow/scripts/detail_route.tcl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
utl::set_metrics_stage "detailedroute__{}"
source $::env(SCRIPTS_DIR)/load.tcl
load_design 5_1_grt.odb
load_stage_input 5_1_grt.odb
source_step_tcl PRE DETAIL_ROUTE

if { !$::env(SKIP_DETAILED_ROUTE) } {
Expand Down
2 changes: 1 addition & 1 deletion flow/scripts/floorplan.tcl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
utl::set_metrics_stage "floorplan__{}"
source $::env(SCRIPTS_DIR)/load.tcl
erase_non_stage_variables floorplan
load_design 1_synth.odb
load_stage_input 1_synth.odb

# The global connections, before any step can mark an instance
# dont_touch: global_connect skips one (ODB-0383). The rules stay in the
Expand Down
4 changes: 2 additions & 2 deletions flow/scripts/global_place_skip_io.tcl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
source $::env(SCRIPTS_DIR)/load.tcl
erase_non_stage_variables place
if { $::env(GPL_PLACE_IOS) } {
orfs_copy_db $::env(RESULTS_DIR)/2_floorplan.odb \
orfs_copy_db $::env(INPUT_RESULTS_DIR)/2_floorplan.odb \
$::env(RESULTS_DIR)/3_1_place_gp_skip_io.odb
return
}
load_design 2_floorplan.odb
load_stage_input 2_floorplan.odb
source_step_tcl PRE GLOBAL_PLACE_SKIP_IO

if { [env_var_exists_and_non_empty FLOORPLAN_DEF] } {
Expand Down
2 changes: 1 addition & 1 deletion flow/scripts/global_route.tcl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
utl::set_metrics_stage "globalroute__{}"
source $::env(SCRIPTS_DIR)/load.tcl
erase_non_stage_variables grt
load_design 4_cts.odb
load_stage_input 4_cts.odb

source_step_tcl PRE GLOBAL_ROUTE

Expand Down
39 changes: 30 additions & 9 deletions flow/scripts/load.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,31 @@ source $::env(SCRIPTS_DIR)/util.tcl

source $::env(SCRIPTS_DIR)/report_metrics.tcl

# A step's input is the result of an earlier step of its stage.
proc load_design { design_file } {
load_design_from $::env(RESULTS_DIR) $design_file
}

# A stage's input is the previous stage's result, read from the
# variant FLOW_INPUT_VARIANT names.
proc load_stage_input { design_file } {
if { $::env(INPUT_RESULTS_DIR) ne $::env(RESULTS_DIR) } {
if { $::env(AUTO_MEMORIES) } {
error "AUTO_MEMORIES=1 reads the memories synthesised in this variant,\
$::env(FLOW_VARIANT), and FLOW_INPUT_VARIANT=$::env(FLOW_INPUT_VARIANT)\
reads the design from another"
}
if { [file exists $::env(RESULTS_DIR)/$design_file] } {
error "$design_file is in both FLOW_VARIANT=$::env(FLOW_VARIANT) and\
FLOW_INPUT_VARIANT=$::env(FLOW_INPUT_VARIANT). Run the stage that\
reads another variant alone, then the stages after it with\
FLOW_INPUT_VARIANT unset, and remove a copy left from an earlier run."
}
}
load_design_from $::env(INPUT_RESULTS_DIR) $design_file
}

proc load_design_from { dir design_file } {
# Do not reload if design is already loaded
set db [ord::get_db]
if { [$db getChip] != "NULL" && [[$db getChip] getBlock] != "NULL" } {
Expand All @@ -23,22 +47,19 @@ proc load_design { design_file } {
read_lef $lef
}
}
# AUTO_MEMORIES: abstract LEFs generated pre-synthesis; globbed
# because the file names are only known at run time.
if { [env_var_equals AUTO_MEMORIES 1] } {
foreach lef [glob -nocomplain $::env(RESULTS_DIR)/memories/*.lef] {
read_lef $lef
}
# AUTO_MEMORIES: abstract LEFs generated pre-synthesis
foreach lef [auto_memories_views .lef] {
read_lef $lef
}
read_verilog $::env(RESULTS_DIR)/$design_file
read_verilog $dir/$design_file
log_cmd link_design {*}[hier_options] $::env(DESIGN_NAME)
} elseif { $ext == ".odb" } {
log_cmd read_db {*}[hier_options] $::env(RESULTS_DIR)/$design_file
log_cmd read_db {*}[hier_options] $dir/$design_file
} else {
error "Unrecognized input file $design_file"
}

log_cmd read_sdc $::env(RESULTS_DIR)/[sdc_file_of $design_file]
log_cmd read_sdc $dir/[sdc_file_of $design_file]

if { [file exists $::env(PLATFORM_DIR)/derate.tcl] } {
log_cmd source $::env(PLATFORM_DIR)/derate.tcl
Expand Down
7 changes: 2 additions & 5 deletions flow/scripts/macro_place.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ source_step_tcl PRE MACRO_PLACE
# after macro placement, and the rows are then cut MACRO_ROWS_HALO_X/Y
# around every other macro: a halo that wide keeps them off its core,
# which fills its outline to the edge.
set regfile_list "$::env(RESULTS_DIR)/memories/regfiles.txt"
if { [env_var_equals AUTO_MEMORIES 1] && [file exists $regfile_list] } {
set f [open $regfile_list r]
set regfile_masters [split [string trim [read $f]] "\n"]
close $f
set regfile_masters [auto_memories_names regfiles.txt]
if { [llength $regfile_masters] > 0 } {
set dbu [[ord::get_db_tech] getDbUnitsPerMicron]
set halo {}
foreach v {MACRO_ROWS_HALO_X MACRO_ROWS_HALO_Y} {
Expand Down
24 changes: 9 additions & 15 deletions flow/scripts/read_liberty.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,15 @@ if { [env_var_exists_and_non_empty CORNERS] } {
}

# AUTO_MEMORIES: liberty views generated pre-synthesis by
# scripts/memories/gen_memories.py. The file names are only known at
# run time, so they are globbed here rather than threaded through
# LIB_FILES. The _pre_layout variants (ideal clock) are for pre-CTS
# consumers that select lib files themselves.
if { [env_var_equals AUTO_MEMORIES 1] } {
foreach libFile [glob -nocomplain $::env(RESULTS_DIR)/memories/*.lib] {
if { [string match *_pre_layout.lib $libFile] } {
continue
}
if { [env_var_exists_and_non_empty CORNERS] } {
foreach corner $::env(CORNERS) {
log_cmd read_liberty -corner $corner $libFile
}
} else {
log_cmd read_liberty $libFile
# scripts/memories/gen_memories.py, named by blackboxes.txt. The
# _pre_layout variants (ideal clock) are for pre-CTS consumers that
# select lib files themselves.
foreach libFile [auto_memories_views .lib] {
if { [env_var_exists_and_non_empty CORNERS] } {
foreach corner $::env(CORNERS) {
log_cmd read_liberty -corner $corner $libFile
}
} else {
log_cmd read_liberty $libFile
}
}
9 changes: 1 addition & 8 deletions flow/scripts/regfile_dissolve.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ proc regfile_internal_net { net placed } {
return 1
}

set regfile_list "$::env(RESULTS_DIR)/memories/regfiles.txt"
set regfile_modules {}
if { [env_var_equals AUTO_MEMORIES 1] && [file exists $regfile_list] } {
set f [open $regfile_list r]
set regfile_modules [split [string trim [read $f]] "\n"]
close $f
set regfile_modules [lsearch -all -inline -not -exact $regfile_modules ""]
}
set regfile_modules [auto_memories_names regfiles.txt]
if { [llength $regfile_modules] > 0 } {
set block [ord::get_db_block]
set db [ord::get_db]
Expand Down
Loading