diff --git a/.gitignore b/.gitignore index 07f02b0..825d99f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ __pycache__/ results/ demo/alu-chisel/generated/ +gurobi.log diff --git a/demo/config.sample.ini b/demo/config.sample.ini index b96724a..f087441 100644 --- a/demo/config.sample.ini +++ b/demo/config.sample.ini @@ -34,7 +34,7 @@ ; # External toolkit settings ; dreamplace_bin_path str Path/to/DREAMPlace/.../Placer.py -; yosys_bin_path str Path/to/Yosys/binary +; yosys_bin_path str Path/to/Yosys/build_dir/, which contains yosys and yosys-abc binaries ; # Flow settings ; flow dict {'synth':'genus'/'yosys', 'placement':'innovus/dreamplace', 'routing':'innovus'} @@ -43,8 +43,8 @@ [flow1] # Design settings -design_name = AluTop -is_Chisel_design = True +design_name = gcd +is_Chisel_design = False rtl_input = /home/wxm/cocoon/demo/gcd/gcd.v Chisel_input = /home/wxm/cocoon/demo/alu-chisel/ result_dir = /home/wxm/cocoon/results/ @@ -58,10 +58,10 @@ liberty_input = /home/wxm/cocoon/demo/lib/gscl45nm.lib # External toolkit settings dreamplace_bin_path = /home/wxm/DREAMPlace/install/dreamplace/Placer.py -yosys_bin_path = +yosys_bin_path = /home/wxm/yosys/build # Flow settings -flow = {'synth':'genus', 'placement':'dreamplace', 'routing':'innovus'} +flow = {'synth':'yosys', 'placement':'dreamplace', 'routing':'innovus'} n_iter_IFT = 0 diff --git a/engine.py b/engine.py index 6b367ef..682feff 100644 --- a/engine.py +++ b/engine.py @@ -33,9 +33,18 @@ def run(design, flow): if x[0] == "GenusSynth": script_path = "../scripts/" tmp_op_syn = syn.GenusSynth(design) - tmp_op_syn.config(design, design_name + "_" + x[1]) + tmp_op_syn.config(design_name + "_" + x[1]) make_file.write("all:\n") make_file.write("\tgenus -legacy_ui -batch -files " + script_path + design_name + "_" + x[1] + ".tcl\n") + + if x[0] == "yosys": + script_path = "../scripts/" + tmp_op_syn = syn.YosysSynth(design) + tmp_op_syn.config(design_name + "_" + x[1], flow) + make_file.write("all:\n") + yosys_path = os.path.join(flow.yosys_bin_path, "yosys") + save_log = f" | tee -a {os.path.join(rpt_path, 'yosys.log')}\n" + make_file.write(f"\t{yosys_path} " + script_path + design_name + "_" + x[1] + ".ys" + save_log) if x[0] == "InnovusFloorplan": tmp_op_fp = fp.InnovusFloorplan(design) @@ -80,7 +89,8 @@ def run(design, flow): make_file.write("\tinnovus -batch -files " + script_path + "flow.tcl") elif flow.flow['placement'] == "dreamplace": make_file.write("\tinnovus -batch -files " + script_path + "%s_to_floorplan.tcl\n" % design_name) - make_file.write("\tpython %s %s\n" % (flow.dreamplace_bin_path, script_path + "%s_to_place.json" % design_name)) + save_log = f" | tee -a {os.path.join(rpt_path, 'dreamplace.log')}\n" + make_file.write("\tpython %s %s" % (flow.dreamplace_bin_path, script_path + "%s_to_place.json" % design_name) + save_log) make_file.write("\tinnovus -batch -files " + script_path + "%s_to_route.tcl\n" % design_name) make_file.close() diff --git a/flow.py b/flow.py index 4b019d3..d2da29b 100644 --- a/flow.py +++ b/flow.py @@ -19,6 +19,8 @@ class MyFlow(object): if self.flow['synth'] == 'genus': op_synth = "GenusSynth" + elif self.flow['synth'] == 'yosys': + op_synth = "yosys" self.ops.append((op_synth, "to_synth")) op_floorplan = "InnovusFloorplan" @@ -34,8 +36,8 @@ class MyFlow(object): self.ops.append((op_place, "to_place")) self.params_place["def_out"] = False - op_cts = "InnovusCTS" - self.ops.append((op_cts, "to_cts")) + # op_cts = "InnovusCTS" + # self.ops.append((op_cts, "to_cts")) op_route = "InnovusRoute" self.ops.append((op_route, "to_route")) diff --git a/ops/cds/syn.py b/ops/cds/syn.py index 92b3b37..b92f636 100644 --- a/ops/cds/syn.py +++ b/ops/cds/syn.py @@ -2,7 +2,7 @@ import os import util -class GenusSynth(): +class GenusSynth: def __init__(self, design, critical_path=None): self.params = dict() self.params["effort"] = "medium" @@ -69,11 +69,11 @@ class GenusSynth(): return cmd - def config(self, design, tcl_file): - rtl_file = design.rtl_input - lib_file = design.liberty_input + def config(self, tcl_name): + rtl_file = self.design.rtl_input + lib_file = self.design.liberty_input tcl_path = util.getScriptPath(self.design) - tcl = open(os.path.join(tcl_path, tcl_file + ".tcl"), 'w', encoding='utf-8') + tcl = open(os.path.join(tcl_path, tcl_name + ".tcl"), 'w', encoding='utf-8') tcl.write('set DESIGN %s\n'%(self.design.top_name)) tcl.write('set clkpin %s\n'%(self.design.clk_name)) @@ -110,3 +110,50 @@ class GenusSynth(): tcl.write('write_sdc > %s\n'%(self.getObjSDC())) tcl.close() + + +class YosysSynth: + + def __init__(self, design): + self.design = design + + def getObjHDL(self): + obj_path = util.getObjPath(self.design) + obj_hdl = os.path.join(obj_path, self.design.top_name + ".vh") + return obj_hdl + + def getObjSDC(self): + obj_path = util.getObjPath(self.design) + obj_sdc = os.path.join(obj_path, self.design.top_name + ".sdc") + return obj_sdc + + def writeSDC(self): + sdc = open(self.getObjSDC(), 'w', encoding='utf-8') + sdc.write("set sdc_version 2.0\n") + sdc.write(f"current_design {self.design.top_name}\n") + sdc.write(f'create_clock -name "{self.design.clk_name}" -period {0.001 * self.design.delay} ' + '-waveform {0.0 0.05}\n') + sdc.close() + + def config(self, tcl_name, flow): + rtl_file = self.design.rtl_input + lib_file = self.design.liberty_input + tcl_path = util.getScriptPath(self.design) + tcl = open(os.path.join(tcl_path, tcl_name + ".ys"), 'w', encoding='utf-8') + + tcl.write("# Synthesis script for yosys created by qflow\n") + tcl.write(f"read_liberty -lib -ignore_miss_dir -setattr blackbox {lib_file}\n") + tcl.write(f"read_verilog {rtl_file}\n\n") + tcl.write("# High-level synthesis\n") + tcl.write(f"synth -top {self.design.top_name}\n") + tcl.write(f"dfflibmap -liberty {lib_file}\nopt\n\n") + + abc_path = os.path.join(flow.yosys_bin_path, "yosys-abc") + tcl.write(f"abc -exe {abc_path} -liberty {lib_file} " + "-script +strash;scorr;ifraig;retime,{D};strash;dch,-f;map,-M,1,{D}\n") + tcl.write("flatten\nsetundef -zero\nclean -purge\niopadmap -outpad BUFX2 A:Y -bits\n") + tcl.write("opt\nclean\nrename -enumerate\n") + tcl.write(f"write_verilog {self.getObjHDL()}\n") + tcl.write("stat\n") + + tcl.close() + + self.writeSDC()