Skip to content

Commit d07d6d9

Browse files
committed
Use estimates for ungrouping decisions
Signed-off-by: Martin Povišer <[email protected]>
1 parent 1cbce35 commit d07d6d9

File tree

3 files changed

+59
-46
lines changed

3 files changed

+59
-46
lines changed

flow/Makefile

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,6 @@ include $(PLATFORM_DIR)/config.mk
178178
# is no way to escape space in defaults.py and get "foreach" to work.
179179
$(foreach line,$(shell $(SCRIPTS_DIR)/defaults.py),$(eval export $(subst __SPACE__, ,$(line))))
180180

181-
# Enables hierarchical yosys
182-
export SYNTH_STATS = $(RESULTS_DIR)/synth_stats.txt
183-
export SYNTH_STATS_SCRIPT = $(SCRIPTS_DIR)/synth_stats.tcl
184181
# If the design, nor $(PLATFORM_DIR)/config.mk provided a default, provide one here
185182
export MAX_UNGROUP_SIZE ?= 0
186183

@@ -454,13 +451,6 @@ memory:
454451

455452
export SYNTH_SCRIPT ?= $(SCRIPTS_DIR)/synth.tcl
456453
export SYNTH_MEMORY_MAX_BITS ?= 4096
457-
458-
.PHONY: do-yosys-stats
459-
do-yosys-stats:
460-
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR)
461-
(export VERILOG_FILES=$(RESULTS_DIR)/1_synth.rtlil; \
462-
$(TIME_CMD) $(YOSYS_EXE) $(YOSYS_FLAGS) -c $(SYNTH_STATS_SCRIPT)) 2>&1 | tee $(abspath $(LOG_DIR)/1_1_yosys_stats.log)
463-
464454
export SDC_FILE_CLOCK_PERIOD = $(RESULTS_DIR)/clock_period.txt
465455

466456
$(SDC_FILE_CLOCK_PERIOD): $(SDC_FILE)
@@ -487,7 +477,7 @@ $(RESULTS_DIR)/1_synth.rtlil: $(YOSYS_DEPENDENCIES)
487477
$(UNSET_AND_MAKE) do-yosys-canonicalize
488478

489479
$(RESULTS_DIR)/1_1_yosys.v: $(RESULTS_DIR)/1_synth.rtlil
490-
$(UNSET_AND_MAKE) do-yosys-stats do-yosys
480+
$(UNSET_AND_MAKE) do-yosys
491481

492482
.PHONY: do-synth
493483
do-synth:

flow/scripts/synth.tcl

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,41 @@ source $::env(SCRIPTS_DIR)/synth_preamble.tcl
22

33
hierarchy -check -top $::env(DESIGN_NAME)
44

5-
set ungroup_threshold 0
6-
if { $::env(MAX_UNGROUP_SIZE) > 0 } {
7-
set ungroup_threshold $::env(MAX_UNGROUP_SIZE)
8-
puts "Ungroup modules of size greater than $ungroup_threshold"
9-
}
10-
11-
set fp [open $::env(SYNTH_STATS) r]
12-
while {[gets $fp line] != -1} {
13-
set fields [split $line " "]
14-
set area [lindex $fields 0]
15-
set module_name [lindex $fields 1]
16-
17-
if {[expr $area > $ungroup_threshold]} {
18-
puts "Keeping module $module_name (area: $area)"
19-
select -module $module_name
20-
setattr -mod -set keep_hierarchy 1
21-
select -clear
22-
} else {
23-
puts "Flattening module $module_name (area: $area)"
24-
}
25-
}
26-
close $fp
27-
285
if { [env_var_equals SYNTH_GUT 1] } {
296
# /deletes all cells at the top level, which will quickly optimize away
307
# everything else, including macros.
318
delete $::env(DESIGN_NAME)/c:*
329
}
3310

34-
synthesize_check mem $::env(SYNTH_FULL_ARGS)
11+
if {![env_var_equals SYNTH_HIERARCHICAL 1]} {
12+
# Perform standard coarse-level synthesis script, flatten right away
13+
# (-flatten part of $synth_args per default)
14+
synth -run :fine {*}$::env(SYNTH_FULL_ARGS)
15+
} else {
16+
# Perform standard coarse-level synthesis script,
17+
# defer flattening until we have decided what hierarchy to keep
18+
synth -run :fine
19+
20+
if {[env_var_exists_and_non_empty MAX_UNGROUP_SIZE]} {
21+
set ungroup_threshold $::env(MAX_UNGROUP_SIZE)
22+
puts "Ungroup modules below estimated size of $ungroup_threshold instances"
23+
24+
convert_liberty_areas
25+
keep_hierarchy -min_cost $ungroup_threshold
26+
} else {
27+
keep_hierarchy
28+
}
29+
30+
# Re-run coarse-level script, this time do pass -flatten
31+
synth -run coarse:fine {*}$::env(SYNTH_FULL_ARGS)
32+
}
33+
34+
json -o $::env(RESULTS_DIR)/mem.json
35+
# Run report and check here so as to fail early if this synthesis run is doomed
36+
exec -- python3 $::env(SCRIPTS_DIR)/mem_dump.py --max-bits $::env(SYNTH_MEMORY_MAX_BITS) $::env(RESULTS_DIR)/mem.json
37+
synth -top $::env(DESIGN_NAME) -run fine: {*}$::env(SYNTH_FULL_ARGS)
38+
# Get rid of indigestibles
39+
chformal -remove
3540

3641
# rename registers to have the verilog register name in its name
3742
# of the form \regName$_DFF_P_. We should fix yosys to make it the reg name.

flow/scripts/synth_preamble.tcl

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ foreach file $::env(VERILOG_FILES) {
3838

3939
# Read standard cells and macros as blackbox inputs
4040
# These libs have their dont_use properties set accordingly
41-
read_liberty -overwrite -lib {*}$::env(DONT_USE_LIBS)
42-
read_liberty -overwrite -unit_delay -wb -ignore_miss_func -ignore_buses {*}$::env(DONT_USE_LIBS)
41+
read_liberty -overwrite -setattr liberty_cell -lib {*}$::env(DONT_USE_LIBS)
42+
read_liberty -overwrite -setattr liberty_cell \
43+
-unit_delay -wb -ignore_miss_func -ignore_buses {*}$::env(DONT_USE_LIBS)
4344

4445
# Apply toplevel parameters (if exist)
4546
if {[env_var_exists_and_non_empty VERILOG_TOP_PARAMS]} {
@@ -108,13 +109,30 @@ puts $constr "set_driving_cell $::env(ABC_DRIVER_CELL)"
108109
puts $constr "set_load $::env(ABC_LOAD_IN_FF)"
109110
close $constr
110111

111-
proc synthesize_check {report synth_args} {
112-
# Generic synthesis
113-
log_cmd synth -top $::env(DESIGN_NAME) -run :fine {*}$synth_args
114-
json -o $::env(RESULTS_DIR)/$report.json
115-
# Run report and check here so as to fail early if this synthesis run is doomed
116-
exec -- python3 $::env(SCRIPTS_DIR)/mem_dump.py --max-bits $::env(SYNTH_MEMORY_MAX_BITS) $::env(RESULTS_DIR)/$report.json
117-
synth -top $::env(DESIGN_NAME) -run fine: {*}$synth_args
118-
# Get rid of indigestibles
119-
chformal -remove
112+
proc convert_liberty_areas {} {
113+
cellmatch -derive_luts =A:liberty_cell
114+
# find a reference nand2 gate
115+
set found_cell ""
116+
set found_cell_area ""
117+
foreach cell [tee -q -s result.string select -list-mod =*/a:lut=4'b0111 %m] {
118+
if {! [rtlil::has_attr -mod $cell area]} {
119+
puts "Cell $cell missing area information"
120+
continue
121+
}
122+
set area [rtlil::get_attr -string -mod $cell area]
123+
if {$found_cell == "" || [expr $area < $found_cell_area]} {
124+
set found_cell $cell
125+
set found_cell_area $area
126+
}
127+
}
128+
if {$found_cell == ""} {
129+
error "reference nand2 cell not found"
130+
}
131+
132+
# convert the area on all Liberty cells to a gate number equivalent
133+
foreach box [tee -q -s result.string select -list-mod =A:area =A:liberty_cell %i] {
134+
set area [rtlil::get_attr -mod -string $box area]
135+
set gate_eq [expr int($area / $found_cell_area)]
136+
rtlil::set_attr -mod -uint $box gate_cost_equivalent $gate_eq
137+
}
120138
}

0 commit comments

Comments
 (0)