siliconcompiler 0.32.0__py3-none-any.whl → 0.32.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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/_common.py +23 -6
- siliconcompiler/apps/sc_dashboard.py +7 -1
- siliconcompiler/apps/sc_install.py +13 -5
- siliconcompiler/apps/sc_remote.py +2 -1
- siliconcompiler/apps/sc_show.py +6 -0
- siliconcompiler/core.py +34 -16
- siliconcompiler/fpgas/lattice_ice40.py +6 -16
- siliconcompiler/package/__init__.py +11 -55
- siliconcompiler/package/github.py +124 -0
- siliconcompiler/package/https.py +6 -0
- siliconcompiler/report/dashboard/components/__init__.py +2 -1
- siliconcompiler/report/dashboard/components/flowgraph.py +3 -0
- siliconcompiler/report/dashboard/utils/__init__.py +5 -2
- siliconcompiler/report/utils.py +3 -0
- siliconcompiler/scheduler/__init__.py +37 -8
- siliconcompiler/scheduler/docker_runner.py +2 -1
- siliconcompiler/schema/schema_obj.py +3 -2
- siliconcompiler/schema/utils.py +0 -3
- siliconcompiler/sphinx_ext/dynamicgen.py +11 -11
- siliconcompiler/targets/fpgaflow_demo.py +0 -2
- siliconcompiler/templates/tcl/manifest.tcl.j2 +4 -120
- siliconcompiler/tools/_common/tcl/sc_schema_access.tcl +126 -0
- siliconcompiler/tools/openroad/_apr.py +3 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +53 -7
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +19 -1
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +16 -5
- siliconcompiler/tools/slang/__init__.py +7 -8
- siliconcompiler/tools/sv2v/sv2v.py +4 -1
- siliconcompiler/tools/yosys/__init__.py +4 -36
- siliconcompiler/tools/yosys/lec.py +3 -4
- siliconcompiler/tools/yosys/{syn_asic.tcl → sc_synth_asic.tcl} +79 -0
- siliconcompiler/tools/yosys/{syn_fpga.tcl → sc_synth_fpga.tcl} +78 -0
- siliconcompiler/tools/yosys/syn_asic.py +26 -10
- siliconcompiler/tools/yosys/syn_fpga.py +23 -16
- siliconcompiler/toolscripts/_tools.json +18 -9
- siliconcompiler/toolscripts/rhel9/install-gtkwave.sh +1 -1
- siliconcompiler/toolscripts/rhel9/install-vpr.sh +29 -0
- siliconcompiler/toolscripts/rhel9/install-yosys-parmys.sh +59 -0
- siliconcompiler/toolscripts/ubuntu20/install-yosys-parmys.sh +59 -0
- siliconcompiler/toolscripts/ubuntu22/install-bluespec.sh +25 -2
- siliconcompiler/toolscripts/ubuntu22/install-ghdl.sh +2 -2
- siliconcompiler/toolscripts/ubuntu22/install-yosys-parmys.sh +59 -0
- siliconcompiler/toolscripts/ubuntu24/install-ghdl.sh +2 -2
- siliconcompiler/toolscripts/ubuntu24/install-icarus.sh +2 -1
- siliconcompiler/toolscripts/ubuntu24/install-netgen.sh +1 -1
- siliconcompiler/toolscripts/ubuntu24/install-yosys-parmys.sh +59 -0
- siliconcompiler/utils/__init__.py +9 -15
- siliconcompiler/utils/logging.py +1 -1
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/METADATA +12 -9
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/RECORD +55 -55
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/entry_points.txt +1 -0
- siliconcompiler/fpgas/vpr_example.py +0 -116
- siliconcompiler/tools/yosys/sc_syn.tcl +0 -87
- siliconcompiler/toolscripts/rhel8/install-ghdl.sh +0 -25
- siliconcompiler/toolscripts/rhel8/install-yosys-moosic.sh +0 -17
- siliconcompiler/toolscripts/rhel8/install-yosys-slang.sh +0 -22
- siliconcompiler/toolscripts/rhel8/install-yosys.sh +0 -23
- siliconcompiler/toolscripts/ubuntu20/install-yosys-slang.sh +0 -22
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info/licenses}/LICENSE +0 -0
- {siliconcompiler-0.32.0.dist-info → siliconcompiler-0.32.2.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,7 @@ import contextlib
|
|
|
2
2
|
import distro
|
|
3
3
|
import getpass
|
|
4
4
|
import multiprocessing
|
|
5
|
+
import logging
|
|
5
6
|
import os
|
|
6
7
|
import platform
|
|
7
8
|
import psutil
|
|
@@ -17,6 +18,7 @@ import packaging.specifiers
|
|
|
17
18
|
from io import StringIO
|
|
18
19
|
import traceback
|
|
19
20
|
from datetime import datetime
|
|
21
|
+
from logging.handlers import QueueHandler, QueueListener
|
|
20
22
|
from siliconcompiler import sc_open
|
|
21
23
|
from siliconcompiler import utils
|
|
22
24
|
from siliconcompiler import _metadata
|
|
@@ -275,7 +277,12 @@ def _local_process(chip, flow):
|
|
|
275
277
|
nodes_to_run = {}
|
|
276
278
|
processes = {}
|
|
277
279
|
local_processes = []
|
|
278
|
-
_prepare_nodes(chip, nodes_to_run, processes, local_processes, flow)
|
|
280
|
+
log_queue = _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow)
|
|
281
|
+
|
|
282
|
+
# Handle logs across threads
|
|
283
|
+
log_listener = QueueListener(log_queue, chip.logger._console)
|
|
284
|
+
chip.logger._console.setFormatter(logging.Formatter("%(message)s"))
|
|
285
|
+
log_listener.start()
|
|
279
286
|
|
|
280
287
|
# Update dashboard before run begins
|
|
281
288
|
if chip._dash:
|
|
@@ -285,6 +292,7 @@ def _local_process(chip, flow):
|
|
|
285
292
|
_launch_nodes(chip, nodes_to_run, processes, local_processes)
|
|
286
293
|
except KeyboardInterrupt:
|
|
287
294
|
# exit immediately
|
|
295
|
+
log_listener.stop()
|
|
288
296
|
sys.exit(0)
|
|
289
297
|
|
|
290
298
|
if _get_callback('post_run'):
|
|
@@ -292,6 +300,10 @@ def _local_process(chip, flow):
|
|
|
292
300
|
|
|
293
301
|
_check_nodes_status(chip, flow)
|
|
294
302
|
|
|
303
|
+
# Cleanup logger
|
|
304
|
+
log_listener.stop()
|
|
305
|
+
chip._init_logger_formats()
|
|
306
|
+
|
|
295
307
|
|
|
296
308
|
def __is_posix():
|
|
297
309
|
return sys.platform != 'win32'
|
|
@@ -421,7 +433,7 @@ def _check_version(chip, reported_version, tool, step, index):
|
|
|
421
433
|
|
|
422
434
|
|
|
423
435
|
###########################################################################
|
|
424
|
-
def _runtask(chip, flow, step, index, exec_func, pipe=None, replay=False):
|
|
436
|
+
def _runtask(chip, flow, step, index, exec_func, pipe=None, queue=None, replay=False):
|
|
425
437
|
'''
|
|
426
438
|
Private per node run method called by run().
|
|
427
439
|
|
|
@@ -437,6 +449,11 @@ def _runtask(chip, flow, step, index, exec_func, pipe=None, replay=False):
|
|
|
437
449
|
chip._init_codecs()
|
|
438
450
|
|
|
439
451
|
chip._init_logger(step, index, in_run=True)
|
|
452
|
+
if queue:
|
|
453
|
+
chip.logger.removeHandler(chip.logger._console)
|
|
454
|
+
chip.logger._console = QueueHandler(queue)
|
|
455
|
+
chip.logger.addHandler(chip.logger._console)
|
|
456
|
+
chip._init_logger_formats()
|
|
440
457
|
|
|
441
458
|
chip.set('arg', 'step', step, clobber=True)
|
|
442
459
|
chip.set('arg', 'index', index, clobber=True)
|
|
@@ -541,13 +558,12 @@ def _select_inputs(chip, step, index, trial=False):
|
|
|
541
558
|
'_select_inputs',
|
|
542
559
|
None)
|
|
543
560
|
if select_inputs:
|
|
544
|
-
|
|
561
|
+
log_level = chip.logger.level
|
|
545
562
|
if trial:
|
|
546
|
-
|
|
547
|
-
chip.logger.handlers.clear()
|
|
563
|
+
chip.logger.setLevel(logging.CRITICAL)
|
|
548
564
|
sel_inputs = select_inputs(chip, step, index)
|
|
549
|
-
if
|
|
550
|
-
chip.logger.
|
|
565
|
+
if trial:
|
|
566
|
+
chip.logger.setLevel(log_level)
|
|
551
567
|
else:
|
|
552
568
|
sel_inputs = _get_pruned_node_inputs(chip, flow, (step, index))
|
|
553
569
|
|
|
@@ -862,9 +878,16 @@ def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, ru
|
|
|
862
878
|
stderr_writer.close()
|
|
863
879
|
stderr_writer = sys.stdout
|
|
864
880
|
|
|
881
|
+
# Handle logger stdout suppression if quiet
|
|
882
|
+
stdout_handler_level = chip.logger._console.level
|
|
883
|
+
if chip.get('option', 'quiet', step=step, index=index):
|
|
884
|
+
chip.logger._console.setLevel(logging.CRITICAL)
|
|
885
|
+
|
|
865
886
|
with contextlib.redirect_stderr(stderr_writer), \
|
|
866
887
|
contextlib.redirect_stdout(stdout_writer):
|
|
867
888
|
retcode = run_func(chip)
|
|
889
|
+
|
|
890
|
+
chip.logger._console.setLevel(stdout_handler_level)
|
|
868
891
|
except Exception as e:
|
|
869
892
|
chip.logger.error(f'Failed in run() for {tool}/{task}: {e}')
|
|
870
893
|
retcode = 1 # default to non-zero
|
|
@@ -1491,6 +1514,9 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
|
|
|
1491
1514
|
# Call this in case this was invoked without __main__
|
|
1492
1515
|
multiprocessing.freeze_support()
|
|
1493
1516
|
|
|
1517
|
+
# Log queue for logging messages
|
|
1518
|
+
log_queue = multiprocessing.Queue(-1)
|
|
1519
|
+
|
|
1494
1520
|
init_funcs = set()
|
|
1495
1521
|
for (step, index) in nodes_to_execute(chip, flow):
|
|
1496
1522
|
node = (step, index)
|
|
@@ -1525,13 +1551,16 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
|
|
|
1525
1551
|
process["proc"] = multiprocessing.Process(
|
|
1526
1552
|
target=_runtask,
|
|
1527
1553
|
args=(chip, flow, step, index, exec_func),
|
|
1528
|
-
kwargs={"pipe": process["child_pipe"]
|
|
1554
|
+
kwargs={"pipe": process["child_pipe"],
|
|
1555
|
+
"queue": log_queue})
|
|
1529
1556
|
|
|
1530
1557
|
processes[node] = process
|
|
1531
1558
|
|
|
1532
1559
|
for init_func in init_funcs:
|
|
1533
1560
|
init_func(chip)
|
|
1534
1561
|
|
|
1562
|
+
return log_queue
|
|
1563
|
+
|
|
1535
1564
|
|
|
1536
1565
|
def _check_node_dependencies(chip, node, deps, deps_was_successful):
|
|
1537
1566
|
had_deps = len(deps) > 0
|
|
@@ -115,7 +115,8 @@ def run(chip, step, index, replay):
|
|
|
115
115
|
start_cwd = os.getcwd()
|
|
116
116
|
|
|
117
117
|
# Remove handlers from logger
|
|
118
|
-
chip.logger.handlers.
|
|
118
|
+
for handler in chip.logger.handlers.copy():
|
|
119
|
+
chip.logger.removeHandler(handler)
|
|
119
120
|
|
|
120
121
|
# Reinit logger
|
|
121
122
|
chip._init_logger(step=step, index=index, in_run=True)
|
|
@@ -39,7 +39,7 @@ except ImportError:
|
|
|
39
39
|
_has_yaml = False
|
|
40
40
|
|
|
41
41
|
from .schema_cfg import schema_cfg
|
|
42
|
-
from .utils import escape_val_tcl,
|
|
42
|
+
from .utils import escape_val_tcl, translate_loglevel, PerNode, Scope
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class Schema:
|
|
@@ -1122,7 +1122,8 @@ class Schema:
|
|
|
1122
1122
|
|
|
1123
1123
|
if template:
|
|
1124
1124
|
fout.write(template.render(manifest_dict='\n'.join(tcl_set_cmds),
|
|
1125
|
-
scroot=os.path.abspath(
|
|
1125
|
+
scroot=os.path.abspath(
|
|
1126
|
+
os.path.join(os.path.dirname(__file__), '..')),
|
|
1126
1127
|
record_access=self._do_record_access(),
|
|
1127
1128
|
record_access_id=Schema._RECORD_ACCESS_IDENTIFIER))
|
|
1128
1129
|
else:
|
siliconcompiler/schema/utils.py
CHANGED
|
@@ -4,13 +4,10 @@
|
|
|
4
4
|
# SC dependencies outside of its directory, since it may be used by tool drivers
|
|
5
5
|
# that have isolated Python environments.
|
|
6
6
|
|
|
7
|
-
import os
|
|
8
7
|
import re
|
|
9
8
|
import sys
|
|
10
9
|
from enum import Enum
|
|
11
10
|
|
|
12
|
-
PACKAGE_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
|
13
|
-
|
|
14
11
|
|
|
15
12
|
#############################################################################
|
|
16
13
|
# ENUM DEFINITIONs
|
|
@@ -325,7 +325,7 @@ class DynamicGen(SphinxDirective):
|
|
|
325
325
|
|
|
326
326
|
return True
|
|
327
327
|
|
|
328
|
-
def _document_free_params(self, cfg, type, key_path, reference_prefix, s):
|
|
328
|
+
def _document_free_params(self, cfg, type, key_path, reference_prefix, s, show_type=False):
|
|
329
329
|
if type in cfg:
|
|
330
330
|
cfg = cfg[type]
|
|
331
331
|
else:
|
|
@@ -337,8 +337,12 @@ class DynamicGen(SphinxDirective):
|
|
|
337
337
|
type_heading = "Files"
|
|
338
338
|
elif type == "dir":
|
|
339
339
|
type_heading = "Directories"
|
|
340
|
+
else:
|
|
341
|
+
raise ValueError(type)
|
|
340
342
|
|
|
341
343
|
table = [[strong('Parameters'), strong('Help')]]
|
|
344
|
+
if show_type:
|
|
345
|
+
table[0].insert(1, strong('Type'))
|
|
342
346
|
for key, params in cfg.items():
|
|
343
347
|
if key == "default":
|
|
344
348
|
continue
|
|
@@ -346,7 +350,10 @@ class DynamicGen(SphinxDirective):
|
|
|
346
350
|
key_node = nodes.paragraph()
|
|
347
351
|
key_node += keypath(key_path + [key], self.env.docname,
|
|
348
352
|
key_text=["...", f"'{type}'", f"'{key}'"])
|
|
349
|
-
|
|
353
|
+
entry = [key_node, para(params["help"])]
|
|
354
|
+
if show_type:
|
|
355
|
+
entry.insert(1, code(params["type"]))
|
|
356
|
+
table.append(entry)
|
|
350
357
|
|
|
351
358
|
if len(table) > 1:
|
|
352
359
|
s += build_section(type_heading, self.get_ref(*reference_prefix, type))
|
|
@@ -710,14 +717,6 @@ class ToolGen(DynamicGen):
|
|
|
710
717
|
self.__tool = None
|
|
711
718
|
self.__task = None
|
|
712
719
|
|
|
713
|
-
# Annotate the target used for default values
|
|
714
|
-
if chip.valid('option', 'target') and chip.get('option', 'target'):
|
|
715
|
-
p = docutils.nodes.inline('')
|
|
716
|
-
target = chip.get('option', 'target').split('.')[-1]
|
|
717
|
-
targetid = get_ref_id(DynamicGen.get_ref_key(TargetGen.REF_PREFIX, target))
|
|
718
|
-
self.parse_rst(f"Built using target: :ref:`{target}<{targetid}>`", p)
|
|
719
|
-
s += p
|
|
720
|
-
|
|
721
720
|
try:
|
|
722
721
|
task_setup(chip)
|
|
723
722
|
|
|
@@ -780,7 +779,8 @@ class ToolGen(DynamicGen):
|
|
|
780
779
|
|
|
781
780
|
def document_free_params(self, cfg, reference_prefix, s):
|
|
782
781
|
key_path = ['tool', '<tool>', 'task', '<task>']
|
|
783
|
-
self._document_free_params(cfg, 'var', key_path + ['var'], reference_prefix, s
|
|
782
|
+
self._document_free_params(cfg, 'var', key_path + ['var'], reference_prefix, s,
|
|
783
|
+
show_type=True)
|
|
784
784
|
self._document_free_params(cfg, 'file', key_path + ['file'], reference_prefix, s)
|
|
785
785
|
self._document_free_params(cfg, 'dir', key_path + ['dir'], reference_prefix, s)
|
|
786
786
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import siliconcompiler
|
|
2
2
|
from siliconcompiler import SiliconCompilerError
|
|
3
3
|
from siliconcompiler.fpgas import lattice_ice40
|
|
4
|
-
from siliconcompiler.fpgas import vpr_example
|
|
5
4
|
|
|
6
5
|
from siliconcompiler.flows import fpgaflow
|
|
7
6
|
|
|
@@ -30,7 +29,6 @@ def setup(chip, partname=None):
|
|
|
30
29
|
|
|
31
30
|
# 2. Load all available FPGAs
|
|
32
31
|
chip.use(lattice_ice40)
|
|
33
|
-
chip.use(vpr_example)
|
|
34
32
|
|
|
35
33
|
# 3. Load flow
|
|
36
34
|
chip.use(fpgaflow, partname=partname)
|
|
@@ -11,129 +11,13 @@
|
|
|
11
11
|
# Helper functions
|
|
12
12
|
#############################################
|
|
13
13
|
|
|
14
|
-
# Shortcut to get values from configuration
|
|
15
|
-
proc sc_cfg_get { args } {
|
|
16
|
-
# Refer to global sc_cfg dictionary
|
|
17
|
-
global sc_cfg
|
|
18
|
-
|
|
19
|
-
{% if record_access %}puts "{{ record_access_id }} [join $args ,]"{% endif %}
|
|
20
|
-
|
|
21
|
-
if { ![sc_cfg_exists {*}$args] } {
|
|
22
|
-
throw {FLOW KEYERROR} "key \"$args\" is not in the siliconcompiler configuration"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return [dict get $sc_cfg {*}$args]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
proc sc_cfg_exists { args } {
|
|
29
|
-
# Refer to global sc_cfg dictionary
|
|
30
|
-
global sc_cfg
|
|
31
|
-
|
|
32
|
-
return [dict exists $sc_cfg {*}$args]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
proc sc_top {} {
|
|
36
|
-
set sc_entrypoint [sc_cfg_get option entrypoint]
|
|
37
|
-
if {$sc_entrypoint == {{ '{}' }}} {
|
|
38
|
-
return [sc_cfg_get design]
|
|
39
|
-
}
|
|
40
|
-
return $sc_entrypoint
|
|
41
|
-
}
|
|
42
|
-
|
|
43
14
|
proc sc_root {} {
|
|
44
15
|
return "{{ scroot }}"
|
|
45
16
|
}
|
|
46
17
|
|
|
47
|
-
|
|
48
|
-
proc sc_cfg_tool_task_get { args } {
|
|
49
|
-
set sc_step [sc_cfg_get arg step]
|
|
50
|
-
set sc_index [sc_cfg_get arg index]
|
|
51
|
-
|
|
52
|
-
set sc_flow [sc_cfg_get option flow]
|
|
53
|
-
|
|
54
|
-
set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
|
|
55
|
-
set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
|
|
56
|
-
|
|
57
|
-
return [sc_cfg_get tool $sc_tool task $sc_task {*}$args]
|
|
58
|
-
}
|
|
18
|
+
{% include 'tools/_common/tcl/sc_schema_access.tcl' %}
|
|
59
19
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
set sc_flow [sc_cfg_get option flow]
|
|
65
|
-
|
|
66
|
-
set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
|
|
67
|
-
set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
|
|
68
|
-
|
|
69
|
-
return [sc_cfg_exists tool $sc_tool task $sc_task {*}$args]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
# Check if an item is present in a list
|
|
73
|
-
proc sc_cfg_tool_task_check_in_list { item args } {
|
|
74
|
-
set result [sc_cfg_tool_task_get {*}$args]
|
|
75
|
-
|
|
76
|
-
if { [lsearch -exact $result $item] != -1 } {
|
|
77
|
-
return 1
|
|
78
|
-
} else {
|
|
79
|
-
return 0
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
proc sc_section_banner { text { method puts } } {
|
|
84
|
-
$method "============================================================"
|
|
85
|
-
$method "| $text"
|
|
86
|
-
$method "============================================================"
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Get list of soft libraries
|
|
90
|
-
proc sc_get_libraries { {library {}} {libraries {}} } {
|
|
91
|
-
set key []
|
|
92
|
-
if { [llength $library] != 0 } {
|
|
93
|
-
lappend key library $library
|
|
94
|
-
}
|
|
95
|
-
lappend key option library
|
|
96
|
-
|
|
97
|
-
set libs []
|
|
98
|
-
foreach lib [sc_cfg_get {*}$key] {
|
|
99
|
-
if { [lsearch -exact $libs $lib] != -1 || [lsearch -exact $libraries $lib] != -1 } {
|
|
100
|
-
continue
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
lappend libs $lib
|
|
104
|
-
|
|
105
|
-
foreach sublib [sc_get_libraries $lib $libs] {
|
|
106
|
-
lappend libs $sublib
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return [lsort -unique $libs]
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
# Get list of asic libraries
|
|
114
|
-
proc sc_get_asic_libraries { type } {
|
|
115
|
-
set libs []
|
|
116
|
-
|
|
117
|
-
foreach lib [sc_cfg_get asic ${type}lib] {
|
|
118
|
-
if { [lsearch -exact $libs $lib] != -1 } {
|
|
119
|
-
continue
|
|
120
|
-
}
|
|
121
|
-
lappend libs $lib
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
foreach lib [sc_get_libraries] {
|
|
125
|
-
if { ![sc_cfg_exists library $lib asic ${type}lib] } {
|
|
126
|
-
continue
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
foreach sublib [sc_cfg_get library $lib asic ${type}lib] {
|
|
130
|
-
if { [lsearch -exact $libs $sublib] != -1 } {
|
|
131
|
-
continue
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
lappend libs $sublib
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return $libs
|
|
20
|
+
# Redefine
|
|
21
|
+
proc _sc_cfg_get_debug { args } {
|
|
22
|
+
{% if record_access %}puts "{{ record_access_id }} [join $args ,]"{% endif %}
|
|
139
23
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
proc _sc_cfg_get_debug { args } {
|
|
2
|
+
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
# Shortcut to get values from configuration
|
|
6
|
+
proc sc_cfg_get { args } {
|
|
7
|
+
_sc_cfg_get_debug $args
|
|
8
|
+
|
|
9
|
+
# Refer to global sc_cfg dictionary
|
|
10
|
+
global sc_cfg
|
|
11
|
+
|
|
12
|
+
if { ![sc_cfg_exists {*}$args] } {
|
|
13
|
+
throw {FLOW KEYERROR} "key \"$args\" is not in the siliconcompiler configuration"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return [dict get $sc_cfg {*}$args]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
proc sc_cfg_exists { args } {
|
|
20
|
+
# Refer to global sc_cfg dictionary
|
|
21
|
+
global sc_cfg
|
|
22
|
+
|
|
23
|
+
return [dict exists $sc_cfg {*}$args]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
proc sc_top { } {
|
|
27
|
+
set sc_entrypoint [sc_cfg_get option entrypoint]
|
|
28
|
+
if { $sc_entrypoint == {{ '{}' }} } {
|
|
29
|
+
return [sc_cfg_get design]
|
|
30
|
+
}
|
|
31
|
+
return $sc_entrypoint
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Shortcut to get tool vars
|
|
35
|
+
proc sc_cfg_tool_task_get { args } {
|
|
36
|
+
set sc_step [sc_cfg_get arg step]
|
|
37
|
+
set sc_index [sc_cfg_get arg index]
|
|
38
|
+
|
|
39
|
+
set sc_flow [sc_cfg_get option flow]
|
|
40
|
+
|
|
41
|
+
set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
|
|
42
|
+
set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
|
|
43
|
+
|
|
44
|
+
return [sc_cfg_get tool $sc_tool task $sc_task {*}$args]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
proc sc_cfg_tool_task_exists { args } {
|
|
48
|
+
set sc_step [sc_cfg_get arg step]
|
|
49
|
+
set sc_index [sc_cfg_get arg index]
|
|
50
|
+
|
|
51
|
+
set sc_flow [sc_cfg_get option flow]
|
|
52
|
+
|
|
53
|
+
set sc_task [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index task]
|
|
54
|
+
set sc_tool [sc_cfg_get flowgraph $sc_flow $sc_step $sc_index tool]
|
|
55
|
+
|
|
56
|
+
return [sc_cfg_exists tool $sc_tool task $sc_task {*}$args]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# Check if an item is present in a list
|
|
60
|
+
proc sc_cfg_tool_task_check_in_list { item args } {
|
|
61
|
+
set result [sc_cfg_tool_task_get {*}$args]
|
|
62
|
+
|
|
63
|
+
if { [lsearch -exact $result $item] != -1 } {
|
|
64
|
+
return 1
|
|
65
|
+
} else {
|
|
66
|
+
return 0
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
proc sc_section_banner { text { method puts } } {
|
|
71
|
+
$method "============================================================"
|
|
72
|
+
$method "| $text"
|
|
73
|
+
$method "============================================================"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Get list of soft libraries
|
|
77
|
+
proc sc_get_libraries { { library {} } { libraries {} } } {
|
|
78
|
+
set key []
|
|
79
|
+
if { [llength $library] != 0 } {
|
|
80
|
+
lappend key library $library
|
|
81
|
+
}
|
|
82
|
+
lappend key option library
|
|
83
|
+
|
|
84
|
+
set libs []
|
|
85
|
+
foreach lib [sc_cfg_get {*}$key] {
|
|
86
|
+
if { [lsearch -exact $libs $lib] != -1 || [lsearch -exact $libraries $lib] != -1 } {
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
lappend libs $lib
|
|
91
|
+
|
|
92
|
+
foreach sublib [sc_get_libraries $lib $libs] {
|
|
93
|
+
lappend libs $sublib
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return [lsort -unique $libs]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Get list of asic libraries
|
|
101
|
+
proc sc_get_asic_libraries { type } {
|
|
102
|
+
set libs []
|
|
103
|
+
|
|
104
|
+
foreach lib [sc_cfg_get asic ${type}lib] {
|
|
105
|
+
if { [lsearch -exact $libs $lib] != -1 } {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
lappend libs $lib
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
foreach lib [sc_get_libraries] {
|
|
112
|
+
if { ![sc_cfg_exists library $lib asic ${type}lib] } {
|
|
113
|
+
continue
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
foreach sublib [sc_cfg_get library $lib asic ${type}lib] {
|
|
117
|
+
if { [lsearch -exact $libs $sublib] != -1 } {
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
lappend libs $sublib
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return $libs
|
|
126
|
+
}
|
|
@@ -555,6 +555,9 @@ def define_pad_params(chip):
|
|
|
555
555
|
|
|
556
556
|
|
|
557
557
|
def define_rsz_params(chip):
|
|
558
|
+
set_tool_task_var(chip, param_key='rsz_skip_drv_repair',
|
|
559
|
+
default_value=False,
|
|
560
|
+
schelp='skip design rule violation repair')
|
|
558
561
|
set_tool_task_var(chip, param_key='rsz_skip_setup_repair',
|
|
559
562
|
default_value=False,
|
|
560
563
|
schelp='skip setup timing repair')
|
|
@@ -15,6 +15,11 @@ source -echo "$sc_refdir/apr/preamble.tcl"
|
|
|
15
15
|
# Timing Repair
|
|
16
16
|
###############################
|
|
17
17
|
|
|
18
|
+
set parasitics_stage -placement
|
|
19
|
+
if { false } {
|
|
20
|
+
set parasitics_stage -global_routing
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
set rsz_setup_slack_margin [lindex [sc_cfg_tool_task_get {var} rsz_setup_slack_margin] 0]
|
|
19
24
|
set rsz_hold_slack_margin [lindex [sc_cfg_tool_task_get {var} rsz_hold_slack_margin] 0]
|
|
20
25
|
set rsz_slew_margin [lindex [sc_cfg_tool_task_get {var} rsz_slew_margin] 0]
|
|
@@ -30,6 +35,42 @@ if { [lindex [sc_cfg_tool_task_get {var} rsz_skip_gate_cloning] 0] == "true" } {
|
|
|
30
35
|
lappend repair_timing_args "-skip_gate_cloning"
|
|
31
36
|
}
|
|
32
37
|
|
|
38
|
+
set repair_design_args []
|
|
39
|
+
set rsz_cap_margin [lindex [sc_cfg_tool_task_get {var} rsz_cap_margin] 0]
|
|
40
|
+
if { $rsz_cap_margin != "false" } {
|
|
41
|
+
lappend repair_design_args "-cap_margin" $rsz_cap_margin
|
|
42
|
+
}
|
|
43
|
+
set rsz_slew_margin [lindex [sc_cfg_tool_task_get {var} rsz_slew_margin] 0]
|
|
44
|
+
if { $rsz_slew_margin != "false" } {
|
|
45
|
+
lappend repair_design_args "-slew_margin" $rsz_slew_margin
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
set total_insts [llength [[ord::get_db_block] getInsts]]
|
|
49
|
+
# Remove filler cells before attempting to repair timing
|
|
50
|
+
remove_fillers
|
|
51
|
+
set removed_fillers [expr { $total_insts - [llength [[ord::get_db_block] getInsts]] }]
|
|
52
|
+
|
|
53
|
+
if { [lindex [sc_cfg_tool_task_get var rsz_skip_drv_repair] 0] != "true" } {
|
|
54
|
+
###############################
|
|
55
|
+
# DRV Repair
|
|
56
|
+
###############################
|
|
57
|
+
|
|
58
|
+
# Enable ffs for resizing
|
|
59
|
+
sc_set_dont_use -scanchain -multibit -report dont_use.repair_timing.drv
|
|
60
|
+
|
|
61
|
+
estimate_parasitics $parasitics_stage
|
|
62
|
+
|
|
63
|
+
sc_report_args -command repair_design -args $repair_design_args
|
|
64
|
+
repair_design \
|
|
65
|
+
-verbose \
|
|
66
|
+
{*}$repair_design_args
|
|
67
|
+
|
|
68
|
+
sc_detailed_placement -congestion_report reports/congestion.drv.rpt
|
|
69
|
+
|
|
70
|
+
# Restore dont use
|
|
71
|
+
sc_set_dont_use
|
|
72
|
+
}
|
|
73
|
+
|
|
33
74
|
if { [lindex [sc_cfg_tool_task_get var rsz_skip_setup_repair] 0] != "true" } {
|
|
34
75
|
###############################
|
|
35
76
|
# Setup Repair
|
|
@@ -38,7 +79,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_setup_repair] 0] != "true" } {
|
|
|
38
79
|
# Enable ffs for resizing
|
|
39
80
|
sc_set_dont_use -scanchain -multibit -report dont_use.repair_timing.setup
|
|
40
81
|
|
|
41
|
-
estimate_parasitics
|
|
82
|
+
estimate_parasitics $parasitics_stage
|
|
42
83
|
|
|
43
84
|
sc_report_args -command repair_timing -args $repair_timing_args
|
|
44
85
|
repair_timing \
|
|
@@ -49,7 +90,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_setup_repair] 0] != "true" } {
|
|
|
49
90
|
-repair_tns $rsz_repair_tns \
|
|
50
91
|
{*}$repair_timing_args
|
|
51
92
|
|
|
52
|
-
sc_detailed_placement
|
|
93
|
+
sc_detailed_placement -congestion_report reports/congestion.setup_repair.rpt
|
|
53
94
|
|
|
54
95
|
# Restore dont use
|
|
55
96
|
sc_set_dont_use
|
|
@@ -60,7 +101,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_hold_repair] 0] != "true" } {
|
|
|
60
101
|
# Hold Repair
|
|
61
102
|
###############################
|
|
62
103
|
|
|
63
|
-
estimate_parasitics
|
|
104
|
+
estimate_parasitics $parasitics_stage
|
|
64
105
|
|
|
65
106
|
# Enable hold cells
|
|
66
107
|
sc_set_dont_use -hold -scanchain -multibit -report dont_use.repair_timing.hold
|
|
@@ -74,7 +115,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_hold_repair] 0] != "true" } {
|
|
|
74
115
|
-repair_tns $rsz_repair_tns \
|
|
75
116
|
{*}$repair_timing_args
|
|
76
117
|
|
|
77
|
-
sc_detailed_placement
|
|
118
|
+
sc_detailed_placement -congestion_report reports/congestion.hold_repair.rpt
|
|
78
119
|
|
|
79
120
|
# Restore dont use
|
|
80
121
|
sc_set_dont_use
|
|
@@ -85,7 +126,7 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_recover_power] 0] != "true" } {
|
|
|
85
126
|
# Recover power
|
|
86
127
|
###############################
|
|
87
128
|
|
|
88
|
-
estimate_parasitics
|
|
129
|
+
estimate_parasitics $parasitics_stage
|
|
89
130
|
|
|
90
131
|
# Enable cells
|
|
91
132
|
sc_set_dont_use -hold -scanchain -multibit -report dont_use.repair_timing.power
|
|
@@ -98,16 +139,21 @@ if { [lindex [sc_cfg_tool_task_get var rsz_skip_recover_power] 0] != "true" } {
|
|
|
98
139
|
-hold_margin $rsz_hold_slack_margin \
|
|
99
140
|
{*}$repair_timing_args
|
|
100
141
|
|
|
101
|
-
sc_detailed_placement
|
|
142
|
+
sc_detailed_placement -congestion_report reports/congestion.power_recovery.rpt
|
|
102
143
|
|
|
103
144
|
# Restore dont use
|
|
104
145
|
sc_set_dont_use
|
|
105
146
|
}
|
|
106
147
|
|
|
148
|
+
if { $removed_fillers > 0 } {
|
|
149
|
+
# Add filler cells back
|
|
150
|
+
sc_insert_fillers
|
|
151
|
+
}
|
|
152
|
+
|
|
107
153
|
global_connect
|
|
108
154
|
|
|
109
155
|
# estimate for metrics
|
|
110
|
-
estimate_parasitics
|
|
156
|
+
estimate_parasitics $parasitics_stage
|
|
111
157
|
|
|
112
158
|
###############################
|
|
113
159
|
# Task Postamble
|
|
@@ -97,7 +97,12 @@ proc sc_global_placement { args } {
|
|
|
97
97
|
# Detailed Placement
|
|
98
98
|
###########################
|
|
99
99
|
|
|
100
|
-
proc sc_detailed_placement { } {
|
|
100
|
+
proc sc_detailed_placement { args } {
|
|
101
|
+
sta::parse_key_args "sc_detailed_placement" args \
|
|
102
|
+
keys {-congestion_report} \
|
|
103
|
+
flags {}
|
|
104
|
+
sta::check_argc_eq0 "sc_detailed_placement" $args
|
|
105
|
+
|
|
101
106
|
set dpl_padding [lindex [sc_cfg_tool_task_get var pad_detail_place] 0]
|
|
102
107
|
set dpl_disallow_one_site [lindex [sc_cfg_tool_task_get var dpl_disallow_one_site] 0]
|
|
103
108
|
set dpl_max_displacement [lindex [sc_cfg_tool_task_get var dpl_max_displacement] 0]
|
|
@@ -111,10 +116,23 @@ proc sc_detailed_placement { } {
|
|
|
111
116
|
lappend dpl_args "-disallow_one_site_gaps"
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
set incremental_route false
|
|
120
|
+
|
|
121
|
+
if { $incremental_route } {
|
|
122
|
+
global_route -start_incremental
|
|
123
|
+
}
|
|
124
|
+
|
|
114
125
|
sc_report_args -command detailed_placement -args $dpl_args
|
|
126
|
+
|
|
115
127
|
detailed_placement \
|
|
116
128
|
-max_displacement $dpl_max_displacement \
|
|
117
129
|
{*}$dpl_args
|
|
130
|
+
|
|
131
|
+
if { $incremental_route } {
|
|
132
|
+
global_route -end_incremental \
|
|
133
|
+
-congestion_report_file $keys(-congestion_report)
|
|
134
|
+
}
|
|
135
|
+
|
|
118
136
|
check_placement -verbose
|
|
119
137
|
}
|
|
120
138
|
|