Files
yosys/tests/abc_new/librelane/construct_abc_script.py
T
2026-09-21 16:33:47 +02:00

180 lines
6.7 KiB
Python

# https://github.com/librelane/librelane/blob/f24e0ea5db2260719e9a0c7d51d07db74a87fa23/librelane/scripts/pyosys/construct_abc_script.py
# Copyright 2020-2024 Efabless Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
class ABCScriptCreator:
def __init__(self, config):
self.config = config
D = config["CLOCK_PERIOD"] * 1000 # ns -> ps
self.D = D
self.rs_K = "resub -K "
self.rs = "resub"
self.rsz = "resub -z"
self.rf = "drf -l"
self.rfz = "drf -l -z"
self.rw = "drw -l"
self.rwz = "drw -l -z"
self.rw_K = "drw -l -K"
if config["SYNTH_ABC_LEGACY_REFACTOR"]:
self.rf = "refactor"
self.rfz = "refactor -z"
if config["SYNTH_ABC_LEGACY_REWRITE"]:
self.rw = "rewrite"
self.rwz = "rewrite -z"
self.rw_K = "rewrite -K"
self.b = "balance"
self.resyn2 = f"{self.b}; {self.rw}; {self.rf}; {self.b}; {self.rw}; {self.rwz}; {self.b}; {self.rfz}; {self.rwz}; {self.b}"
self.share = f"strash; multi -m; {self.resyn2}"
self.resyn2a = f"{self.b};{self.rw};{self.b};{self.rw};{self.rwz};{self.b};{self.rwz};{self.b}"
self.resyn3 = f"{self.b}; resub; resub -K 6; {self.b};resub -z;resub -z -K 6; {self.b};resub -z -K 5; {self.b}"
self.resyn2rs = f"{self.b};{self.rs_K} 6;{self.rw};{self.rs_K} 6 -N 2;{self.rf};{self.rs_K} 8;{self.rw};{self.rs_K} 10;{self.rwz};{self.rs_K} 10 -N 2;{self.b} {self.rs_K} 12;{self.rfz};{self.rs_K} 12 -N 2;{self.rwz};{self.b}"
self.choice = f"fraig_store; {self.resyn2}; fraig_store; {self.resyn2}; fraig_store; fraig_restore"
self.choice2 = f"fraig_store; {self.b}; fraig_store; {self.resyn2}; fraig_store; {self.resyn2}; fraig_store; {self.resyn2}; fraig_store; fraig_restore"
self.area_mfs3 = ""
self.delay_mfs3 = ""
if config["SYNTH_ABC_USE_MFS3"]:
self.area_mfs3 = "mfs3 -aemvz -I 4 -O 2"
self.delay_mfs3 = "mfs3 -emvz -I 4 -O 2"
self.map_old_area = "map -p -a -B 0.2 -A 0.9 -M 0"
self.map_old_dly = "map -p -B 0.2 -A 0.9 -M 0"
self.retime_area = "retime -M 5"
self.retime_dly = "retime -M 6"
self.map_new_area = "amap -m -Q 0.1 -F 20 -A 20 -C 5000"
if config["SYNTH_ABC_AREA_USE_NF"]:
self.map_new_area = "&get -n; &nf -R 1000; &put"
self.max_fanout = config["MAX_FANOUT_CONSTRAINT"]
self.max_transition = (
config.get("MAX_TRANSITION_CONSTRAINT") or 0
) * 1000 # ns -> ps
self.fine_tune = ""
if config["SYNTH_ABC_BUFFERING"]:
max_tr_arg = ""
if self.max_transition != 0:
max_tr_arg = f" -S {self.max_transition}"
self.fine_tune = f"buffer -N {self.max_fanout}{max_tr_arg};upsize;dnsize"
elif config["SYNTH_SIZING"]:
self.fine_tune = "upsize;dnsize"
def generate_abc_script(self, step_dir, strategy):
strategy_clean = re.sub(r"\s+", "_", strategy)
abc_script_path = os.path.join(step_dir, f"{strategy_clean}.abc")
f = open(abc_script_path, "w")
if strategy == "AREA 3":
# ORFS Area Script
print("strash", file=f)
print("dch", file=f)
print("map -B 0.9", file=f)
print("topo", file=f)
print("stime -c", file=f)
print(f"buffer -c -N {self.max_fanout}", file=f)
print("upsize -c", file=f)
print("dnsize -c", file=f)
elif strategy == "DELAY 4":
# ORFS Delay Script
def repeated_sequence(f):
print("&st", file=f)
print("&syn2", file=f)
print("&if -g -K 6", file=f)
print("&synch2", file=f)
print("&nf", file=f)
print("&get -n", file=f)
print("&st", file=f)
print("&dch", file=f)
print("&nf", file=f)
for _ in range(5):
repeated_sequence(f)
print("&put", file=f)
print(f"buffer -c -N {self.max_fanout}", file=f)
print("topo", file=f)
print("stime -c", file=f)
print("upsize -c", file=f)
print("dnsize -c", file=f)
else:
print("fx", file=f)
print("mfs", file=f)
print("strash", file=f)
print(self.rf, file=f)
# Resynth/Retime
if strategy == "AREA 2":
print(self.choice2, file=f)
else:
print(self.resyn2, file=f)
if strategy.startswith("AREA ") or strategy == "DELAY 3":
print(self.retime_area, file=f)
else:
print(self.retime_dly, file=f)
print("scleanup", file=f)
if strategy in ["AREA 4", "DELAY 2"]:
print(self.choice, file=f)
elif strategy != "DELAY 0":
print(self.choice2, file=f)
if strategy.startswith("AREA ") or strategy == "DELAY 3":
print(self.map_new_area, file=f)
else:
print(self.map_old_dly, file=f)
# Area Recovery
if strategy in ["AREA 1", "AREA 2"]:
print(self.choice2, file=f)
print(self.map_new_area, file=f)
elif strategy in ["DELAY 1"]:
print(self.choice2, file=f)
print("map", file=f)
elif strategy in ["DELAY 2"]:
print(self.choice, file=f)
print("map", file=f)
elif strategy in ["DELAY 3"]:
print(self.choice2, file=f)
print(self.map_old_dly, file=f)
if strategy.startswith("AREA "):
print(self.area_mfs3, file=f)
else:
print(self.delay_mfs3, file=f)
print("retime", file=f)
# & space
print("&get -n", file=f)
print("&st", file=f)
print("&dch", file=f)
print("&nf", file=f)
print("&put", file=f)
print(self.fine_tune, file=f)
# Common Conclusion
print("stime -p", file=f)
print("print_stats -m", file=f)
f.close()
return abc_script_path