siliconcompiler 0.36.0__py3-none-any.whl → 0.36.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 (56) hide show
  1. siliconcompiler/_metadata.py +1 -1
  2. siliconcompiler/asic.py +4 -4
  3. siliconcompiler/design.py +6 -1
  4. siliconcompiler/package/__init__.py +3 -2
  5. siliconcompiler/project.py +30 -14
  6. siliconcompiler/schema_support/filesetschema.py +9 -1
  7. siliconcompiler/schema_support/pathschema.py +16 -10
  8. siliconcompiler/tool.py +3 -1
  9. siliconcompiler/tools/chisel/convert.py +44 -0
  10. siliconcompiler/tools/ghdl/convert.py +37 -2
  11. siliconcompiler/tools/icarus/compile.py +14 -0
  12. siliconcompiler/tools/keplerformal/lec.py +2 -2
  13. siliconcompiler/tools/klayout/drc.py +14 -0
  14. siliconcompiler/tools/klayout/export.py +41 -1
  15. siliconcompiler/tools/klayout/operations.py +40 -0
  16. siliconcompiler/tools/openroad/__init__.py +11 -0
  17. siliconcompiler/tools/openroad/_apr.py +823 -12
  18. siliconcompiler/tools/openroad/antenna_repair.py +26 -0
  19. siliconcompiler/tools/openroad/fillmetal_insertion.py +14 -0
  20. siliconcompiler/tools/openroad/global_placement.py +67 -0
  21. siliconcompiler/tools/openroad/global_route.py +15 -0
  22. siliconcompiler/tools/openroad/init_floorplan.py +14 -0
  23. siliconcompiler/tools/openroad/macro_placement.py +252 -0
  24. siliconcompiler/tools/openroad/power_grid.py +44 -1
  25. siliconcompiler/tools/openroad/rcx_bench.py +28 -0
  26. siliconcompiler/tools/openroad/rcx_extract.py +14 -0
  27. siliconcompiler/tools/openroad/rdlroute.py +14 -0
  28. siliconcompiler/tools/openroad/repair_design.py +41 -0
  29. siliconcompiler/tools/openroad/repair_timing.py +54 -0
  30. siliconcompiler/tools/openroad/screenshot.py +31 -1
  31. siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +8 -0
  32. siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +5 -1
  33. siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +17 -15
  34. siliconcompiler/tools/openroad/scripts/common/write_data_timing.tcl +3 -1
  35. siliconcompiler/tools/openroad/write_data.py +76 -0
  36. siliconcompiler/tools/opensta/timing.py +37 -2
  37. siliconcompiler/tools/slang/elaborate.py +16 -1
  38. siliconcompiler/tools/surelog/parse.py +54 -0
  39. siliconcompiler/tools/verilator/compile.py +120 -0
  40. siliconcompiler/tools/vivado/syn_fpga.py +27 -0
  41. siliconcompiler/tools/vpr/__init__.py +9 -9
  42. siliconcompiler/tools/vpr/place.py +1 -2
  43. siliconcompiler/tools/vpr/route.py +40 -0
  44. siliconcompiler/tools/xdm/convert.py +14 -0
  45. siliconcompiler/tools/xyce/simulate.py +26 -0
  46. siliconcompiler/tools/yosys/lec_asic.py +13 -0
  47. siliconcompiler/tools/yosys/syn_asic.py +336 -7
  48. siliconcompiler/tools/yosys/syn_fpga.py +39 -8
  49. siliconcompiler/toolscripts/_tools.json +5 -5
  50. siliconcompiler/utils/logging.py +6 -0
  51. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/METADATA +3 -3
  52. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/RECORD +56 -56
  53. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/WHEEL +0 -0
  54. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/entry_points.txt +0 -0
  55. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/licenses/LICENSE +0 -0
  56. {siliconcompiler-0.36.0.dist-info → siliconcompiler-0.36.2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  # Version number following semver standard.
2
- version = '0.36.0'
2
+ version = '0.36.2'
3
3
 
4
4
  # Default server address for remote runs, if unspecified.
5
5
  default_server = 'https://server.siliconcompiler.com'
siliconcompiler/asic.py CHANGED
@@ -244,7 +244,7 @@ class ASIC(Project):
244
244
  if pdk not in self.getkeys("library"):
245
245
  error = True
246
246
  self.logger.error(f"{pdk} library has not been loaded")
247
- elif not isinstance(self.get("library", pdk, field="schema"), PDK):
247
+ elif not isinstance(self.get_library(pdk), PDK):
248
248
  error = True
249
249
  self.logger.error(f"{pdk} must be a PDK")
250
250
 
@@ -432,7 +432,7 @@ class ASIC(Project):
432
432
  if not self.get("asic", "pdk") and self.get("asic", "mainlib"):
433
433
  mainlib = None
434
434
  if self._has_library(self.get("asic", "mainlib")):
435
- mainlib = self.get("library", self.get("asic", "mainlib"), field="schema")
435
+ mainlib = self.get_library(self.get("asic", "mainlib"))
436
436
  if mainlib:
437
437
  mainlib_pdk = mainlib.get("asic", "pdk")
438
438
  if mainlib_pdk:
@@ -530,7 +530,7 @@ class ASICTask(Task):
530
530
  raise ValueError("mainlib has not been defined in [asic,mainlib]")
531
531
  if mainlib not in self.project.getkeys("library"):
532
532
  raise LookupError(f"{mainlib} has not been loaded")
533
- return self.project.get("library", mainlib, field="schema")
533
+ return self.project.get_library(mainlib)
534
534
 
535
535
  @property
536
536
  def pdk(self) -> PDK:
@@ -540,7 +540,7 @@ class ASICTask(Task):
540
540
  raise ValueError("pdk has not been defined in [asic,pdk]")
541
541
  if pdk not in self.project.getkeys("library"):
542
542
  raise LookupError(f"{pdk} has not been loaded")
543
- return self.project.get("library", pdk, field="schema")
543
+ return self.project.get_library(pdk)
544
544
 
545
545
  def set_asic_var(self,
546
546
  key: str,
siliconcompiler/design.py CHANGED
@@ -694,7 +694,12 @@ class Design(DependencySchema, LibrarySchema):
694
694
  if dataroot is ...:
695
695
  dataroot = None
696
696
  else:
697
- dataroot = self._get_active_dataroot(dataroot)
697
+ if option in ['idir', 'libdir']:
698
+ try:
699
+ dataroot = self._get_active_dataroot(dataroot)
700
+ except ValueError as e:
701
+ if any(not os.path.isabs(v) for v in value):
702
+ raise e
698
703
 
699
704
  with self.active_dataroot(dataroot):
700
705
  if list in typelist and not clobber:
@@ -72,9 +72,10 @@ class Resolver:
72
72
  self.__cacheid = None
73
73
 
74
74
  if self.__root and hasattr(self.__root, "logger"):
75
- self.__logger = self.__root.logger.getChild(f"resolver-{self.name}")
75
+ rootlogger = self.__root.logger
76
76
  else:
77
- self.__logger = logging.getLogger(f"resolver-{self.name}")
77
+ rootlogger = MPManager.logger()
78
+ self.__logger = rootlogger.getChild(f"resolver-{self.name}")
78
79
 
79
80
  @staticmethod
80
81
  def populate_resolvers() -> None:
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  import os
3
- import sys
4
3
  import uuid
5
4
 
6
5
  import os.path
@@ -28,7 +27,7 @@ from siliconcompiler.schema_support.pathschema import PathSchemaBase
28
27
 
29
28
  from siliconcompiler.report.dashboard.cli import CliDashboard
30
29
  from siliconcompiler.scheduler import Scheduler, SCRuntimeError
31
- from siliconcompiler.utils.logging import SCColorLoggerFormatter, SCLoggerFormatter
30
+ from siliconcompiler.utils.logging import get_stream_handler
32
31
  from siliconcompiler.utils import get_file_ext
33
32
  from siliconcompiler.utils.multiprocessing import MPManager
34
33
  from siliconcompiler.utils.paths import jobdir, workdir
@@ -143,12 +142,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
143
142
  self.__logger = MPManager.logger().getChild(f"project_{uuid.uuid4().hex}")
144
143
  self.__logger.setLevel(logging.INFO)
145
144
 
146
- self._logger_console = logging.StreamHandler(stream=sys.stdout)
147
- if SCColorLoggerFormatter.supports_color(sys.stdout):
148
- self._logger_console.setFormatter(SCColorLoggerFormatter(SCLoggerFormatter()))
149
- else:
150
- self._logger_console.setFormatter(SCLoggerFormatter())
151
-
145
+ self._logger_console = get_stream_handler(self, in_run=False, step=None, index=None)
152
146
  self.__logger.addHandler(self._logger_console)
153
147
 
154
148
  def __init_dashboard(self):
@@ -225,7 +219,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
225
219
  if not self.valid("library", design_name):
226
220
  raise KeyError(f"{design_name} design has not been loaded")
227
221
 
228
- return self.get("library", design_name, field="schema")
222
+ return self.get_library(design_name)
229
223
 
230
224
  @property
231
225
  def option(self) -> OptionSchema:
@@ -482,7 +476,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
482
476
  if not self._has_library(src_lib):
483
477
  continue
484
478
 
485
- if not self.get("library", src_lib, field="schema").has_fileset(src_fileset):
479
+ if not self.get_library(src_lib).has_fileset(src_fileset):
486
480
  self.logger.error(f"{src_fileset} is not a valid fileset in {src_lib}")
487
481
  error = True
488
482
  continue
@@ -496,7 +490,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
496
490
  continue
497
491
 
498
492
  if dst_fileset and \
499
- not self.get("library", dst_lib, field="schema").has_fileset(dst_fileset):
493
+ not self.get_library(dst_lib).has_fileset(dst_fileset):
500
494
  self.logger.error(f"{dst_fileset} is not a valid fileset in {dst_lib}")
501
495
  error = True
502
496
  continue
@@ -715,7 +709,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
715
709
  if dst_lib:
716
710
  if not self._has_library(dst_lib):
717
711
  raise KeyError(f"{dst_lib} is not a loaded library")
718
- dst_obj = self.get("library", dst_lib, field="schema")
712
+ dst_obj = self.get_library(dst_lib)
719
713
  else:
720
714
  dst_obj = None
721
715
  if not dst_fileset:
@@ -844,7 +838,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
844
838
 
845
839
  if isinstance(src_dep, str):
846
840
  if self._has_library(src_dep):
847
- src_dep = self.get("library", src_dep, field="schema")
841
+ src_dep = self.get_library(src_dep)
848
842
  else:
849
843
  src_dep_name = src_dep
850
844
  src_dep = None
@@ -875,7 +869,7 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
875
869
  if not self._has_library(alias_dep):
876
870
  raise KeyError(f"{alias_dep} has not been loaded")
877
871
 
878
- alias_dep = self.get("library", alias_dep, field="schema")
872
+ alias_dep = self.get_library(alias_dep)
879
873
 
880
874
  if alias_dep is not None:
881
875
  if isinstance(alias_dep, Design):
@@ -894,6 +888,28 @@ class Project(PathSchemaBase, CommandLineSchema, BaseSchema):
894
888
  else:
895
889
  return self.add("option", "alias", alias)
896
890
 
891
+ def get_library(self, library: str) -> NamedSchema:
892
+ """
893
+ Retrieves a library by name from the project.
894
+
895
+ Args:
896
+ library (str): The name of the library to retrieve.
897
+
898
+ Returns:
899
+ NamedSchema: The `NamedSchema` object representing the library.
900
+
901
+ Raises:
902
+ KeyError: If the specified library is not found in the project.
903
+ TypeError: If the provided `library` is not a string.
904
+ """
905
+ if not isinstance(library, str):
906
+ raise TypeError("library must be a string")
907
+
908
+ if not self._has_library(library):
909
+ raise KeyError(f"{library} is not a valid library")
910
+
911
+ return self.get("library", library, field="schema")
912
+
897
913
  def _has_library(self, library: Union[str, NamedSchema]) -> bool:
898
914
  """
899
915
  Checks if a library with the given name exists and is loaded in the project.
@@ -1,5 +1,7 @@
1
1
  import contextlib
2
2
 
3
+ import os.path
4
+
3
5
  from pathlib import Path
4
6
 
5
7
  from typing import List, Tuple, Optional, Union, Iterable, Set
@@ -118,8 +120,14 @@ class FileSetSchema(PathSchema):
118
120
  ext = utils.get_file_ext(filename)
119
121
  filetype = utils.get_default_iomap().get(ext, ext)
120
122
 
123
+ try:
124
+ dataroot = self._get_active_dataroot(dataroot)
125
+ except ValueError as e:
126
+ if not os.path.isabs(filename):
127
+ raise e
128
+
121
129
  # adding files to dictionary
122
- with self.active_dataroot(self._get_active_dataroot(dataroot)):
130
+ with self.active_dataroot(dataroot):
123
131
  if clobber:
124
132
  return self.set('fileset', fileset, 'file', filetype, filename)
125
133
  else:
@@ -11,7 +11,9 @@ from siliconcompiler.schema.parameter import Parameter, Scope
11
11
  from siliconcompiler.schema.utils import trim
12
12
 
13
13
  from siliconcompiler.package import Resolver
14
+ from siliconcompiler.utils.logging import get_stream_handler
14
15
  from siliconcompiler.utils.paths import collectiondir, cwdirsafe
16
+ from siliconcompiler.utils.multiprocessing import MPManager
15
17
 
16
18
 
17
19
  class PathSchemaBase(BaseSchema):
@@ -19,6 +21,15 @@ class PathSchemaBase(BaseSchema):
19
21
  Schema extension to add simpler find_files and check_filepaths
20
22
  '''
21
23
 
24
+ def __getlogger(self, logger_name: str) -> logging.Logger:
25
+ schema_root = self._parent(root=True)
26
+ root_logger = getattr(schema_root, "logger", MPManager.logger())
27
+ logger = root_logger.getChild(logger_name)
28
+ if not logger.handlers:
29
+ logger.addHandler(get_stream_handler(schema_root, in_run=False, step=None, index=None))
30
+ logger.setLevel(logging.INFO)
31
+ return logger
32
+
22
33
  def find_files(self, *keypath: str,
23
34
  missing_ok: bool = False,
24
35
  step: Optional[str] = None, index: Optional[Union[int, str]] = None) \
@@ -69,13 +80,10 @@ class PathSchemaBase(BaseSchema):
69
80
  True if all file paths are valid, otherwise False.
70
81
  '''
71
82
  schema_root = self._parent(root=True)
72
- logger = getattr(schema_root,
73
- "logger",
74
- logging.getLogger("siliconcompiler.check_filepaths"))
75
83
 
76
84
  return super()._check_filepaths(
77
85
  ignore_keys=ignore_keys,
78
- logger=logger,
86
+ logger=self.__getlogger("check_filepaths"),
79
87
  collection_dir=collectiondir(schema_root),
80
88
  cwd=cwdirsafe(schema_root))
81
89
 
@@ -121,13 +129,11 @@ class PathSchemaBase(BaseSchema):
121
129
  >>> hashlist = hash_files('input', 'rtl', 'verilog')
122
130
  Computes, stores, and returns hashes of files in :keypath:`input, rtl, verilog`.
123
131
  '''
124
- schema_root = self._parent(root=True)
125
- logger = getattr(schema_root,
126
- "logger",
127
- logging.getLogger("siliconcompiler.hash_files"))
128
-
129
132
  if verbose:
130
- logger.info(f"Computing hash value for [{','.join([*self._keypath, *keypath])}]")
133
+ self.__getlogger("hash_files").info(
134
+ f"Computing hash value for [{','.join([*self._keypath, *keypath])}]")
135
+
136
+ schema_root = self._parent(root=True)
131
137
 
132
138
  hashes = super()._hash_files(*keypath,
133
139
  missing_ok=missing_ok,
siliconcompiler/tool.py CHANGED
@@ -997,7 +997,7 @@ class Task(NamedSchema, PathSchema, DocsSchema):
997
997
  open(stderr_file, 'w') as stderr_writer:
998
998
  if stderr_file == stdout_file:
999
999
  stderr_writer.close()
1000
- stderr_writer = sys.stdout
1000
+ stderr_writer = stdout_writer
1001
1001
 
1002
1002
  with contextlib.redirect_stderr(stderr_writer), \
1003
1003
  contextlib.redirect_stdout(stdout_writer):
@@ -1009,6 +1009,8 @@ class Task(NamedSchema, PathSchema, DocsSchema):
1009
1009
  finally:
1010
1010
  with sc_open(stdout_file) as stdout_reader, \
1011
1011
  sc_open(stderr_file) as stderr_reader:
1012
+ if stdout_file == stderr_file:
1013
+ stderr_reader = None
1012
1014
  read_stdio(stdout_reader, stderr_reader)
1013
1015
 
1014
1016
  if resource:
@@ -4,6 +4,8 @@ import glob
4
4
 
5
5
  import os.path
6
6
 
7
+ from typing import Optional, List, Union
8
+
7
9
  from siliconcompiler import sc_open
8
10
 
9
11
  from siliconcompiler import Task
@@ -18,6 +20,48 @@ class ConvertTask(Task):
18
20
  self.add_parameter("targetdir", "str", "Output target directory name",
19
21
  defvalue="chisel-output")
20
22
 
23
+ def set_chisel_application(self, application: str,
24
+ step: Optional[str] = None, index: Optional[str] = None) -> None:
25
+ """
26
+ Sets the application name of the chisel program.
27
+
28
+ Args:
29
+ application (str): The application name.
30
+ step (str, optional): The specific step to apply this configuration to.
31
+ index (str, optional): The specific index to apply this configuration to.
32
+ """
33
+ self.set("var", "application", application, step=step, index=index)
34
+
35
+ def add_chisel_argument(self, argument: Union[str, List[str]],
36
+ step: Optional[str] = None, index: Optional[str] = None,
37
+ clobber: bool = False) -> None:
38
+ """
39
+ Adds arguments for the chisel build.
40
+
41
+ Args:
42
+ argument (Union[str, List[str]]): The argument(s) to add.
43
+ step (str, optional): The specific step to apply this configuration to.
44
+ index (str, optional): The specific index to apply this configuration to.
45
+ clobber (bool, optional): If True, overwrites the existing list. Defaults to False.
46
+ """
47
+ if clobber:
48
+ self.set("var", "argument", argument, step=step, index=index)
49
+ else:
50
+ self.add("var", "argument", argument, step=step, index=index)
51
+
52
+ def set_chisel_targetdir(self, targetdir: str,
53
+ step: Optional[str] = None,
54
+ index: Optional[str] = None) -> None:
55
+ """
56
+ Sets the output target directory name.
57
+
58
+ Args:
59
+ targetdir (str): The target directory name.
60
+ step (str, optional): The specific step to apply this configuration to.
61
+ index (str, optional): The specific index to apply this configuration to.
62
+ """
63
+ self.set("var", "targetdir", targetdir, step=step, index=index)
64
+
21
65
  def tool(self):
22
66
  return "chisel"
23
67
 
@@ -1,3 +1,4 @@
1
+ from typing import Optional
1
2
  from siliconcompiler import Task
2
3
 
3
4
 
@@ -12,10 +13,44 @@ class ConvertTask(Task):
12
13
  self.add_parameter("use_latches", "bool", "add the --latches flag", defvalue=False)
13
14
 
14
15
  def set_usefsynopsys(self, value: bool):
15
- self.set("var", "use_fsynopsys", value)
16
+ """Deprecated: use set_ghdl_usefsynopsys instead."""
17
+ import warnings
18
+ warnings.warn("set_usefsynopsys is deprecated, use set_ghdl_usefsynopsys instead.",
19
+ DeprecationWarning, stacklevel=2)
20
+ self.set_ghdl_usefsynopsys(value)
21
+
22
+ def set_ghdl_usefsynopsys(self, value: bool,
23
+ step: Optional[str] = None,
24
+ index: Optional[str] = None):
25
+ """
26
+ Adds the -fsynopsys flag to the GHDL command.
27
+
28
+ Args:
29
+ value (bool): Whether to add the flag.
30
+ step (str, optional): The step to associate with this setting.
31
+ index (str, optional): The index to associate with this setting.
32
+ """
33
+ self.set("var", "use_fsynopsys", value, step=step, index=index)
16
34
 
17
35
  def set_uselatches(self, value: bool):
18
- self.set("var", "use_latches", value)
36
+ """Deprecated: use set_ghdl_uselatches instead."""
37
+ import warnings
38
+ warnings.warn("set_uselatches is deprecated, use set_ghdl_uselatches instead.",
39
+ DeprecationWarning, stacklevel=2)
40
+ self.set_ghdl_uselatches(value)
41
+
42
+ def set_ghdl_uselatches(self, value: bool,
43
+ step: Optional[str] = None,
44
+ index: Optional[str] = None):
45
+ """
46
+ Adds the --latches flag to the GHDL command.
47
+
48
+ Args:
49
+ value (bool): Whether to add the flag.
50
+ step (str, optional): The step to associate with this setting.
51
+ index (str, optional): The index to associate with this setting.
52
+ """
53
+ self.set("var", "use_latches", value, step=step, index=index)
19
54
 
20
55
  def tool(self):
21
56
  return "ghdl"
@@ -1,3 +1,4 @@
1
+ from typing import Optional
1
2
  from siliconcompiler import Task
2
3
 
3
4
 
@@ -14,6 +15,19 @@ class CompileTask(Task):
14
15
  'See the corresponding "-g" flags in the Icarus manual for more "'
15
16
  '"information.')
16
17
 
18
+ def set_icarus_veriloggeneration(self, gen: str,
19
+ step: Optional[str] = None,
20
+ index: Optional[str] = None):
21
+ """
22
+ Sets the Verilog language generation for Icarus.
23
+
24
+ Args:
25
+ gen (str): The Verilog generation to use.
26
+ step (str, optional): The specific step to apply this configuration to.
27
+ index (str, optional): The specific index to apply this configuration to.
28
+ """
29
+ self.set("var", "verilog_generation", gen, step=step, index=index)
30
+
17
31
  def tool(self):
18
32
  return "icarus"
19
33
 
@@ -37,7 +37,7 @@ class LECTask(Task):
37
37
  libcorners = scenario.get_libcorner(self.step, self.index)
38
38
  delay_model = self.project.get("asic", "delaymodel")
39
39
  for asiclib in self.project.get("asic", "asiclib"):
40
- lib = self.project.get("library", asiclib, field="schema")
40
+ lib = self.project.get_library(asiclib)
41
41
  for corner in libcorners:
42
42
  if not lib.valid("asic", "libcornerfileset", corner, delay_model):
43
43
  continue
@@ -64,7 +64,7 @@ class LECTask(Task):
64
64
  libcorners = scenario.get_libcorner(self.step, self.index)
65
65
  delay_model = self.project.get("asic", "delaymodel")
66
66
  for asiclib in self.project.get("asic", "asiclib"):
67
- lib = self.project.get("library", asiclib, field="schema")
67
+ lib = self.project.get_library(asiclib)
68
68
  for corner in libcorners:
69
69
  if not lib.valid("asic", "libcornerfileset", corner, delay_model):
70
70
  continue
@@ -2,6 +2,7 @@ import shlex
2
2
 
3
3
  import os.path
4
4
 
5
+ from typing import Optional
5
6
  from xml.etree import ElementTree
6
7
 
7
8
  from siliconcompiler.tools.klayout import KLayoutTask
@@ -14,6 +15,19 @@ class DRCTask(KLayoutTask):
14
15
 
15
16
  self.add_parameter("drc_name", "str", "name of the DRC deck to run")
16
17
 
18
+ def set_klayout_drcname(self, name: str,
19
+ step: Optional[str] = None,
20
+ index: Optional[str] = None):
21
+ """
22
+ Sets the name of the DRC deck to run.
23
+
24
+ Args:
25
+ name (str): The name of the DRC deck.
26
+ step (str, optional): The specific step to apply this configuration to.
27
+ index (str, optional): The specific index to apply this configuration to.
28
+ """
29
+ self.set("var", "drc_name", name, step=step, index=index)
30
+
17
31
  def task(self):
18
32
  return "drc"
19
33
 
@@ -1,3 +1,4 @@
1
+ from typing import Optional
1
2
  from siliconcompiler.tools.klayout import KLayoutTask
2
3
  from siliconcompiler.tools.klayout.screenshot import ScreenshotParams
3
4
 
@@ -13,6 +14,45 @@ class ExportTask(KLayoutTask, ScreenshotParams):
13
14
  "true/false: true will cause KLayout to generate a screenshot of "
14
15
  "the layout", defvalue=True)
15
16
 
17
+ def set_klayout_stream(self, stream: str,
18
+ step: Optional[str] = None,
19
+ index: Optional[str] = None):
20
+ """
21
+ Sets the stream format for generation.
22
+
23
+ Args:
24
+ stream (str): The stream format to use.
25
+ step (str, optional): The specific step to apply this configuration to.
26
+ index (str, optional): The specific index to apply this configuration to.
27
+ """
28
+ self.set("var", "stream", stream, step=step, index=index)
29
+
30
+ def set_klayout_timestamps(self, enable: bool,
31
+ step: Optional[str] = None,
32
+ index: Optional[str] = None):
33
+ """
34
+ Enables or disables exporting GDSII with timestamps.
35
+
36
+ Args:
37
+ enable (bool): Whether to enable timestamps.
38
+ step (str, optional): The specific step to apply this configuration to.
39
+ index (str, optional): The specific index to apply this configuration to.
40
+ """
41
+ self.set("var", "timestamps", enable, step=step, index=index)
42
+
43
+ def set_klayout_screenshot(self, enable: bool,
44
+ step: Optional[str] = None,
45
+ index: Optional[str] = None):
46
+ """
47
+ Enables or disables generating a screenshot of the layout.
48
+
49
+ Args:
50
+ enable (bool): Whether to generate a screenshot.
51
+ step (str, optional): The specific step to apply this configuration to.
52
+ index (str, optional): The specific index to apply this configuration to.
53
+ """
54
+ self.set("var", "screenshot", enable, step=step, index=index)
55
+
16
56
  def task(self):
17
57
  return "export"
18
58
 
@@ -58,7 +98,7 @@ class ExportTask(KLayoutTask, ScreenshotParams):
58
98
  lib_requires_stream = False
59
99
 
60
100
  req_set = False
61
- libobj = self.project.get("library", lib, field="schema")
101
+ libobj = self.project.get_library(lib)
62
102
  for s in sc_stream_order:
63
103
  for fileset in libobj.get("asic", "aprfileset"):
64
104
  if libobj.valid("fileset", fileset, "file", s):
@@ -1,3 +1,4 @@
1
+ from typing import Optional, List, Tuple
1
2
  from siliconcompiler.tools.klayout import KLayoutTask
2
3
 
3
4
 
@@ -15,6 +16,45 @@ class OperationsTask(KLayoutTask):
15
16
  self.add_parameter("timestamps", "bool",
16
17
  "Export GDSII with timestamps", defvalue=True)
17
18
 
19
+ def set_klayout_operations(self, operations: List[Tuple[str, str]],
20
+ step: Optional[str] = None,
21
+ index: Optional[str] = None):
22
+ """
23
+ Sets the list of operations to perform.
24
+
25
+ Args:
26
+ operations (List[Tuple[str, str]]): The list of operations.
27
+ step (str, optional): The specific step to apply this configuration to.
28
+ index (str, optional): The specific index to apply this configuration to.
29
+ """
30
+ self.set("var", "operations", operations, step=step, index=index)
31
+
32
+ def set_klayout_stream(self, stream: str,
33
+ step: Optional[str] = None,
34
+ index: Optional[str] = None):
35
+ """
36
+ Sets the stream format for generation.
37
+
38
+ Args:
39
+ stream (str): The stream format to use.
40
+ step (str, optional): The specific step to apply this configuration to.
41
+ index (str, optional): The specific index to apply this configuration to.
42
+ """
43
+ self.set("var", "stream", stream, step=step, index=index)
44
+
45
+ def set_klayout_timestamps(self, enable: bool,
46
+ step: Optional[str] = None,
47
+ index: Optional[str] = None):
48
+ """
49
+ Enables or disables exporting GDSII with timestamps.
50
+
51
+ Args:
52
+ enable (bool): Whether to enable timestamps.
53
+ step (str, optional): The specific step to apply this configuration to.
54
+ index (str, optional): The specific index to apply this configuration to.
55
+ """
56
+ self.set("var", "timestamps", enable, step=step, index=index)
57
+
18
58
  def task(self):
19
59
  return "operations"
20
60
 
@@ -51,6 +51,8 @@ class OpenROADPDK(PDK):
51
51
  "router and only uses the specified tech vias")
52
52
  self.define_tool_parameter("openroad", "drt_repair_pdn_vias", "str",
53
53
  "Via layer to repair after detailed routing")
54
+ self.define_tool_parameter("openroad", "drt_via_in_pin_layers", "(str,str)",
55
+ "Tuple of layers for vias in pin layers")
54
56
 
55
57
  def set_openroad_rclayers(self, signal: str = None, clock: str = None):
56
58
  """
@@ -155,6 +157,15 @@ class OpenROADPDK(PDK):
155
157
  """
156
158
  self.set("tool", "openroad", "drt_repair_pdn_vias", layer)
157
159
 
160
+ def set_openroad_detailedrouteviainpinlayers(self, layer1: str, layer2: str):
161
+ """Sets the via layers used in pin layers during detailed routing.
162
+
163
+ Args:
164
+ layer1 (str): The first layer for vias in pin layers.
165
+ layer2 (str): The second layer for vias in pin layers.
166
+ """
167
+ self.set("tool", "openroad", "drt_via_in_pin_layers", (layer1, layer2))
168
+
158
169
 
159
170
  class OpenROADStdCellLibrary(StdCellLibrary):
160
171
  """