Skip to content

Commit 9323372

Browse files
authored
Merge pull request #1727 from Pinata-Consulting/memory-report
Memory report
2 parents bc89a50 + 70df171 commit 9323372

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)