siliconcompiler 0.33.1__py3-none-any.whl → 0.34.0__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 (59) hide show
  1. siliconcompiler/__init__.py +2 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/sc_issue.py +5 -3
  4. siliconcompiler/apps/sc_remote.py +0 -17
  5. siliconcompiler/apps/utils/replay.py +5 -5
  6. siliconcompiler/checklist.py +1 -1
  7. siliconcompiler/core.py +39 -48
  8. siliconcompiler/data/templates/replay/replay.sh.j2 +18 -1
  9. siliconcompiler/dependencyschema.py +392 -0
  10. siliconcompiler/design.py +664 -0
  11. siliconcompiler/flowgraph.py +32 -1
  12. siliconcompiler/metric.py +19 -0
  13. siliconcompiler/package/__init__.py +383 -223
  14. siliconcompiler/package/git.py +75 -77
  15. siliconcompiler/package/github.py +70 -97
  16. siliconcompiler/package/https.py +77 -93
  17. siliconcompiler/packageschema.py +260 -0
  18. siliconcompiler/pdk.py +2 -2
  19. siliconcompiler/record.py +57 -5
  20. siliconcompiler/remote/client.py +61 -13
  21. siliconcompiler/remote/server.py +109 -64
  22. siliconcompiler/report/dashboard/cli/board.py +1 -2
  23. siliconcompiler/scheduler/__init__.py +3 -1375
  24. siliconcompiler/scheduler/docker.py +268 -0
  25. siliconcompiler/scheduler/run_node.py +20 -19
  26. siliconcompiler/scheduler/scheduler.py +308 -0
  27. siliconcompiler/scheduler/schedulernode.py +934 -0
  28. siliconcompiler/scheduler/slurm.py +147 -163
  29. siliconcompiler/scheduler/taskscheduler.py +39 -52
  30. siliconcompiler/schema/__init__.py +3 -3
  31. siliconcompiler/schema/baseschema.py +256 -11
  32. siliconcompiler/schema/editableschema.py +4 -0
  33. siliconcompiler/schema/journal.py +210 -0
  34. siliconcompiler/schema/namedschema.py +31 -2
  35. siliconcompiler/schema/parameter.py +14 -1
  36. siliconcompiler/schema/parametervalue.py +1 -34
  37. siliconcompiler/schema/schema_cfg.py +211 -350
  38. siliconcompiler/tool.py +139 -37
  39. siliconcompiler/tools/_common/__init__.py +14 -11
  40. siliconcompiler/tools/builtin/concatenate.py +2 -2
  41. siliconcompiler/tools/builtin/verify.py +1 -2
  42. siliconcompiler/tools/openroad/scripts/common/procs.tcl +27 -25
  43. siliconcompiler/tools/slang/__init__.py +3 -2
  44. siliconcompiler/tools/vpr/route.py +69 -0
  45. siliconcompiler/tools/yosys/sc_synth_asic.tcl +0 -4
  46. siliconcompiler/toolscripts/_tools.json +13 -8
  47. siliconcompiler/toolscripts/ubuntu22/install-klayout.sh +4 -0
  48. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +4 -0
  49. siliconcompiler/utils/__init__.py +2 -23
  50. siliconcompiler/utils/flowgraph.py +5 -5
  51. siliconcompiler/utils/logging.py +2 -1
  52. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/METADATA +8 -6
  53. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/RECORD +57 -52
  54. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/WHEEL +1 -1
  55. siliconcompiler/scheduler/docker_runner.py +0 -254
  56. siliconcompiler/schema/journalingschema.py +0 -238
  57. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/entry_points.txt +0 -0
  58. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/licenses/LICENSE +0 -0
  59. {siliconcompiler-0.33.1.dist-info → siliconcompiler-0.34.0.dist-info}/top_level.txt +0 -0
siliconcompiler/tool.py CHANGED
@@ -61,11 +61,35 @@ class TaskExecutableNotFound(TaskError):
61
61
 
62
62
 
63
63
  class TaskSchema(NamedSchema):
64
- def __init__(self, name=None):
65
- super().__init__(name=name)
64
+ def __init__(self, name):
65
+ super().__init__(name)
66
66
 
67
67
  schema_task(self)
68
68
 
69
+ def add_parameter(self, name, type, help, defvalue=None):
70
+ '''
71
+ Adds a parameter to the task definition.
72
+
73
+ Args:
74
+ name (str): name of parameter
75
+ type (str): schema type of the parameter
76
+ help (str): help string for this parameter
77
+ defvalue (any): default value for the parameter
78
+ '''
79
+ help = trim(help)
80
+ param = Parameter(
81
+ type,
82
+ defvalue=defvalue,
83
+ scope=Scope.JOB,
84
+ pernode=PerNode.OPTIONAL,
85
+ shorthelp=help,
86
+ help=help
87
+ )
88
+
89
+ EditableSchema(self).insert("var", name, param)
90
+
91
+ return param
92
+
69
93
 
70
94
  class ToolSchema(NamedSchema):
71
95
  __parse_version_check_str = r"""
@@ -83,13 +107,13 @@ class ToolSchema(NamedSchema):
83
107
  r"^\s*" + __parse_version_check_str + r"\s*$",
84
108
  re.VERBOSE | re.IGNORECASE)
85
109
 
86
- def __init__(self, name=None):
87
- super().__init__(name=name)
110
+ def __init__(self, name):
111
+ super().__init__(name)
88
112
 
89
113
  schema_tool(self)
90
114
 
91
115
  schema = EditableSchema(self)
92
- schema.insert("task", "default", TaskSchema())
116
+ schema.insert("task", "default", TaskSchema(None))
93
117
 
94
118
  self.set_runtime(None)
95
119
 
@@ -144,6 +168,14 @@ class ToolSchema(NamedSchema):
144
168
 
145
169
  return self.__step, self.__index
146
170
 
171
+ def tool(self):
172
+ '''
173
+ Returns:
174
+ task name
175
+ '''
176
+
177
+ return self.__tool
178
+
147
179
  def task(self):
148
180
  '''
149
181
  Returns:
@@ -351,13 +383,14 @@ class ToolSchema(NamedSchema):
351
383
  envvars[lic_env] = ':'.join(license_file)
352
384
 
353
385
  if include_path:
354
- path_param = self.get('path', field=None, step=self.__step, index=self.__index)
355
- if path_param.get(field='package'):
356
- raise NotImplementedError
386
+ path = self.find_files(
387
+ "path", step=self.__step, index=self.__index,
388
+ packages=self.__chip.get("package", field="schema").get_resolvers(),
389
+ cwd=self.__chip.cwd,
390
+ missing_ok=True)
357
391
 
358
392
  envvars["PATH"] = os.getenv("PATH", os.defpath)
359
393
 
360
- path = path_param.get(field=None).resolve_path() # TODO: needs package search
361
394
  if path:
362
395
  envvars["PATH"] = path + os.pathsep + envvars["PATH"]
363
396
 
@@ -383,15 +416,6 @@ class ToolSchema(NamedSchema):
383
416
  '''
384
417
 
385
418
  cmdargs = []
386
- cmdargs.extend(self.get('task', self.__task, 'option',
387
- step=self.__step, index=self.__index))
388
-
389
- # Add scripts files / TODO:
390
- scripts = self.__chip.find_files('tool', self.__tool, 'task', self.__task, 'script',
391
- step=self.__step, index=self.__index)
392
-
393
- cmdargs.extend(scripts)
394
-
395
419
  try:
396
420
  cmdargs.extend(self.runtime_options())
397
421
  except Exception as e:
@@ -417,6 +441,10 @@ class ToolSchema(NamedSchema):
417
441
  replay_opts["exports"] = self.get_runtime_environmental_variables(include_path=include_path)
418
442
 
419
443
  replay_opts["executable"] = self.get('exe')
444
+ replay_opts["step"] = self.__step
445
+ replay_opts["index"] = self.__index
446
+ replay_opts["cfg_file"] = f"inputs/{self.__chip.design}.pkg.json"
447
+ replay_opts["node_only"] = 0 if replay_opts["executable"] else 1
420
448
 
421
449
  vswitch = self.get('vswitch')
422
450
  if vswitch:
@@ -428,23 +456,25 @@ class ToolSchema(NamedSchema):
428
456
  # detect file paths
429
457
  file_test = re.compile(r'^[/\.]')
430
458
 
431
- format_cmd = [replay_opts["executable"]]
459
+ if replay_opts["executable"]:
460
+ format_cmd = [replay_opts["executable"]]
432
461
 
433
- for cmdarg in self.get_runtime_arguments():
434
- add_new_line = len(format_cmd) == 1
462
+ for cmdarg in self.get_runtime_arguments():
463
+ add_new_line = len(format_cmd) == 1
435
464
 
436
- if arg_test.match(cmdarg) or file_test.match(cmdarg):
437
- add_new_line = True
438
- else:
439
- if not arg_test.match(format_cmd[-1]):
465
+ if arg_test.match(cmdarg) or file_test.match(cmdarg):
440
466
  add_new_line = True
467
+ else:
468
+ if not arg_test.match(format_cmd[-1]):
469
+ add_new_line = True
441
470
 
442
- cmdarg = shlex.quote(cmdarg)
443
- if add_new_line:
444
- format_cmd.append(cmdarg)
445
- else:
446
- format_cmd[-1] += f' {cmdarg}'
447
-
471
+ cmdarg = shlex.quote(cmdarg)
472
+ if add_new_line:
473
+ format_cmd.append(cmdarg)
474
+ else:
475
+ format_cmd[-1] += f' {cmdarg}'
476
+ else:
477
+ format_cmd = []
448
478
  replay_opts["cmds"] = format_cmd
449
479
 
450
480
  # create replay file
@@ -812,7 +842,17 @@ class ToolSchema(NamedSchema):
812
842
  pass
813
843
 
814
844
  def runtime_options(self):
815
- return []
845
+ cmdargs = []
846
+ cmdargs.extend(self.get('task', self.__task, 'option',
847
+ step=self.__step, index=self.__index))
848
+
849
+ # Add scripts files / TODO:
850
+ scripts = self.__chip.find_files('tool', self.__tool, 'task', self.__task, 'script',
851
+ step=self.__step, index=self.__index)
852
+
853
+ cmdargs.extend(scripts)
854
+
855
+ return cmdargs
816
856
 
817
857
  def run(self):
818
858
  raise NotImplementedError("must be implemented by the implementation class")
@@ -825,6 +865,9 @@ class ToolSchema(NamedSchema):
825
865
  # Migration helper
826
866
  ###########################################################################
827
867
  class ToolSchemaTmp(ToolSchema):
868
+ def __init__(self):
869
+ super().__init__(None)
870
+
828
871
  def __module_func(self, name, modules):
829
872
  for module in modules:
830
873
  method = getattr(module, name, None)
@@ -860,32 +903,76 @@ class ToolSchemaTmp(ToolSchema):
860
903
  return method(version)
861
904
  return ToolSchema.normalize_version(self, version)
862
905
 
906
+ def generate_replay_script(self, filepath, workdir, include_path=True):
907
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
908
+ self._ToolSchema__chip.get('arg', 'index')
909
+ step, index = self.node()
910
+ self._ToolSchema__chip.set('arg', 'step', step)
911
+ self._ToolSchema__chip.set('arg', 'index', index)
912
+ ret = ToolSchema.generate_replay_script(self, filepath, workdir, include_path=include_path)
913
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
914
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
915
+ return ret
916
+
863
917
  def setup(self):
864
918
  _, task = self.__tool_task_modules()
865
919
  method = self.__module_func("setup", [task])
866
920
  if method:
867
- return method(self._ToolSchema__chip)
921
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
922
+ self._ToolSchema__chip.get('arg', 'index')
923
+ step, index = self.node()
924
+ self._ToolSchema__chip.set('arg', 'step', step)
925
+ self._ToolSchema__chip.set('arg', 'index', index)
926
+ ret = method(self._ToolSchema__chip)
927
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
928
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
929
+ return ret
868
930
  return ToolSchema.setup(self)
869
931
 
870
932
  def select_input_nodes(self):
871
933
  _, task = self.__tool_task_modules()
872
934
  method = self.__module_func("_select_inputs", [task])
873
935
  if method:
874
- return method(self._ToolSchema__chip, *self.node())
936
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
937
+ self._ToolSchema__chip.get('arg', 'index')
938
+ step, index = self.node()
939
+ self._ToolSchema__chip.set('arg', 'step', step)
940
+ self._ToolSchema__chip.set('arg', 'index', index)
941
+ ret = method(self._ToolSchema__chip, *self.node())
942
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
943
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
944
+ return ret
875
945
  return ToolSchema.select_input_nodes(self)
876
946
 
877
947
  def pre_process(self):
878
948
  _, task = self.__tool_task_modules()
879
949
  method = self.__module_func("pre_process", [task])
880
950
  if method:
881
- return method(self._ToolSchema__chip)
951
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
952
+ self._ToolSchema__chip.get('arg', 'index')
953
+ step, index = self.node()
954
+ self._ToolSchema__chip.set('arg', 'step', step)
955
+ self._ToolSchema__chip.set('arg', 'index', index)
956
+ ret = method(self._ToolSchema__chip)
957
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
958
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
959
+ return ret
882
960
  return ToolSchema.pre_process(self)
883
961
 
884
962
  def runtime_options(self):
885
963
  tool, task = self.__tool_task_modules()
886
964
  method = self.__module_func("runtime_options", [task, tool])
887
965
  if method:
888
- return method(self._ToolSchema__chip)
966
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
967
+ self._ToolSchema__chip.get('arg', 'index')
968
+ step, index = self.node()
969
+ self._ToolSchema__chip.set('arg', 'step', step)
970
+ self._ToolSchema__chip.set('arg', 'index', index)
971
+ ret = ToolSchema.runtime_options(self)
972
+ ret.extend(method(self._ToolSchema__chip))
973
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
974
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
975
+ return ret
889
976
  return ToolSchema.runtime_options(self)
890
977
 
891
978
  def run(self):
@@ -898,7 +985,14 @@ class ToolSchemaTmp(ToolSchema):
898
985
  if self._ToolSchema__chip.get('option', 'quiet', step=step, index=index):
899
986
  self._ToolSchema__chip.logger._console.setLevel(logging.CRITICAL)
900
987
 
988
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
989
+ self._ToolSchema__chip.get('arg', 'index')
990
+ step, index = self.node()
991
+ self._ToolSchema__chip.set('arg', 'step', step)
992
+ self._ToolSchema__chip.set('arg', 'index', index)
901
993
  retcode = method(self._ToolSchema__chip)
994
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
995
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
902
996
 
903
997
  self._ToolSchema__chip.logger._console.setLevel(stdout_handler_level)
904
998
 
@@ -909,7 +1003,15 @@ class ToolSchemaTmp(ToolSchema):
909
1003
  _, task = self.__tool_task_modules()
910
1004
  method = self.__module_func("post_process", [task])
911
1005
  if method:
912
- return method(self._ToolSchema__chip)
1006
+ prev_step, prev_index = self._ToolSchema__chip.get('arg', 'step'), \
1007
+ self._ToolSchema__chip.get('arg', 'index')
1008
+ step, index = self.node()
1009
+ self._ToolSchema__chip.set('arg', 'step', step)
1010
+ self._ToolSchema__chip.set('arg', 'index', index)
1011
+ ret = method(self._ToolSchema__chip)
1012
+ self._ToolSchema__chip.set('arg', 'step', prev_step)
1013
+ self._ToolSchema__chip.set('arg', 'index', prev_index)
1014
+ return ret
913
1015
  return ToolSchema.post_process(self)
914
1016
 
915
1017
 
@@ -377,17 +377,20 @@ def input_file_node_name(filename, step, index):
377
377
 
378
378
  file_type = get_file_ext(filename)
379
379
 
380
- base = filename
381
- total_ext = []
382
- ext = None
383
- while ext != file_type:
384
- base, ext = os.path.splitext(base)
385
- ext = ext[1:].lower()
386
- total_ext.append(ext)
387
-
388
- total_ext.reverse()
389
-
390
- return f'{base}.{step}{index}.{".".join(total_ext)}'
380
+ if file_type:
381
+ base = filename
382
+ ext = None
383
+ total_ext = []
384
+ while ext != file_type:
385
+ base, ext = os.path.splitext(base)
386
+ ext = ext[1:].lower()
387
+ total_ext.append(ext)
388
+
389
+ total_ext.reverse()
390
+
391
+ return f'{base}.{step}{index}.{".".join(total_ext)}'
392
+ else:
393
+ return f'{filename}.{step}{index}'
391
394
 
392
395
 
393
396
  def add_common_file(chip, key, file):
@@ -3,7 +3,7 @@ import os
3
3
  from siliconcompiler import sc_open, SiliconCompilerError
4
4
  from siliconcompiler import utils
5
5
  from siliconcompiler.tools._common import input_provides, input_file_node_name, get_tool_task
6
- from siliconcompiler import scheduler
6
+ from siliconcompiler.scheduler.schedulernode import SchedulerNode
7
7
 
8
8
 
9
9
  def make_docs(chip):
@@ -12,7 +12,7 @@ def make_docs(chip):
12
12
  chip.set('option', 'flow', 'asicflow')
13
13
 
14
14
  for step, index in chip.schema.get("flowgraph", "asicflow", field="schema").get_entry_nodes():
15
- scheduler._setup_node(chip, step, index)
15
+ SchedulerNode(chip, step, index).setup()
16
16
 
17
17
  chip.set('arg', 'step', 'import.combine')
18
18
  chip.set('arg', 'index', '0')
@@ -1,6 +1,5 @@
1
1
  from siliconcompiler.tools.builtin import _common
2
2
  from siliconcompiler.schema.parametertype import NodeType
3
- from siliconcompiler.scheduler import _haltstep
4
3
  from siliconcompiler.tools.builtin.builtin import set_io_files
5
4
  from siliconcompiler import utils, SiliconCompilerError
6
5
  from siliconcompiler.tools._common import get_tool_task
@@ -59,7 +58,7 @@ def _select_inputs(chip, step, index):
59
58
  chip.error(f"{step}{index} fails '{metric}' metric: {value}{op}{goal}")
60
59
 
61
60
  if not passes:
62
- _haltstep(chip, flow, step, index)
61
+ return []
63
62
 
64
63
  return inputs
65
64
 
@@ -634,36 +634,38 @@ proc sc_setup_sta { } {
634
634
  set_timing_derate -late $sta_late_timing_derate
635
635
  }
636
636
 
637
- # Create path groups
638
- if {
639
- [lindex [sc_cfg_tool_task_get var sta_define_path_groups] 0] == "true" &&
640
- [llength [sta::path_group_names]] == 0
641
- } {
642
- sc_path_group -name in2out -from [all_inputs -no_clocks] -to [all_outputs]
643
-
637
+ if { [sc_check_version 19370] } {
638
+ # Create path groups
644
639
  if {
645
- [llength [all_clocks]] == 1 ||
646
- [lindex [sc_cfg_tool_task_get var sta_unique_path_groups_per_clock] 0] == "false"
640
+ [lindex [sc_cfg_tool_task_get var sta_define_path_groups] 0] == "true" &&
641
+ [llength [sta::path_group_names]] == 0
647
642
  } {
648
- sc_path_group -name in2reg -from [all_inputs -no_clocks] -to [all_registers]
649
- sc_path_group -name reg2reg -from [all_registers] -to [all_registers]
650
- sc_path_group -name reg2out -from [all_registers] -to [all_outputs]
651
- } else {
652
- foreach clock [all_clocks] {
653
- set clk_name [get_property $clock name]
654
- sc_path_group -name in2reg.${clk_name} \
655
- -from [all_inputs -no_clocks] \
656
- -to [all_registers -clock $clock]
657
- sc_path_group -name reg2reg.${clk_name} \
658
- -from [all_registers -clock $clock] \
659
- -to [all_registers -clock $clock]
660
- sc_path_group -name reg2out.${clk_name} \
661
- -from [all_registers -clock $clock] \
662
- -to [all_outputs]
643
+ sc_path_group -name in2out -from [all_inputs -no_clocks] -to [all_outputs]
644
+
645
+ if {
646
+ [llength [all_clocks]] == 1 ||
647
+ [lindex [sc_cfg_tool_task_get var sta_unique_path_groups_per_clock] 0] == "false"
648
+ } {
649
+ sc_path_group -name in2reg -from [all_inputs -no_clocks] -to [all_registers]
650
+ sc_path_group -name reg2reg -from [all_registers] -to [all_registers]
651
+ sc_path_group -name reg2out -from [all_registers] -to [all_outputs]
652
+ } else {
653
+ foreach clock [all_clocks] {
654
+ set clk_name [get_property $clock name]
655
+ sc_path_group -name in2reg.${clk_name} \
656
+ -from [all_inputs -no_clocks] \
657
+ -to [all_registers -clock $clock]
658
+ sc_path_group -name reg2reg.${clk_name} \
659
+ -from [all_registers -clock $clock] \
660
+ -to [all_registers -clock $clock]
661
+ sc_path_group -name reg2out.${clk_name} \
662
+ -from [all_registers -clock $clock] \
663
+ -to [all_outputs]
664
+ }
663
665
  }
664
666
  }
667
+ utl::info FLW 1 "Timing path groups: [sta::path_group_names]"
665
668
  }
666
- utl::info FLW 1 "Timing path groups: [sta::path_group_names]"
667
669
 
668
670
  # Check timing setup
669
671
  if { [sc_cfg_tool_task_check_in_list check_setup var reports] } {
@@ -11,6 +11,7 @@ Sources: https://github.com/MikePopoloski/slang
11
11
  Installation: https://sv-lang.com/building.html
12
12
  '''
13
13
  import os
14
+ import shlex
14
15
 
15
16
  try:
16
17
  import pyslang
@@ -121,7 +122,6 @@ def common_runtime_options(chip):
121
122
  ###############################
122
123
  # Set up user-provided parameters to ensure we elaborate the correct modules
123
124
  for param, value in opts['param']:
124
- value = value.replace('"', '\\"')
125
125
  options.extend(['-G', f'{param}={value}'])
126
126
 
127
127
  return options
@@ -135,7 +135,8 @@ def _get_driver(chip, options_func, ignored_diagnotics=None):
135
135
 
136
136
  parse_options = pyslang.CommandLineOptions()
137
137
  parse_options.ignoreProgramName = True
138
- opts = " ".join(options)
138
+ opts = shlex.join(options)
139
+ chip.logger.info(f"runtime arguments: {opts}")
139
140
  code = 0
140
141
  if not driver.parseCommandLine(opts, parse_options):
141
142
  code = 1
@@ -44,6 +44,45 @@ def setup(chip, clobber=True):
44
44
  chip.add('tool', tool, 'task', task, 'output', design + '.net', step=step, index=index)
45
45
  chip.add('tool', tool, 'task', task, 'output', design + '.place', step=step, index=index)
46
46
 
47
+ # Add a parameter for generating a post-implementation netlist for external
48
+ # static timing analysis.
49
+ chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
50
+ False, step=step, index=index, clobber=False)
51
+
52
+ chip.set('tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist',
53
+ 'set to true to have VPR generate a post-implementation netlist',
54
+ field='help')
55
+
56
+ chip.set('tool', tool, 'task', task, 'require',
57
+ ",".join(['tool', tool, 'task', task, 'var', 'gen_post_implementation_netlist']),
58
+ step=step, index=index)
59
+
60
+ # Add a parameter to control the timing corner used when generating SDF files.
61
+ chip.set('tool', tool, 'task', task, 'var', 'timing_corner', 'typical',
62
+ step=step, index=index, clobber=False)
63
+
64
+ chip.set('tool', tool, 'task', task, 'var', 'timing_corner',
65
+ 'set the timing corner for files generated by the post-implementation netlist',
66
+ field='help')
67
+
68
+ chip.set('tool', tool, 'task', task, 'require',
69
+ ",".join(['tool', tool, 'task', task, 'var', 'timing_corner']),
70
+ step=step, index=index)
71
+
72
+ # Add the post-implementation timing netlist outputs if requested.
73
+ gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
74
+ 'gen_post_implementation_netlist',
75
+ step=step, index=index)[0]
76
+ timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
77
+ step=step, index=index)[0]
78
+ if gen_post_implementation_netlist == 'true':
79
+ chip.add('tool', tool, 'task', task, 'output', f'{design}.vg',
80
+ step=step, index=index)
81
+ chip.add('tool', tool, 'task', task, 'output', f'{design}.sdc',
82
+ step=step, index=index)
83
+ chip.add('tool', tool, 'task', task, 'output', f'{design}.{timing_corner}.sdf',
84
+ step=step, index=index)
85
+
47
86
 
48
87
  def runtime_options(chip):
49
88
  '''Command line options to vpr for the route step
@@ -104,6 +143,21 @@ def runtime_options(chip):
104
143
  options.append("--graphics_commands")
105
144
  options.append(graphics_command_str)
106
145
 
146
+ # Generate a post-implementation netlist for use in external timing analysis
147
+ # if requested.
148
+ gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
149
+ 'gen_post_implementation_netlist',
150
+ step=step, index=index)[0]
151
+ if gen_post_implementation_netlist == 'true':
152
+ # Generate the netlist.
153
+ options.extend(["--gen_post_synthesis_netlist", "on"])
154
+ # Generate the SDC file.
155
+ options.extend(["--gen_post_implementation_sdc", "on"])
156
+ # Create undriven nets for unconnected inputs.
157
+ options.extend(["--post_synth_netlist_unconn_inputs", "nets"])
158
+ # Turn off module parameters.
159
+ options.extend(["--post_synth_netlist_module_parameters", "off"])
160
+
107
161
  return options
108
162
 
109
163
 
@@ -122,3 +176,18 @@ def post_process(chip):
122
176
  shutil.copy2(f'inputs/{design}.blif', 'outputs')
123
177
  shutil.copy2(f'inputs/{design}.net', 'outputs')
124
178
  shutil.copy2(f'inputs/{design}.place', 'outputs')
179
+
180
+ # Copy and rename the post-implementation netlist results into the output
181
+ # directory to be used in external timing analysis.
182
+ step = chip.get('arg', 'step')
183
+ index = chip.get('arg', 'index')
184
+ tool, task = get_tool_task(chip, step, index)
185
+ gen_post_implementation_netlist = chip.get('tool', tool, 'task', task, 'var',
186
+ 'gen_post_implementation_netlist',
187
+ step=step, index=index)[0]
188
+ timing_corner = chip.get('tool', tool, 'task', task, 'var', 'timing_corner',
189
+ step=step, index=index)[0]
190
+ if gen_post_implementation_netlist == 'true':
191
+ shutil.move(f'{design}_post_synthesis.v', f'outputs/{design}.vg')
192
+ shutil.move(f'{design}_post_synthesis.sdc', f'outputs/{design}.sdc')
193
+ shutil.move(f'{design}_post_synthesis.sdf', f'outputs/{design}.{timing_corner}.sdf')
@@ -120,10 +120,6 @@ if { [lindex [sc_cfg_tool_task_get var use_slang] 0] == "true" && [sc_load_plugi
120
120
  set slang_params []
121
121
  if { [sc_cfg_exists option param] } {
122
122
  dict for {key value} [sc_cfg_get option param] {
123
- if { ![string is integer $value] } {
124
- set value [concat \"$value\"]
125
- }
126
-
127
123
  lappend slang_params -G "${key}=${value}"
128
124
  }
129
125
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "openroad": {
3
3
  "git-url": "https://github.com/The-OpenROAD-Project/OpenROAD.git",
4
- "git-commit": "b0107893ea0693f3cf09bbf95450a38c1b26b950",
4
+ "git-commit": "4b729ea474e9bd0a3513579b41a8c96fe20dc75e",
5
5
  "docker-cmds": [
6
6
  "# Remove OR-Tools files",
7
7
  "RUN rm -f $SC_PREFIX/Makefile $SC_PREFIX/README.md",
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "opensta": {
19
19
  "git-url": "https://github.com/parallaxsw/OpenSTA.git",
20
- "git-commit": "71bdfb99049f33a010bb23527c5c921c925378a0",
20
+ "git-commit": "343b93b6336962b2dbcc5b7c7500c01df0367696",
21
21
  "auto-update": true
22
22
  },
23
23
  "netgen": {
@@ -41,12 +41,17 @@
41
41
  "auto-update": false
42
42
  },
43
43
  "klayout": {
44
- "version": "0.30.1",
44
+ "version": "0.30.2",
45
45
  "git-url": "https://github.com/KLayout/klayout.git",
46
- "docker-skip": true,
47
46
  "auto-update": true,
48
47
  "run-version": "source version.sh && echo $KLAYOUT_VERSION",
49
- "release-notes": "https://www.klayout.de/development.html"
48
+ "release-notes": "https://www.klayout.de/development.html",
49
+ "docker-cmds": [
50
+ "RUN echo \"#!/bin/bash\" > $SC_PREFIX/install-klayout.sh",
51
+ "RUN echo \"sudo apt-get install -y $SC_PREFIX/klayout.deb\" >> $SC_PREFIX/install-klayout.sh",
52
+ "RUN echo \"sudo rm $SC_PREFIX/klayout.deb\" >> $SC_PREFIX/install-klayout.sh",
53
+ "RUN chmod +x $SC_PREFIX/install-klayout.sh"
54
+ ]
50
55
  },
51
56
  "sv2v": {
52
57
  "git-url": "https://github.com/zachjs/sv2v.git",
@@ -96,7 +101,7 @@
96
101
  },
97
102
  "yosys": {
98
103
  "git-url": "https://github.com/YosysHQ/yosys.git",
99
- "git-commit": "v0.53",
104
+ "git-commit": "v0.54",
100
105
  "version-prefix": "",
101
106
  "auto-update": true
102
107
  },
@@ -135,7 +140,7 @@
135
140
  "auto-update": false
136
141
  },
137
142
  "slang": {
138
- "git-commit": "v8.0",
143
+ "git-commit": "v8.1",
139
144
  "git-url": "https://github.com/MikePopoloski/slang.git",
140
145
  "auto-update": true
141
146
  },
@@ -146,7 +151,7 @@
146
151
  },
147
152
  "yosys-slang": {
148
153
  "git-url": "https://github.com/povik/yosys-slang.git",
149
- "git-commit": "34753c07b7bd285b784b3a2c756cfac56e1a26ab",
154
+ "git-commit": "e863336db656b1f0ec82f7af65249b6a4ee3e56c",
150
155
  "docker-depends": "yosys",
151
156
  "auto-update": true
152
157
  },
@@ -35,4 +35,8 @@ wget -O klayout.deb $url
35
35
  # Install package
36
36
  sudo apt-get install -y ./klayout.deb
37
37
 
38
+ if [ ! -z ${SC_PREFIX+x} ]; then
39
+ sudo cp ./klayout.deb "${SC_PREFIX}/"
40
+ fi
41
+
38
42
  cd -
@@ -37,4 +37,8 @@ wget -O klayout.deb $url
37
37
  # Install package
38
38
  sudo apt-get install -y ./klayout.deb
39
39
 
40
+ if [ ! -z ${SC_PREFIX+x} ]; then
41
+ sudo cp ./klayout.deb "${SC_PREFIX}/"
42
+ fi
43
+
40
44
  cd -