siliconcompiler 0.29.0__py3-none-any.whl → 0.29.2__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.
Files changed (104) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/apps/__init__.py +26 -0
  3. siliconcompiler/apps/sc_install.py +1 -1
  4. siliconcompiler/apps/utils/replay.py +96 -38
  5. siliconcompiler/checklists/__init__.py +12 -0
  6. siliconcompiler/core.py +85 -15
  7. siliconcompiler/flows/__init__.py +34 -0
  8. siliconcompiler/flows/showflow.py +1 -1
  9. siliconcompiler/libs/__init__.py +5 -0
  10. siliconcompiler/optimizer/__init__.py +199 -0
  11. siliconcompiler/optimizer/vizier.py +259 -0
  12. siliconcompiler/pdks/__init__.py +5 -0
  13. siliconcompiler/scheduler/__init__.py +67 -49
  14. siliconcompiler/scheduler/send_messages.py +1 -1
  15. siliconcompiler/schema/schema_cfg.py +2 -2
  16. siliconcompiler/schema/schema_obj.py +13 -10
  17. siliconcompiler/schema/utils.py +2 -0
  18. siliconcompiler/sphinx_ext/__init__.py +85 -0
  19. siliconcompiler/sphinx_ext/dynamicgen.py +17 -33
  20. siliconcompiler/sphinx_ext/schemagen.py +3 -2
  21. siliconcompiler/targets/__init__.py +26 -0
  22. siliconcompiler/templates/replay/replay.py.j2 +62 -0
  23. siliconcompiler/templates/replay/requirements.txt +2 -1
  24. siliconcompiler/templates/replay/setup.sh +119 -6
  25. siliconcompiler/tools/__init__.py +62 -0
  26. siliconcompiler/tools/_common/asic.py +77 -6
  27. siliconcompiler/tools/_common/tcl/sc_pin_constraints.tcl +2 -2
  28. siliconcompiler/tools/ghdl/ghdl.py +1 -2
  29. siliconcompiler/tools/gtkwave/__init__.py +39 -0
  30. siliconcompiler/tools/gtkwave/scripts/sc_show.tcl +34 -0
  31. siliconcompiler/tools/gtkwave/show.py +70 -0
  32. siliconcompiler/tools/icarus/compile.py +4 -0
  33. siliconcompiler/tools/klayout/convert_drc_db.py +1 -1
  34. siliconcompiler/tools/klayout/drc.py +1 -1
  35. siliconcompiler/tools/klayout/export.py +8 -1
  36. siliconcompiler/tools/klayout/klayout.py +2 -2
  37. siliconcompiler/tools/klayout/klayout_convert_drc_db.py +2 -2
  38. siliconcompiler/tools/klayout/klayout_export.py +7 -5
  39. siliconcompiler/tools/klayout/klayout_operations.py +4 -3
  40. siliconcompiler/tools/klayout/klayout_show.py +3 -2
  41. siliconcompiler/tools/klayout/klayout_utils.py +1 -1
  42. siliconcompiler/tools/klayout/operations.py +8 -0
  43. siliconcompiler/tools/klayout/screenshot.py +6 -1
  44. siliconcompiler/tools/klayout/show.py +8 -1
  45. siliconcompiler/tools/magic/magic.py +1 -1
  46. siliconcompiler/tools/openroad/__init__.py +1 -1
  47. siliconcompiler/tools/openroad/_apr.py +11 -2
  48. siliconcompiler/tools/openroad/global_placement.py +23 -2
  49. siliconcompiler/tools/openroad/init_floorplan.py +1 -1
  50. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +1 -1
  51. siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +4 -0
  52. siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +64 -1
  53. siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +4 -0
  54. siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +8 -2
  55. siliconcompiler/tools/openroad/scripts/common/procs.tcl +88 -0
  56. siliconcompiler/tools/openroad/scripts/common/reports.tcl +1 -1
  57. siliconcompiler/tools/openroad/scripts/common/write_images.tcl +10 -1
  58. siliconcompiler/tools/openroad/scripts/sc_show.tcl +5 -0
  59. siliconcompiler/tools/opensta/__init__.py +1 -1
  60. siliconcompiler/tools/opensta/check_library.py +27 -0
  61. siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +255 -0
  62. siliconcompiler/tools/opensta/scripts/sc_timing.tcl +1 -1
  63. siliconcompiler/tools/sv2v/sv2v.py +1 -2
  64. siliconcompiler/tools/verilator/compile.py +11 -0
  65. siliconcompiler/tools/verilator/verilator.py +7 -8
  66. siliconcompiler/tools/vivado/vivado.py +1 -1
  67. siliconcompiler/tools/yosys/__init__.py +149 -0
  68. siliconcompiler/tools/yosys/lec.py +22 -9
  69. siliconcompiler/tools/yosys/sc_lec.tcl +94 -49
  70. siliconcompiler/tools/yosys/sc_syn.tcl +1 -0
  71. siliconcompiler/tools/yosys/screenshot.py +2 -2
  72. siliconcompiler/tools/yosys/syn_asic.py +98 -74
  73. siliconcompiler/tools/yosys/syn_asic.tcl +31 -6
  74. siliconcompiler/tools/yosys/syn_fpga.py +2 -3
  75. siliconcompiler/tools/yosys/syn_fpga.tcl +0 -1
  76. siliconcompiler/toolscripts/_tools.json +8 -3
  77. siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +40 -0
  78. siliconcompiler/toolscripts/ubuntu20/install-gtkwave.sh +28 -0
  79. siliconcompiler/toolscripts/ubuntu22/install-gtkwave.sh +28 -0
  80. siliconcompiler/toolscripts/ubuntu22/install-slang.sh +0 -0
  81. siliconcompiler/toolscripts/ubuntu24/install-gtkwave.sh +29 -0
  82. siliconcompiler/utils/__init__.py +7 -3
  83. siliconcompiler/utils/showtools.py +3 -0
  84. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.dist-info}/METADATA +14 -11
  85. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.dist-info}/RECORD +88 -91
  86. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.dist-info}/WHEEL +1 -1
  87. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.dist-info}/entry_points.txt +13 -0
  88. siliconcompiler/libs/asap7sc7p5t.py +0 -8
  89. siliconcompiler/libs/gf180mcu.py +0 -8
  90. siliconcompiler/libs/interposer.py +0 -8
  91. siliconcompiler/libs/nangate45.py +0 -8
  92. siliconcompiler/libs/sg13g2_stdcell.py +0 -8
  93. siliconcompiler/libs/sky130hd.py +0 -8
  94. siliconcompiler/libs/sky130io.py +0 -8
  95. siliconcompiler/pdks/asap7.py +0 -8
  96. siliconcompiler/pdks/freepdk45.py +0 -8
  97. siliconcompiler/pdks/gf180.py +0 -8
  98. siliconcompiler/pdks/ihp130.py +0 -8
  99. siliconcompiler/pdks/interposer.py +0 -8
  100. siliconcompiler/pdks/skywater130.py +0 -8
  101. siliconcompiler/templates/replay/run.py.j2 +0 -22
  102. siliconcompiler/tools/yosys/yosys.py +0 -148
  103. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.dist-info}/LICENSE +0 -0
  104. {siliconcompiler-0.29.0.dist-info → siliconcompiler-0.29.2.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.yosys import setup as setup_tool
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 not chip.valid('input', 'netlist', 'verilog') or \
32
- not chip.get('input', 'netlist', 'verilog', step=step, index=index):
33
- chip.set('tool', tool, 'task', task, 'input', design + '.vg', step=step, index=index)
34
- # if not chip.get('input', 'rtl', 'verilog'):
35
- # TODO: Not sure this logic makes sense? Seems like reverse of tcl
36
- # chip.set('tool', tool, 'task', task, 'input', design + '.v', step=step, index=index)
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/d052a918f4a46ddbae0ad09812f6cd0b8eb4a1e5/scripts/logic_equiv_check.tcl
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
- set sc_targetlibs [sc_get_asic_libraries logic]
17
-
18
- # TODO: properly handle complexity here
19
- set lib [lindex $sc_targetlibs 0]
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
- # Yosys default
30
- set sc_induction_steps 4
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
- # Gold netlist
34
- yosys read_liberty -ignore_miss_func $sc_liberty
35
- if { [file exists "inputs/$sc_design.v"] } {
36
- set source "inputs/$sc_design.v"
37
- } else {
38
- set source [lindex [sc_cfg_get input rtl verilog] 0]
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
- yosys proc
43
- yosys rmports
44
- yosys splitnets -ports
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
- yosys setattr -set keep 1
49
- yosys stat
50
- yosys rename -top gold
51
- yosys design -stash gold
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
- # Gate netlist
54
- yosys read_liberty -ignore_miss_func $sc_liberty
55
- if { [sc_cfg_exists input netlist verilog] } {
56
- set netlist [lindex [sc_cfg_get input netlist verilog] 0]
57
- } else {
58
- set netlist "inputs/$sc_design.vg"
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
- yosys proc
63
- yosys rmports
64
- yosys splitnets -ports
65
- yosys hierarchy -auto-top
66
- yosys flatten
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
- yosys setattr -set keep 1
69
- yosys stat
70
- yosys rename -top gate
71
- yosys design -stash gate
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
- yosys read_liberty -ignore_miss_func $sc_liberty
122
+ prepare_libraries
78
123
 
79
124
  yosys equiv_make gold gate equiv
80
125
 
@@ -75,3 +75,4 @@ source "$sc_refdir/${sc_task}.tcl"
75
75
  # Write Netlist
76
76
  ########################################################
77
77
  yosys write_verilog -noexpr -nohex -nodec "outputs/${sc_design}.vg"
78
+ yosys write_json "outputs/${sc_design}.netlist.json"
@@ -1,12 +1,12 @@
1
- from siliconcompiler.tools.yosys.yosys import setup as tool_setup
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.yosys import syn_setup, syn_post_process
2
+ from siliconcompiler.tools.yosys import syn_setup, syn_post_process
3
3
  import os
4
+ import json
4
5
  import re
5
- import siliconcompiler.tools.yosys.prepareLib as prepareLib
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
- # mark dff libery file with dont use
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
- if lib_file == dff_liberty_file:
266
- with sc_open(yosys_dff_file) as f:
267
- lib_content[lib_file_name] = f.read()
268
- continue
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")