Skip to content

Commit 70df171

Browse files
committed
makefile: check that inferred memories are smaller than SYNTH_MEMORY_MAX_BITS
Dusted off some code that Tutu wrote to create a report of memories in the design. Before even trying synthesis optimization, it is useful to know what memories are in the design, error out by default when there are too big memories in the design. Adjust this threshold by changing SYNTH_MEMORY_MAX_BITS, default 4096 bits. If the memories are small(Tutu mentioned that 1024 bits or smaller, same as Chipyard uses), then they are best instantiated as flip flops. Running `make memory` prints out the report after synthesis. Signed-off-by: Øyvind Harboe <[email protected]> Co-author: Tutu Ajayi <[email protected]>
1 parent a006172 commit 70df171

File tree

6 files changed

+72
-9
lines changed

6 files changed

+72
-9
lines changed

flow/Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,12 +458,18 @@ synth-report: synth
458458
do-synth-report:
459459
($(TIME_CMD) $(OPENROAD_CMD) $(SCRIPTS_DIR)/synth_metrics.tcl) 2>&1 | tee -a $(LOG_DIR)/1_1_yosys.log
460460

461+
.PHONY: memory
462+
memory: $(RESULTS_DIR)/mem.json
463+
python3 $(SCRIPTS_DIR)/mem_dump.py $(RESULTS_DIR)/mem.json
464+
461465
# ==============================================================================
462466

463467

464468
# Run Synthesis using yosys
465469
#-------------------------------------------------------------------------------
466-
SYNTH_SCRIPT ?= $(SCRIPTS_DIR)/synth.tcl
470+
471+
export SYNTH_SCRIPT ?= $(SCRIPTS_DIR)/synth.tcl
472+
export SYNTH_MEMORY_MAX_BITS ?= 4096
467473

468474
$(SYNTH_STOP_MODULE_SCRIPT):
469475
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR)
@@ -484,7 +490,7 @@ yosys-dependencies: $(DONT_USE_LIBS) $(WRAPPED_LIBS) $(DONT_USE_SC_LIB) $(DFF_LI
484490

485491
.PHONY: do-yosys
486492
do-yosys: yosys-dependencies
487-
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR)
493+
mkdir -p $(RESULTS_DIR) $(LOG_DIR) $(REPORTS_DIR) $(OBJECTS_DIR)
488494
($(TIME_CMD) $(YOSYS_CMD) $(YOSYS_FLAGS) -c $(SYNTH_SCRIPT)) 2>&1 | tee $(LOG_DIR)/1_1_yosys.log
489495

490496
$(RESULTS_DIR)/1_1_yosys.v: $(SDC_FILE_CLOCK_PERIOD)
@@ -504,7 +510,7 @@ $(RESULTS_DIR)/1_synth.v: $(RESULTS_DIR)/1_1_yosys.v
504510

505511
.PHONY: clean_synth
506512
clean_synth:
507-
rm -f $(RESULTS_DIR)/1_*.v $(RESULTS_DIR)/1_synth.sdc
513+
rm -f $(RESULTS_DIR)/1_*.v $(RESULTS_DIR)/1_synth.sdc $(RESULTS_DIR)/mem.json
508514
rm -f $(REPORTS_DIR)/synth_*
509515
rm -f $(LOG_DIR)/1_*
510516
rm -f $(SYNTH_STOP_MODULE_SCRIPT)

flow/designs/sky130hd/microwatt/config.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ export SKIP_GATE_CLONING = 1
4141
export export SETUP_SLACK_MARGIN = 0.2
4242

4343
export GLOBAL_ROUTE_ARGS=-congestion_iterations 100 -verbose
44+
45+
# This is high, some SRAMs should probably be converted
46+
# to real SRAMs and not instantiated as flops
47+
export SYNTH_MEMORY_MAX_BITS ?= 42000

flow/scripts/mem_dump.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import argparse
2+
import json
3+
import os
4+
import sys
5+
6+
7+
def format_ram_table_from_json(data, max_bits=None):
8+
formatting = "{:<15} | {:<15} | {:<15} | {:<50}\n"
9+
table = formatting.format("Rows",
10+
"Width",
11+
"Total bits",
12+
"Name")
13+
table += "-"*len(table) + "\n"
14+
max_ok = True
15+
for module_name, module_info in data["modules"].items():
16+
cells = module_info["cells"]
17+
for memory, cell in cells.items():
18+
if not cell["type"].startswith("$mem"):
19+
continue
20+
parameters = cell["parameters"]
21+
size = int(parameters["SIZE"], 2)
22+
width = int(parameters["WIDTH"], 2)
23+
bits = size * width
24+
table += formatting.format(size,
25+
width,
26+
bits,
27+
module_name + "." + memory)
28+
if max_bits is not None and bits > max_bits:
29+
max_ok = False
30+
return table, max_ok
31+
32+
33+
if __name__ == "__main__":
34+
parser = argparse.ArgumentParser()
35+
parser.add_argument("file")
36+
parser.add_argument("-m", "--max-bits", type=int, default=None)
37+
args = parser.parse_args()
38+
39+
with open(args.file, 'r') as file:
40+
json_data = json.load(file)
41+
formatted_table, max_ok = format_ram_table_from_json(json_data, args.max_bits)
42+
print()
43+
print(formatted_table)
44+
if not max_ok:
45+
sys.exit("ERROR: Synthesized memory size exceeds maximum allowed bits " + str(args.max_bits))

flow/scripts/synth.tcl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ if { [info exist ::env(SYNTH_GUT)] && $::env(SYNTH_GUT) == 1 } {
1212
delete $::env(DESIGN_NAME)/c:*
1313
}
1414

15-
# Generic synthesis
16-
synth -top $::env(DESIGN_NAME) {*}$::env(SYNTH_ARGS)
17-
# Get rid of indigestibles
18-
chformal -remove
15+
synthesize_check $::env(SYNTH_ARGS)
1916

2017
if { [info exists ::env(USE_LSORACLE)] } {
2118
set lso_script [open $::env(OBJECTS_DIR)/lso.script w]

flow/scripts/synth_hier_report.tcl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
source $::env(SCRIPTS_DIR)/synth_preamble.tcl
22

3-
# Hierarchical synthesis
4-
synth -top $::env(DESIGN_NAME)
3+
synthesize_check {}
4+
55
if { [info exist ::env(ADDER_MAP_FILE)] && [file isfile $::env(ADDER_MAP_FILE)] } {
66
techmap -map $::env(ADDER_MAP_FILE)
77
}

flow/scripts/synth_preamble.tcl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,14 @@ set constr [open $::env(OBJECTS_DIR)/abc.constr w]
105105
puts $constr "set_driving_cell $::env(ABC_DRIVER_CELL)"
106106
puts $constr "set_load $::env(ABC_LOAD_IN_FF)"
107107
close $constr
108+
109+
proc synthesize_check {synth_args} {
110+
# Generic synthesis
111+
synth -top $::env(DESIGN_NAME) -run :fine {*}$synth_args
112+
json -o $::env(RESULTS_DIR)/mem.json
113+
# Run report and check here so as to fail early if this synthesis run is doomed
114+
exec -- python3 $::env(SCRIPTS_DIR)/mem_dump.py --max-bits $::env(SYNTH_MEMORY_MAX_BITS) $::env(RESULTS_DIR)/mem.json
115+
synth -top $::env(DESIGN_NAME) -run fine: {*}$synth_args
116+
# Get rid of indigestibles
117+
chformal -remove
118+
}

0 commit comments

Comments
 (0)