siliconcompiler 0.29.0__py3-none-any.whl → 0.29.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/__init__.py +26 -0
- siliconcompiler/apps/utils/replay.py +96 -38
- siliconcompiler/checklists/__init__.py +12 -0
- siliconcompiler/core.py +75 -10
- siliconcompiler/flows/__init__.py +34 -0
- siliconcompiler/flows/showflow.py +1 -1
- siliconcompiler/libs/__init__.py +5 -0
- siliconcompiler/optimizer/__init__.py +199 -0
- siliconcompiler/optimizer/vizier.py +259 -0
- siliconcompiler/pdks/__init__.py +5 -0
- siliconcompiler/scheduler/__init__.py +67 -49
- siliconcompiler/scheduler/send_messages.py +1 -1
- siliconcompiler/schema/schema_cfg.py +2 -2
- siliconcompiler/schema/schema_obj.py +13 -10
- siliconcompiler/schema/utils.py +2 -0
- siliconcompiler/sphinx_ext/__init__.py +85 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +17 -33
- siliconcompiler/sphinx_ext/schemagen.py +3 -2
- siliconcompiler/targets/__init__.py +26 -0
- siliconcompiler/templates/replay/replay.py.j2 +62 -0
- siliconcompiler/templates/replay/requirements.txt +2 -1
- siliconcompiler/templates/replay/setup.sh +119 -6
- siliconcompiler/tools/__init__.py +60 -0
- siliconcompiler/tools/_common/asic.py +7 -6
- siliconcompiler/tools/ghdl/ghdl.py +1 -2
- siliconcompiler/tools/klayout/convert_drc_db.py +1 -1
- siliconcompiler/tools/klayout/drc.py +1 -1
- siliconcompiler/tools/klayout/export.py +8 -1
- siliconcompiler/tools/klayout/klayout.py +2 -2
- siliconcompiler/tools/klayout/klayout_convert_drc_db.py +2 -2
- siliconcompiler/tools/klayout/klayout_export.py +7 -5
- siliconcompiler/tools/klayout/klayout_operations.py +4 -3
- siliconcompiler/tools/klayout/klayout_show.py +3 -2
- siliconcompiler/tools/klayout/klayout_utils.py +1 -1
- siliconcompiler/tools/klayout/operations.py +8 -0
- siliconcompiler/tools/klayout/screenshot.py +6 -1
- siliconcompiler/tools/klayout/show.py +8 -1
- siliconcompiler/tools/magic/magic.py +1 -1
- siliconcompiler/tools/openroad/__init__.py +1 -1
- siliconcompiler/tools/openroad/_apr.py +2 -1
- siliconcompiler/tools/openroad/init_floorplan.py +1 -1
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +4 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +2 -2
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +52 -0
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +1 -1
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +5 -0
- siliconcompiler/tools/opensta/__init__.py +1 -1
- siliconcompiler/tools/opensta/check_library.py +27 -0
- siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +255 -0
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +1 -1
- siliconcompiler/tools/sv2v/sv2v.py +1 -2
- siliconcompiler/tools/verilator/verilator.py +6 -7
- siliconcompiler/tools/vivado/vivado.py +1 -1
- siliconcompiler/tools/yosys/__init__.py +149 -0
- siliconcompiler/tools/yosys/lec.py +22 -9
- siliconcompiler/tools/yosys/sc_lec.tcl +94 -49
- siliconcompiler/tools/yosys/sc_syn.tcl +1 -0
- siliconcompiler/tools/yosys/screenshot.py +2 -2
- siliconcompiler/tools/yosys/syn_asic.py +98 -74
- siliconcompiler/tools/yosys/syn_asic.tcl +31 -6
- siliconcompiler/tools/yosys/syn_fpga.py +2 -3
- siliconcompiler/tools/yosys/syn_fpga.tcl +0 -1
- siliconcompiler/toolscripts/_tools.json +3 -3
- siliconcompiler/utils/__init__.py +7 -3
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/METADATA +13 -10
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/RECORD +72 -82
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/entry_points.txt +13 -0
- siliconcompiler/libs/asap7sc7p5t.py +0 -8
- siliconcompiler/libs/gf180mcu.py +0 -8
- siliconcompiler/libs/interposer.py +0 -8
- siliconcompiler/libs/nangate45.py +0 -8
- siliconcompiler/libs/sg13g2_stdcell.py +0 -8
- siliconcompiler/libs/sky130hd.py +0 -8
- siliconcompiler/libs/sky130io.py +0 -8
- siliconcompiler/pdks/asap7.py +0 -8
- siliconcompiler/pdks/freepdk45.py +0 -8
- siliconcompiler/pdks/gf180.py +0 -8
- siliconcompiler/pdks/ihp130.py +0 -8
- siliconcompiler/pdks/interposer.py +0 -8
- siliconcompiler/pdks/skywater130.py +0 -8
- siliconcompiler/templates/replay/run.py.j2 +0 -22
- siliconcompiler/tools/yosys/yosys.py +0 -148
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Yosys is a framework for RTL synthesis that takes synthesizable
|
|
3
|
+
Verilog-2005 design and converts it to BLIF, EDIF, BTOR, SMT,
|
|
4
|
+
Verilog netlist etc. The tool supports logical synthesis and
|
|
5
|
+
tech mapping to ASIC standard cell libraries, FPGA architectures.
|
|
6
|
+
In addition it has built in formal methods for property and
|
|
7
|
+
equivalence checking.
|
|
8
|
+
|
|
9
|
+
Documentation: https://yosyshq.readthedocs.io/projects/yosys/en/latest/
|
|
10
|
+
|
|
11
|
+
Sources: https://github.com/YosysHQ/yosys
|
|
12
|
+
|
|
13
|
+
Installation: https://github.com/YosysHQ/yosys
|
|
14
|
+
'''
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
import json
|
|
18
|
+
from siliconcompiler import sc_open
|
|
19
|
+
from siliconcompiler.tools._common import get_tool_task, record_metric
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
######################################################################
|
|
23
|
+
# Make Docs
|
|
24
|
+
######################################################################
|
|
25
|
+
def make_docs(chip):
|
|
26
|
+
from siliconcompiler.targets import asap7_demo
|
|
27
|
+
chip.use(asap7_demo)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
################################
|
|
31
|
+
# Setup Tool (pre executable)
|
|
32
|
+
################################
|
|
33
|
+
def setup(chip):
|
|
34
|
+
''' Tool specific function to run before step execution
|
|
35
|
+
'''
|
|
36
|
+
|
|
37
|
+
# If the 'lock' bit is set, don't reconfigure.
|
|
38
|
+
tool = 'yosys'
|
|
39
|
+
refdir = 'tools/' + tool
|
|
40
|
+
step = chip.get('arg', 'step')
|
|
41
|
+
index = chip.get('arg', 'index')
|
|
42
|
+
_, task = get_tool_task(chip, step, index)
|
|
43
|
+
|
|
44
|
+
# Standard Setup
|
|
45
|
+
chip.set('tool', tool, 'exe', 'yosys')
|
|
46
|
+
chip.set('tool', tool, 'vswitch', '--version')
|
|
47
|
+
chip.set('tool', tool, 'version', '>=0.48', clobber=False)
|
|
48
|
+
chip.set('tool', tool, 'format', 'tcl', clobber=False)
|
|
49
|
+
|
|
50
|
+
# Task Setup
|
|
51
|
+
# common to all
|
|
52
|
+
option = []
|
|
53
|
+
if chip.get('option', 'breakpoint', step=step, index=index):
|
|
54
|
+
option.append('-C')
|
|
55
|
+
option.append('-c')
|
|
56
|
+
chip.set('tool', tool, 'task', task, 'option', option, step=step, index=index, clobber=False)
|
|
57
|
+
chip.set('tool', tool, 'task', task, 'refdir', refdir, step=step, index=index,
|
|
58
|
+
package='siliconcompiler', clobber=False)
|
|
59
|
+
chip.set('tool', tool, 'task', task, 'regex', 'warnings', "Warning:",
|
|
60
|
+
step=step, index=index, clobber=False)
|
|
61
|
+
chip.set('tool', tool, 'task', task, 'regex', 'errors', "^ERROR",
|
|
62
|
+
step=step, index=index, clobber=False)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
################################
|
|
66
|
+
# Version Check
|
|
67
|
+
################################
|
|
68
|
+
def parse_version(stdout):
|
|
69
|
+
# Yosys 0.9+3672 (git sha1 014c7e26, gcc 7.5.0-3ubuntu1~18.04 -fPIC -Os)
|
|
70
|
+
return stdout.split()[1]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def normalize_version(version):
|
|
74
|
+
# Replace '+', which represents a "local version label", with '-', which is
|
|
75
|
+
# an "implicit post release number".
|
|
76
|
+
return version.replace('+', '-')
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def syn_setup(chip):
|
|
80
|
+
''' Helper method for configs specific to synthesis tasks.
|
|
81
|
+
'''
|
|
82
|
+
|
|
83
|
+
# Generic tool setup.
|
|
84
|
+
setup(chip)
|
|
85
|
+
|
|
86
|
+
tool = 'yosys'
|
|
87
|
+
step = chip.get('arg', 'step')
|
|
88
|
+
index = chip.get('arg', 'index')
|
|
89
|
+
_, task = get_tool_task(chip, step, index)
|
|
90
|
+
design = chip.top()
|
|
91
|
+
|
|
92
|
+
# Set yosys script path.
|
|
93
|
+
chip.set('tool', tool, 'task', task, 'script', 'sc_syn.tcl',
|
|
94
|
+
step=step, index=index, clobber=False)
|
|
95
|
+
|
|
96
|
+
# Input/output requirements.
|
|
97
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
|
|
98
|
+
chip.set('tool', tool, 'task', task, 'output', design + '.vg', step=step, index=index)
|
|
99
|
+
chip.add('tool', tool, 'task', task, 'output', design + '.netlist.json', step=step, index=index)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
##################################################
|
|
103
|
+
def syn_post_process(chip):
|
|
104
|
+
''' Tool specific function to run after step execution
|
|
105
|
+
'''
|
|
106
|
+
|
|
107
|
+
step = chip.get('arg', 'step')
|
|
108
|
+
index = chip.get('arg', 'index')
|
|
109
|
+
|
|
110
|
+
with sc_open("reports/stat.json") as f:
|
|
111
|
+
metrics = json.load(f)
|
|
112
|
+
if "design" in metrics:
|
|
113
|
+
metrics = metrics["design"]
|
|
114
|
+
|
|
115
|
+
if "area" in metrics:
|
|
116
|
+
record_metric(chip, step, index, 'cellarea',
|
|
117
|
+
float(metrics["area"]),
|
|
118
|
+
"reports/stat.json",
|
|
119
|
+
source_unit='um^2')
|
|
120
|
+
if "num_cells" in metrics:
|
|
121
|
+
record_metric(chip, step, index, 'cells',
|
|
122
|
+
metrics["num_cells"],
|
|
123
|
+
"reports/stat.json")
|
|
124
|
+
if "num_wire_bits" in metrics:
|
|
125
|
+
record_metric(chip, step, index, 'nets',
|
|
126
|
+
metrics["num_wire_bits"],
|
|
127
|
+
"reports/stat.json")
|
|
128
|
+
if "num_port_bits" in metrics:
|
|
129
|
+
record_metric(chip, step, index, 'pins',
|
|
130
|
+
metrics["num_port_bits"],
|
|
131
|
+
"reports/stat.json")
|
|
132
|
+
|
|
133
|
+
registers = None
|
|
134
|
+
with sc_open(f"{step}.log") as f:
|
|
135
|
+
for line in f:
|
|
136
|
+
line_registers = re.findall(r"^\s*mapped ([0-9]+) \$_DFF.*", line)
|
|
137
|
+
if line_registers:
|
|
138
|
+
if registers is None:
|
|
139
|
+
registers = 0
|
|
140
|
+
registers += int(line_registers[0])
|
|
141
|
+
if registers is not None:
|
|
142
|
+
record_metric(chip, step, index, 'registers', registers, f"{step}.log")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
##################################################
|
|
146
|
+
if __name__ == "__main__":
|
|
147
|
+
|
|
148
|
+
chip = make_docs()
|
|
149
|
+
chip.write_manifest("yosys.json")
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import re
|
|
2
2
|
|
|
3
|
-
from siliconcompiler.tools.yosys
|
|
4
|
-
from siliconcompiler.tools.yosys.syn_asic import setup_asic
|
|
3
|
+
from siliconcompiler.tools.yosys import setup as setup_tool
|
|
4
|
+
from siliconcompiler.tools.yosys.syn_asic import setup_asic, prepare_synthesis_libraries
|
|
5
5
|
from siliconcompiler import sc_open
|
|
6
|
-
from siliconcompiler.tools._common import get_tool_task, record_metric
|
|
6
|
+
from siliconcompiler.tools._common import get_tool_task, record_metric, input_provides
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def setup(chip):
|
|
@@ -28,12 +28,25 @@ def setup(chip):
|
|
|
28
28
|
step=step, index=index, clobber=False)
|
|
29
29
|
|
|
30
30
|
# Input/output requirements.
|
|
31
|
-
if
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
if f"{design}.lec.vg" in input_provides(chip, step, index):
|
|
32
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.lec.vg',
|
|
33
|
+
step=step, index=index)
|
|
34
|
+
elif f"{design}.vg" in input_provides(chip, step, index):
|
|
35
|
+
chip.set('tool', tool, 'task', task, 'input', design + '.vg',
|
|
36
|
+
step=step, index=index)
|
|
37
|
+
else:
|
|
38
|
+
chip.add('tool', tool, 'task', task, 'require', 'input,netlist,verilog',
|
|
39
|
+
step=step, index=index)
|
|
40
|
+
|
|
41
|
+
chip.set('tool', tool, 'task', task, 'var', 'induction_steps', '10',
|
|
42
|
+
step=step, index=index, clobber=False)
|
|
43
|
+
chip.set('tool', tool, 'task', task, 'var', 'induction_steps',
|
|
44
|
+
'Number of induction steps for yosys equivalence checking',
|
|
45
|
+
field='help')
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def pre_process(chip):
|
|
49
|
+
prepare_synthesis_libraries(chip)
|
|
37
50
|
|
|
38
51
|
|
|
39
52
|
##################################################
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Script adapted from
|
|
2
|
-
# https://github.com/The-OpenROAD-Project/OpenLane/blob/
|
|
2
|
+
# https://github.com/The-OpenROAD-Project/OpenLane/blob/2264b1240bacca90f8dfd74b8f5d62b7d618038e/scripts/yosys/logic_equiv_check.tcl
|
|
3
3
|
|
|
4
4
|
source ./sc_manifest.tcl
|
|
5
5
|
set sc_tool yosys
|
|
@@ -10,71 +10,116 @@ set sc_step [sc_cfg_get arg step]
|
|
|
10
10
|
set sc_index [sc_cfg_get arg index]
|
|
11
11
|
set sc_flow [sc_cfg_get option flow]
|
|
12
12
|
set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
|
|
13
|
-
set sc_refdir [sc_cfg_tool_task_get refdir]
|
|
14
13
|
|
|
15
14
|
set sc_design [sc_top]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
set
|
|
20
|
-
set sc_delaymodel [sc_cfg_get asic delaymodel]
|
|
21
|
-
set sc_scenarios [dict keys [sc_cfg_get constraint timing]]
|
|
22
|
-
set sc_libcorner [sc_cfg_get constraint timing [lindex $sc_scenarios 0] libcorner]
|
|
23
|
-
set sc_liberty [sc_cfg_get library $lib output $sc_libcorner $sc_delaymodel]
|
|
24
|
-
|
|
25
|
-
if { [sc_cfg_tool_task_exists "variable" induction_steps] } {
|
|
26
|
-
set sc_induction_steps \
|
|
27
|
-
[lindex [sc_cfg_tool_task_get "variable" induction_steps] 0]
|
|
15
|
+
|
|
16
|
+
set sc_libraries [sc_cfg_tool_task_get {file} synthesis_libraries]
|
|
17
|
+
if { [dict exists $sc_cfg tool $sc_tool task $sc_task {file} synthesis_libraries_macros] } {
|
|
18
|
+
set sc_macro_libraries [sc_cfg_tool_task_get {file} synthesis_libraries_macros]
|
|
28
19
|
} else {
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
set sc_macro_libraries []
|
|
21
|
+
}
|
|
22
|
+
set sc_blackboxes []
|
|
23
|
+
foreach lib [sc_cfg_get asic macrolib] {
|
|
24
|
+
if { [sc_cfg_exists library $lib output blackbox verilog] } {
|
|
25
|
+
foreach lib_f [sc_cfg_get library $lib output blackbox verilog] {
|
|
26
|
+
lappend sc_blackboxes $lib_f
|
|
27
|
+
}
|
|
28
|
+
}
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
set sc_induction_steps [lindex [sc_cfg_tool_task_get {var} induction_steps] 0]
|
|
32
|
+
|
|
33
|
+
proc prepare_libraries { } {
|
|
34
|
+
global sc_libraries
|
|
35
|
+
global sc_macro_libraries
|
|
36
|
+
global sc_blackboxes
|
|
37
|
+
|
|
38
|
+
foreach lib_file "$sc_libraries $sc_macro_libraries" {
|
|
39
|
+
yosys read_liberty -ignore_miss_func -ignore_miss_dir $lib_file
|
|
40
|
+
}
|
|
41
|
+
foreach bb_file $sc_blackboxes {
|
|
42
|
+
puts "Reading blackbox model file: $bb_file"
|
|
43
|
+
yosys read_verilog -sv $bb_file
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
set sc_logiclibs [sc_cfg_get asic logiclib]
|
|
47
|
+
set sc_macrolibs [sc_cfg_get asic macrolib]
|
|
48
|
+
|
|
49
|
+
foreach lib "$sc_logiclibs $sc_macrolibs" {
|
|
50
|
+
foreach phy_type "filler decap antenna tap" {
|
|
51
|
+
if { [sc_cfg_exists library $lib asic cells $phy_type] } {
|
|
52
|
+
foreach cells [sc_cfg_get library $lib asic cells $phy_type] {
|
|
53
|
+
puts "Generating $cells for $lib"
|
|
54
|
+
yosys hierarchy -generate $cells
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
39
59
|
}
|
|
40
|
-
yosys read_verilog $source
|
|
41
60
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
yosys hierarchy -auto-top
|
|
46
|
-
yosys flatten
|
|
61
|
+
proc prepare_design { type v_files } {
|
|
62
|
+
global sc_cfg
|
|
63
|
+
global sc_design
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
yosys
|
|
65
|
+
puts "Preparing \"$type\" design"
|
|
66
|
+
foreach f_file $v_files {
|
|
67
|
+
puts "Reading verilog file: $f_file"
|
|
68
|
+
yosys read_verilog -sv $f_file
|
|
69
|
+
}
|
|
52
70
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
71
|
+
########################################################
|
|
72
|
+
# Override top level parameters
|
|
73
|
+
########################################################
|
|
74
|
+
|
|
75
|
+
yosys chparam -list
|
|
76
|
+
if { [dict exists $sc_cfg option param] } {
|
|
77
|
+
dict for {key value} [sc_cfg_get option param] {
|
|
78
|
+
if { ![string is integer $value] } {
|
|
79
|
+
set value [concat \"$value\"]
|
|
80
|
+
}
|
|
81
|
+
yosys chparam -set $key $value $sc_design
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
prepare_libraries
|
|
86
|
+
|
|
87
|
+
yosys proc
|
|
88
|
+
yosys rmports
|
|
89
|
+
yosys splitnets -ports
|
|
90
|
+
yosys hierarchy -top $sc_design
|
|
91
|
+
yosys async2sync
|
|
92
|
+
yosys flatten
|
|
93
|
+
|
|
94
|
+
yosys setattr -set keep 1
|
|
95
|
+
yosys stat
|
|
96
|
+
yosys rename -top $type
|
|
97
|
+
yosys design -stash $type
|
|
59
98
|
}
|
|
60
|
-
yosys read_verilog $netlist
|
|
61
99
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
100
|
+
# Gold netlist
|
|
101
|
+
if { [file exists "inputs/${sc_design}.v"] } {
|
|
102
|
+
set gold_source "inputs/${sc_design}.v"
|
|
103
|
+
} else {
|
|
104
|
+
set gold_source [sc_cfg_get input rtl verilog]
|
|
105
|
+
}
|
|
106
|
+
prepare_design gold $gold_source
|
|
67
107
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
108
|
+
# Gate netlist
|
|
109
|
+
if { [file exists "inputs/${sc_design}.lec.vg"] } {
|
|
110
|
+
set gate_source "inputs/${sc_design}.lec.vg"
|
|
111
|
+
} elseif { [file exists "inputs/${sc_design}.vg"] } {
|
|
112
|
+
set gate_source "inputs/${sc_design}.vg"
|
|
113
|
+
} else {
|
|
114
|
+
set gate_source [sc_cfg_get input netlist verilog]
|
|
115
|
+
}
|
|
116
|
+
prepare_design gate $gate_source
|
|
72
117
|
|
|
73
118
|
yosys design -copy-from gold -as gold gold
|
|
74
119
|
yosys design -copy-from gate -as gate gate
|
|
75
120
|
|
|
76
121
|
# Rebuild the database due to -stash
|
|
77
|
-
|
|
122
|
+
prepare_libraries
|
|
78
123
|
|
|
79
124
|
yosys equiv_make gold gate equiv
|
|
80
125
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from siliconcompiler.tools.yosys
|
|
1
|
+
from siliconcompiler.tools.yosys import setup as tool_setup
|
|
2
2
|
import os
|
|
3
3
|
import siliconcompiler.tools.yosys.prepareLib as prepareLib
|
|
4
4
|
from siliconcompiler.tools._common.asic import get_libraries
|
|
5
5
|
from siliconcompiler.tools._common import get_tool_task
|
|
6
|
-
from siliconcompiler.targets import asap7_demo
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
def make_docs(chip):
|
|
9
|
+
from siliconcompiler.targets import asap7_demo
|
|
10
10
|
chip.use(asap7_demo)
|
|
11
11
|
|
|
12
12
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
from siliconcompiler.tools.yosys
|
|
2
|
+
from siliconcompiler.tools.yosys import syn_setup, syn_post_process
|
|
3
3
|
import os
|
|
4
|
+
import json
|
|
4
5
|
import re
|
|
5
|
-
|
|
6
|
+
from siliconcompiler.tools.yosys.prepareLib import processLibertyFile
|
|
6
7
|
from siliconcompiler import sc_open
|
|
7
8
|
from siliconcompiler import utils
|
|
8
|
-
from siliconcompiler.tools._common.asic import set_tool_task_var, get_libraries, get_mainlib
|
|
9
|
+
from siliconcompiler.tools._common.asic import set_tool_task_var, get_libraries, get_mainlib, \
|
|
10
|
+
CellArea
|
|
9
11
|
from siliconcompiler.tools._common import get_tool_task
|
|
10
|
-
from siliconcompiler.targets import asap7_demo
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def make_docs(chip):
|
|
15
|
+
from siliconcompiler.targets import asap7_demo
|
|
14
16
|
chip.use(asap7_demo)
|
|
15
17
|
|
|
16
18
|
|
|
@@ -158,9 +160,6 @@ def setup_asic(chip):
|
|
|
158
160
|
'true/false, techmap adders in Yosys', field='help')
|
|
159
161
|
chip.set('tool', tool, 'task', task, 'var', 'synthesis_corner',
|
|
160
162
|
'Timing corner to use for synthesis', field='help')
|
|
161
|
-
chip.set('tool', tool, 'task', task, 'file', 'dff_liberty',
|
|
162
|
-
'Liberty file to use for flip-flop mapping, if not specified the first in the '
|
|
163
|
-
'logiclib is used', field='help')
|
|
164
163
|
chip.set('tool', tool, 'task', task, 'var', 'abc_constraint_driver',
|
|
165
164
|
'Buffer that drives the abc techmapping, defaults to first buffer specified',
|
|
166
165
|
field='help')
|
|
@@ -174,8 +173,6 @@ def setup_asic(chip):
|
|
|
174
173
|
'values between 0 and 1', field='help')
|
|
175
174
|
chip.set('tool', tool, 'task', task, 'file', 'techmap',
|
|
176
175
|
'File to use for techmapping in Yosys', field='help')
|
|
177
|
-
chip.set('tool', tool, 'task', task, 'file', 'dff_liberty_file',
|
|
178
|
-
'File to use for the DFF mapping stage of Yosys', field='help')
|
|
179
176
|
chip.set('tool', tool, 'task', task, 'var', 'add_buffers',
|
|
180
177
|
'true/false, flag to indicate whether to add buffers or not.', field='help')
|
|
181
178
|
|
|
@@ -188,6 +185,14 @@ def setup_asic(chip):
|
|
|
188
185
|
'Instance limit for the number of cells in a module to preserve.',
|
|
189
186
|
field='help')
|
|
190
187
|
|
|
188
|
+
set_tool_task_var(chip, 'map_clockgates',
|
|
189
|
+
default_value=False,
|
|
190
|
+
schelp='Map clockgates during synthesis.')
|
|
191
|
+
|
|
192
|
+
set_tool_task_var(chip, 'min_clockgate_fanout',
|
|
193
|
+
default_value=8,
|
|
194
|
+
schelp='Minimum clockgate fanout.')
|
|
195
|
+
|
|
191
196
|
chip.set('tool', tool, 'task', task, 'var', 'strategy',
|
|
192
197
|
'ABC synthesis strategy. Allowed values are DELAY0-4, AREA0-3, or if the strategy '
|
|
193
198
|
'starts with a + it is assumed to be actual commands for ABC.',
|
|
@@ -216,22 +221,13 @@ def prepare_synthesis_libraries(chip):
|
|
|
216
221
|
corners = chip.get('tool', tool, 'task', task, 'var', 'synthesis_corner',
|
|
217
222
|
step=step, index=index)
|
|
218
223
|
|
|
219
|
-
|
|
220
|
-
dff_liberty_file = chip.find_files('tool', tool, 'task', task, 'file', 'dff_liberty',
|
|
221
|
-
step=step, index=index)[0]
|
|
222
|
-
yosys_dff_file = chip.get('tool', tool, 'task', task, 'file', 'dff_liberty_file',
|
|
223
|
-
step=step, index=index)[0]
|
|
224
|
-
|
|
225
|
-
with open(yosys_dff_file, 'w') as f:
|
|
226
|
-
f.write(prepareLib.processLibertyFile(
|
|
227
|
-
dff_liberty_file,
|
|
228
|
-
logger=None if chip.get('option', 'quiet', step=step, index=index) else chip.logger
|
|
229
|
-
))
|
|
224
|
+
logger = None if chip.get('option', 'quiet', step=step, index=index) else chip.logger
|
|
230
225
|
|
|
231
226
|
# Clear in case of rerun
|
|
232
227
|
for libtype in ('synthesis_libraries', 'synthesis_libraries_macros'):
|
|
233
228
|
chip.set('tool', tool, 'task', task, 'file', libtype, [],
|
|
234
229
|
step=step, index=index)
|
|
230
|
+
chip.set('tool', tool, 'task', task, 'file', libtype, False, field='copy')
|
|
235
231
|
|
|
236
232
|
# Generate synthesis_libraries and synthesis_macro_libraries for Yosys use
|
|
237
233
|
|
|
@@ -244,9 +240,11 @@ def prepare_synthesis_libraries(chip):
|
|
|
244
240
|
return chip.find_files(*keypath, step=step, index=index)
|
|
245
241
|
return []
|
|
246
242
|
|
|
243
|
+
lib_file_map = {}
|
|
247
244
|
for libtype in ('logic', 'macro'):
|
|
248
245
|
for lib in get_libraries(chip, libtype):
|
|
249
246
|
lib_content = {}
|
|
247
|
+
lib_map = {}
|
|
250
248
|
# Mark dont use
|
|
251
249
|
for lib_file in get_synthesis_libraries(lib):
|
|
252
250
|
# Ensure a unique name is used for library
|
|
@@ -262,15 +260,11 @@ def prepare_synthesis_libraries(chip):
|
|
|
262
260
|
lib_file_name = f'{lib_file_name_base}_{unique_ident}'
|
|
263
261
|
unique_ident += 1
|
|
264
262
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
lib_content[lib_file_name] = prepareLib.processLibertyFile(
|
|
271
|
-
lib_file,
|
|
272
|
-
logger=None if chip.get('option', 'quiet',
|
|
273
|
-
step=step, index=index) else chip.logger)
|
|
263
|
+
lib_content[lib_file_name] = processLibertyFile(
|
|
264
|
+
lib_file,
|
|
265
|
+
logger=logger
|
|
266
|
+
)
|
|
267
|
+
lib_map[lib_file_name] = lib_file
|
|
274
268
|
|
|
275
269
|
if not lib_content:
|
|
276
270
|
continue
|
|
@@ -285,6 +279,7 @@ def prepare_synthesis_libraries(chip):
|
|
|
285
279
|
'inputs',
|
|
286
280
|
f'sc_{libtype}_{lib}_{file}.lib'
|
|
287
281
|
)
|
|
282
|
+
lib_file_map[lib_map[file]] = output_file
|
|
288
283
|
|
|
289
284
|
with open(output_file, 'w') as f:
|
|
290
285
|
f.write(content)
|
|
@@ -383,42 +378,6 @@ def _get_synthesis_library_key(chip, lib, corners):
|
|
|
383
378
|
return ('library', lib, 'output', corners[0], delaymodel)
|
|
384
379
|
|
|
385
380
|
|
|
386
|
-
def get_dff_liberty_file(chip):
|
|
387
|
-
tool = 'yosys'
|
|
388
|
-
step = chip.get('arg', 'step')
|
|
389
|
-
index = chip.get('arg', 'index')
|
|
390
|
-
_, task = get_tool_task(chip, step, index)
|
|
391
|
-
|
|
392
|
-
dff_liberty = None
|
|
393
|
-
if chip.valid('tool', tool, 'task', task, 'file', 'dff_liberty'):
|
|
394
|
-
dff_liberty = chip.find_files('tool', tool, 'task', task, 'file', 'dff_liberty',
|
|
395
|
-
step=step, index=index)
|
|
396
|
-
if dff_liberty:
|
|
397
|
-
return dff_liberty[0]
|
|
398
|
-
|
|
399
|
-
mainlib = get_mainlib(chip)
|
|
400
|
-
if chip.valid('library', mainlib, 'option', 'file', 'yosys_dff_liberty'):
|
|
401
|
-
dff_liberty = chip.find_files('library', mainlib, 'option', 'file', 'yosys_dff_liberty')
|
|
402
|
-
if dff_liberty:
|
|
403
|
-
return dff_liberty[0]
|
|
404
|
-
|
|
405
|
-
corners = get_synthesis_corner(chip)
|
|
406
|
-
if corners is None:
|
|
407
|
-
return None
|
|
408
|
-
|
|
409
|
-
# if dff liberty file is not set, use the first liberty file defined
|
|
410
|
-
for lib in get_libraries(chip, 'logic'):
|
|
411
|
-
if not chip.valid(*_get_synthesis_library_key(chip, lib, corners)):
|
|
412
|
-
continue
|
|
413
|
-
|
|
414
|
-
lib_files = chip.find_files(*_get_synthesis_library_key(chip, lib, corners),
|
|
415
|
-
step=step, index=index)
|
|
416
|
-
if len(lib_files) > 0:
|
|
417
|
-
return lib_files[0]
|
|
418
|
-
|
|
419
|
-
return None
|
|
420
|
-
|
|
421
|
-
|
|
422
381
|
def get_abc_period(chip):
|
|
423
382
|
|
|
424
383
|
tool = 'yosys'
|
|
@@ -550,17 +509,10 @@ def pre_process(chip):
|
|
|
550
509
|
chip.add('tool', tool, 'task', task, 'file', 'techmap', techmap, step=step, index=index)
|
|
551
510
|
|
|
552
511
|
# Constants needed by yosys, do not allow overriding of values so force clobbering
|
|
553
|
-
chip.set('tool', tool, 'task', task, 'file', 'dff_liberty_file',
|
|
554
|
-
f"{chip.getworkdir(step=step, index=index)}/inputs/sc_dff_library.lib",
|
|
555
|
-
step=step, index=index, clobber=True)
|
|
556
512
|
chip.set('tool', tool, 'task', task, 'file', 'abc_constraint_file',
|
|
557
513
|
f"{chip.getworkdir(step=step, index=index)}/inputs/sc_abc.constraints",
|
|
558
514
|
step=step, index=index, clobber=True)
|
|
559
|
-
|
|
560
|
-
dff_liberty_file = get_dff_liberty_file(chip)
|
|
561
|
-
if dff_liberty_file:
|
|
562
|
-
chip.set('tool', tool, 'task', task, 'file', 'dff_liberty', dff_liberty_file,
|
|
563
|
-
step=step, index=index, clobber=False)
|
|
515
|
+
chip.set('tool', tool, 'task', task, 'file', 'abc_constraint_file', False, field='copy')
|
|
564
516
|
|
|
565
517
|
abc_clock_period = get_abc_period(chip)
|
|
566
518
|
if abc_clock_period:
|
|
@@ -569,8 +521,80 @@ def pre_process(chip):
|
|
|
569
521
|
|
|
570
522
|
prepare_synthesis_libraries(chip)
|
|
571
523
|
create_abc_synthesis_constraints(chip)
|
|
572
|
-
return
|
|
573
524
|
|
|
574
525
|
|
|
575
526
|
def post_process(chip):
|
|
576
527
|
syn_post_process(chip)
|
|
528
|
+
_generate_cell_area_report(chip)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def _generate_cell_area_report(chip):
|
|
532
|
+
design = "gcd"
|
|
533
|
+
if not os.path.exists('reports/stat.json'):
|
|
534
|
+
return
|
|
535
|
+
if not os.path.exists(f'outputs/{design}.netlist.json'):
|
|
536
|
+
return
|
|
537
|
+
|
|
538
|
+
with sc_open('reports/stat.json') as fd:
|
|
539
|
+
stat = json.load(fd)
|
|
540
|
+
|
|
541
|
+
with sc_open(f'outputs/{design}.netlist.json') as fd:
|
|
542
|
+
netlist = json.load(fd)
|
|
543
|
+
modules = []
|
|
544
|
+
for module in stat["modules"].keys():
|
|
545
|
+
if module[0] == "\\":
|
|
546
|
+
modules.append(module[1:])
|
|
547
|
+
|
|
548
|
+
cellarea_report = CellArea()
|
|
549
|
+
|
|
550
|
+
def get_area_count(module):
|
|
551
|
+
if f"\\{module}" not in stat["modules"]:
|
|
552
|
+
return 0.0, 0
|
|
553
|
+
info = stat["modules"][f"\\{module}"]
|
|
554
|
+
|
|
555
|
+
count = info["num_cells"]
|
|
556
|
+
area = 0.0
|
|
557
|
+
if "area" in info:
|
|
558
|
+
area = info["area"]
|
|
559
|
+
|
|
560
|
+
for cell, inst_count in info["num_cells_by_type"].items():
|
|
561
|
+
# print(module, cell, inst_count)
|
|
562
|
+
|
|
563
|
+
cell_area, cell_count = get_area_count(cell)
|
|
564
|
+
|
|
565
|
+
count += cell_count * inst_count
|
|
566
|
+
if cell_count > 0:
|
|
567
|
+
count -= inst_count
|
|
568
|
+
area += cell_area * inst_count
|
|
569
|
+
|
|
570
|
+
return area, count
|
|
571
|
+
|
|
572
|
+
def handle_heir(level_info, prefix):
|
|
573
|
+
cells = list(level_info["cells"])
|
|
574
|
+
|
|
575
|
+
for cell in cells:
|
|
576
|
+
cell_type = level_info["cells"][cell]["type"]
|
|
577
|
+
if cell_type in modules:
|
|
578
|
+
area, count = get_area_count(cell_type)
|
|
579
|
+
cellarea_report.addCell(
|
|
580
|
+
name=f"{prefix}{cell}",
|
|
581
|
+
module=cell_type,
|
|
582
|
+
cellcount=count,
|
|
583
|
+
cellarea=area)
|
|
584
|
+
handle_heir(netlist["modules"][cell_type], f"{prefix}{cell}.")
|
|
585
|
+
|
|
586
|
+
count = stat["design"]["num_cells"]
|
|
587
|
+
area = 0.0
|
|
588
|
+
if "area" in stat["design"]:
|
|
589
|
+
area = stat["design"]["area"]
|
|
590
|
+
cellarea_report.addCell(
|
|
591
|
+
name=design,
|
|
592
|
+
module=design,
|
|
593
|
+
cellarea=area,
|
|
594
|
+
cellcount=count
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
handle_heir(netlist["modules"][design], "")
|
|
598
|
+
|
|
599
|
+
if cellarea_report.size() > 0:
|
|
600
|
+
cellarea_report.writeReport("reports/hierarchical_cell_area.json")
|