lambdapdk 0.2.6__tar.gz → 0.2.7__tar.gz

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 (41) hide show
  1. {lambdapdk-0.2.6/lambdapdk.egg-info → lambdapdk-0.2.7}/PKG-INFO +4 -4
  2. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/__init__.py +1 -1
  3. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/asap7/libs/fakeram7.py +125 -4
  4. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/freepdk45/libs/fakeram45.py +79 -2
  5. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/gf180/libs/gf180sram.py +80 -2
  6. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/ihp130/__init__.py +5 -6
  7. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/ihp130/libs/sg13g2_sram.py +90 -2
  8. lambdapdk-0.2.7/lambdapdk/sky130/libs/sky130sram.py +141 -0
  9. lambdapdk-0.2.7/lambdapdk/utils.py +16 -0
  10. {lambdapdk-0.2.6 → lambdapdk-0.2.7/lambdapdk.egg-info}/PKG-INFO +4 -4
  11. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk.egg-info/SOURCES.txt +1 -0
  12. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk.egg-info/requires.txt +3 -3
  13. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/pyproject.toml +3 -3
  14. lambdapdk-0.2.6/lambdapdk/sky130/libs/sky130sram.py +0 -60
  15. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/LICENSE +0 -0
  16. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/MANIFEST.in +0 -0
  17. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/README.md +0 -0
  18. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/asap7/__init__.py +0 -0
  19. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/asap7/libs/asap7sc7p5t.py +0 -0
  20. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/asap7/libs/fakeio7.py +0 -0
  21. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/asap7/libs/fakekit7.py +0 -0
  22. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/freepdk45/__init__.py +0 -0
  23. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/freepdk45/libs/nangate45.py +0 -0
  24. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/gf180/__init__.py +0 -0
  25. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/gf180/libs/gf180io.py +0 -0
  26. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/gf180/libs/gf180mcu.py +0 -0
  27. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/ihp130/libs/sg13g2_io.py +0 -0
  28. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/ihp130/libs/sg13g2_stdcell.py +0 -0
  29. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/interposer/__init__.py +0 -0
  30. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/interposer/_generator.py +0 -0
  31. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/interposer/libs/bumps.py +0 -0
  32. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/sky130/__init__.py +0 -0
  33. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/sky130/libs/sky130io.py +0 -0
  34. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk/sky130/libs/sky130sc.py +0 -0
  35. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk.egg-info/dependency_links.txt +0 -0
  36. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk.egg-info/entry_points.txt +0 -0
  37. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/lambdapdk.egg-info/top_level.txt +0 -0
  38. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/setup.cfg +0 -0
  39. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/tests/test_getters.py +0 -0
  40. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/tests/test_lambda.py +0 -0
  41. {lambdapdk-0.2.6 → lambdapdk-0.2.7}/tests/test_paths.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambdapdk
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Library of open source Process Design Kits
5
5
  Author: Zero ASIC
6
6
  License: Apache License
@@ -199,12 +199,12 @@ Requires-Python: >=3.8
199
199
  Description-Content-Type: text/markdown
200
200
  License-File: LICENSE
201
201
  Requires-Dist: siliconcompiler>=0.35.0
202
- Requires-Dist: lambdalib>=0.5.0
202
+ Requires-Dist: lambdalib>=0.7.0
203
203
  Provides-Extra: test
204
204
  Requires-Dist: flake8==7.3.0; extra == "test"
205
- Requires-Dist: pytest==8.4.2; extra == "test"
205
+ Requires-Dist: pytest==9.0.2; extra == "test"
206
206
  Requires-Dist: pytest-timeout==2.4.0; extra == "test"
207
- Requires-Dist: tclint==0.6.2; extra == "test"
207
+ Requires-Dist: tclint==0.7.0; extra == "test"
208
208
  Requires-Dist: sc-leflib==0.5.1; extra == "test"
209
209
  Requires-Dist: Jinja2==3.1.6; extra == "test"
210
210
  Dynamic: license-file
@@ -11,7 +11,7 @@ from siliconcompiler.tools.openroad import OpenROADStdCellLibrary
11
11
  from siliconcompiler.tools.bambu import BambuStdCellLibrary
12
12
  from siliconcompiler.tools.klayout import KLayoutLibrary
13
13
 
14
- __version__ = "0.2.6"
14
+ __version__ = "0.2.7"
15
15
 
16
16
 
17
17
  class _LambdaPath(PathSchema):
@@ -1,12 +1,20 @@
1
+ import argparse
2
+ import math
3
+
4
+ import os.path
5
+
1
6
  from pathlib import Path
2
7
 
8
+ from typing import Dict, Tuple
9
+
3
10
  from lambdalib import LambalibTechLibrary
4
11
  from lambdapdk import LambdaLibrary, _LambdaPath
5
- from lambdalib.ramlib import Spram, Dpram, Tdpram
12
+ from lambdalib.ramlib import Spram, Dpram, Tdpram, RAMTechLib
6
13
  from lambdapdk.asap7 import ASAP7PDK
14
+ from lambdapdk.utils import format_verilog
7
15
 
8
16
 
9
- class _FakeRAM7Library(LambdaLibrary):
17
+ class _FakeRAM7Library(LambdaLibrary, RAMTechLib):
10
18
  def __init__(self, config):
11
19
  super().__init__()
12
20
  self.set_name(f"fakeram7_{config}")
@@ -33,6 +41,89 @@ class _FakeRAM7Library(LambdaLibrary):
33
41
 
34
42
  self.add_klayout_allowmissingcell(self.name)
35
43
 
44
+ def __ram_props(self) -> Tuple[str, int, int]:
45
+ """Returns the RAM properties (width, depth) based on the configuration."""
46
+ type, size = self.name.split('_')[-2:]
47
+ width = int(size.split('x')[1])
48
+ depth = int(size.split('x')[0])
49
+ return type, width, depth
50
+
51
+ def get_ram_width(self) -> int:
52
+ """Returns the width of the RAM cell.
53
+
54
+ Returns:
55
+ int: The width of the RAM cell.
56
+ """
57
+ _, width, _ = self.__ram_props()
58
+ return width
59
+
60
+ def get_ram_depth(self) -> int:
61
+ """Returns the depth of the RAM cell.
62
+
63
+ Returns:
64
+ int: The depth of the RAM cell.
65
+ """
66
+ _, _, depth = self.__ram_props()
67
+ return int(math.log2(depth))
68
+
69
+ def get_ram_ports(self) -> Dict[str, str]:
70
+ """Returns the port mapping for the RAM cell.
71
+
72
+ Returns:
73
+ Dict[str, str]: A dictionary mapping port names to their expressions.
74
+ """
75
+ type, _, _ = self.__ram_props()
76
+ if type == "sp":
77
+ return {
78
+ "clk": "clk",
79
+ "addr_in": "mem_addr",
80
+ "ce_in": "ce_in",
81
+ "rd_out": "mem_dout",
82
+ "we_in": "we_in",
83
+ "w_mask_in": "mem_wmask",
84
+ "wd_in": "mem_din"
85
+ }
86
+ if type == "dp":
87
+ return {
88
+ "clk": "wr_clk",
89
+ "addr_in_A": "wr_mem_addr",
90
+ "addr_in_B": "rd_mem_addr",
91
+ "ce_in": "wr_ce_in | rd_ce_in",
92
+ "rd_out_A": "",
93
+ "rd_out_B": "mem_dout",
94
+ "we_in_A": "we_in",
95
+ "we_in_B": "1'b0",
96
+ "w_mask_in_A": "mem_wmask",
97
+ "w_mask_in_B": "'b0",
98
+ "wd_in_A": "mem_din",
99
+ "wd_in_B": "'b0"
100
+ }
101
+ if type == "tdp":
102
+ return {
103
+ "clk_A": "clk_a",
104
+ "clk_B": "clk_b",
105
+ "addr_in_A": "mem_addrA",
106
+ "addr_in_B": "mem_addrB",
107
+ "ce_in_A": "ce_in_A",
108
+ "ce_in_B": "ce_in_B",
109
+ "rd_out_A": "mem_doutA",
110
+ "rd_out_B": "mem_doutB",
111
+ "we_in_A": "we_in_A",
112
+ "we_in_B": "we_in_B",
113
+ "w_mask_in_A": "mem_wmaskA",
114
+ "w_mask_in_B": "mem_wmaskB",
115
+ "wd_in_A": "mem_dinA",
116
+ "wd_in_B": "mem_dinB"
117
+ }
118
+
119
+ def get_ram_libcell(self) -> str:
120
+ """Returns the name of the RAM library cell.
121
+
122
+ Returns:
123
+ str: The name of the RAM library cell.
124
+ """
125
+ return self.name
126
+
36
127
 
37
128
  class FakeRAM7_tdp_64x32(_FakeRAM7Library):
38
129
  def __init__(self):
@@ -246,12 +337,12 @@ class FakeRAM7_sp_8192x32(_FakeRAM7Library):
246
337
 
247
338
  class FakeRAM7_tdp_8192x64(_FakeRAM7Library):
248
339
  def __init__(self):
249
- super().__init__("dp_8192x64")
340
+ super().__init__("tdp_8192x64")
250
341
 
251
342
 
252
343
  class FakeRAM7_dp_8192x64(_FakeRAM7Library):
253
344
  def __init__(self):
254
- super().__init__("tdp_8192x64")
345
+ super().__init__("dp_8192x64")
255
346
 
256
347
 
257
348
  class FakeRAM7_sp_8192x64(_FakeRAM7Library):
@@ -350,3 +441,33 @@ class FakeRAM7Lambdalib_TrueDoublePort(LambalibTechLibrary, _LambdaPath):
350
441
  with self.active_fileset("rtl"):
351
442
  self.add_file(lib_path / "lambda" / "la_tdpram.v")
352
443
  self.add_depfileset(Tdpram(), "rtl.impl")
444
+
445
+
446
+ if __name__ == "__main__":
447
+ parser = argparse.ArgumentParser()
448
+ parser.add_argument('--verible_bin',
449
+ metavar='<verible>',
450
+ required=True,
451
+ help='path to verible-verilog-format')
452
+ args = parser.parse_args()
453
+
454
+ files = []
455
+
456
+ spram = Spram()
457
+ files.append(os.path.join(os.path.dirname(__file__), "fakeram7", "lambda", f"{spram.name}.v"))
458
+ spram.write_lambdalib(
459
+ files[-1],
460
+ FakeRAM7Lambdalib_SinglePort().techlibs)
461
+ dpram = Dpram()
462
+ files.append(os.path.join(os.path.dirname(__file__), "fakeram7", "lambda", f"{dpram.name}.v"))
463
+ dpram.write_lambdalib(
464
+ files[-1],
465
+ FakeRAM7Lambdalib_DoublePort().techlibs)
466
+ tdpram = Tdpram()
467
+ files.append(os.path.join(os.path.dirname(__file__), "fakeram7", "lambda", f"{tdpram.name}.v"))
468
+ tdpram.write_lambdalib(
469
+ files[-1],
470
+ FakeRAM7Lambdalib_TrueDoublePort().techlibs)
471
+
472
+ for f in files:
473
+ format_verilog(f, args.verible_bin)
@@ -1,12 +1,20 @@
1
+ import argparse
2
+ import math
3
+
4
+ import os.path
5
+
1
6
  from pathlib import Path
2
7
 
8
+ from typing import Dict, Tuple
9
+
3
10
  from lambdalib import LambalibTechLibrary
4
11
  from lambdapdk import LambdaLibrary, _LambdaPath
5
- from lambdalib.ramlib import Spram
12
+ from lambdalib.ramlib import Spram, RAMTechLib
6
13
  from lambdapdk.freepdk45 import FreePDK45PDK
14
+ from lambdapdk.utils import format_verilog
7
15
 
8
16
 
9
- class _FakeRAM45Library(LambdaLibrary):
17
+ class _FakeRAM45Library(LambdaLibrary, RAMTechLib):
10
18
  def __init__(self, config):
11
19
  super().__init__()
12
20
  self.set_name(f"fakeram45_{config}")
@@ -33,6 +41,55 @@ class _FakeRAM45Library(LambdaLibrary):
33
41
 
34
42
  self.add_klayout_allowmissingcell(self.name)
35
43
 
44
+ def __ram_props(self) -> Tuple[int, int]:
45
+ """Returns the RAM properties (width, depth) based on the configuration."""
46
+ size = self.name.split('_')[-1]
47
+ width = int(size.split('x')[1])
48
+ depth = int(size.split('x')[0])
49
+ return width, depth
50
+
51
+ def get_ram_width(self) -> int:
52
+ """Returns the width of the RAM cell.
53
+
54
+ Returns:
55
+ int: The width of the RAM cell.
56
+ """
57
+ width, _ = self.__ram_props()
58
+ return width
59
+
60
+ def get_ram_depth(self) -> int:
61
+ """Returns the depth of the RAM cell.
62
+
63
+ Returns:
64
+ int: The depth of the RAM cell.
65
+ """
66
+ _, depth = self.__ram_props()
67
+ return int(math.log2(depth))
68
+
69
+ def get_ram_ports(self) -> Dict[str, str]:
70
+ """Returns the port mapping for the RAM cell.
71
+
72
+ Returns:
73
+ Dict[str, str]: A dictionary mapping port names to their expressions.
74
+ """
75
+ return {
76
+ "clk": "clk",
77
+ "addr_in": "mem_addr",
78
+ "ce_in": "ce_in",
79
+ "rd_out": "mem_dout",
80
+ "we_in": "we_in",
81
+ "w_mask_in": "mem_wmask",
82
+ "wd_in": "mem_din"
83
+ }
84
+
85
+ def get_ram_libcell(self) -> str:
86
+ """Returns the name of the RAM library cell.
87
+
88
+ Returns:
89
+ str: The name of the RAM library cell.
90
+ """
91
+ return self.name
92
+
36
93
 
37
94
  class FakeRAM45_64x32(_FakeRAM45Library):
38
95
  def __init__(self):
@@ -84,3 +141,23 @@ class FakeRAM45Lambdalib_SinglePort(LambalibTechLibrary, _LambdaPath):
84
141
  with self.active_fileset("rtl"):
85
142
  self.add_file(lib_path / "lambda" / "la_spram.v")
86
143
  self.add_depfileset(Spram(), "rtl.impl")
144
+
145
+
146
+ if __name__ == "__main__":
147
+ parser = argparse.ArgumentParser()
148
+ parser.add_argument('--verible_bin',
149
+ metavar='<verible>',
150
+ required=True,
151
+ help='path to verible-verilog-format')
152
+ args = parser.parse_args()
153
+
154
+ files = []
155
+
156
+ spram = Spram()
157
+ files.append(os.path.join(os.path.dirname(__file__), "fakeram45", "lambda", f"{spram.name}.v"))
158
+ spram.write_lambdalib(
159
+ files[-1],
160
+ FakeRAM45Lambdalib_SinglePort().techlibs)
161
+
162
+ for f in files:
163
+ format_verilog(f, args.verible_bin)
@@ -1,8 +1,15 @@
1
+ import argparse
2
+ import math
3
+
4
+ import os.path
5
+
1
6
  from pathlib import Path
2
7
 
8
+ from typing import Dict, Tuple
9
+
3
10
  from lambdalib import LambalibTechLibrary
4
11
  from lambdapdk import LambdaLibrary, _LambdaPath
5
- from lambdalib.ramlib import Spram
12
+ from lambdalib.ramlib import Spram, RAMTechLib
6
13
  from lambdapdk.gf180 import GF180_3LM_1TM_6K_7t, \
7
14
  GF180_3LM_1TM_6K_9t, \
8
15
  GF180_3LM_1TM_9K_7t, \
@@ -25,9 +32,10 @@ from lambdapdk.gf180 import GF180_3LM_1TM_6K_7t, \
25
32
  GF180_5LM_1TM_11K_9t, \
26
33
  GF180_6LM_1TM_9K_7t, \
27
34
  GF180_6LM_1TM_9K_9t
35
+ from lambdapdk.utils import format_verilog
28
36
 
29
37
 
30
- class _GF180SRAMLibrary(LambdaLibrary):
38
+ class _GF180SRAMLibrary(LambdaLibrary, RAMTechLib):
31
39
  def __init__(self, config):
32
40
  super().__init__()
33
41
  self.set_name(f"gf180mcu_fd_ip_sram__sram{config}m8wm1")
@@ -84,6 +92,55 @@ class _GF180SRAMLibrary(LambdaLibrary):
84
92
  with self.active_fileset("openroad.globalconnect"):
85
93
  self.add_file(path_base / "apr" / "openroad" / "global_connect.tcl")
86
94
 
95
+ def __ram_props(self) -> Tuple[int, int]:
96
+ """Returns the RAM properties (width, depth) based on the configuration."""
97
+ size = self.name.split('_')[-1][4:-5]
98
+ width = int(size.split('x')[1])
99
+ depth = int(size.split('x')[0])
100
+ return width, depth
101
+
102
+ def get_ram_width(self) -> int:
103
+ """Returns the width of the RAM cell.
104
+
105
+ Returns:
106
+ int: The width of the RAM cell.
107
+ """
108
+ width, _ = self.__ram_props()
109
+ return width
110
+
111
+ def get_ram_depth(self) -> int:
112
+ """Returns the depth of the RAM cell.
113
+
114
+ Returns:
115
+ int: The depth of the RAM cell.
116
+ """
117
+ _, depth = self.__ram_props()
118
+ return int(math.log2(depth))
119
+
120
+ def get_ram_ports(self) -> Dict[str, str]:
121
+ """Returns the port mapping for the RAM cell.
122
+
123
+ Returns:
124
+ Dict[str, str]: A dictionary mapping port names to their expressions.
125
+ """
126
+ return {
127
+ "CLK": "clk",
128
+ "CEN": "~ce_in",
129
+ "GWEN": "~we_in",
130
+ "WEN": "~mem_wmask",
131
+ "A": "mem_addr",
132
+ "D": "mem_din",
133
+ "Q": "mem_dout"
134
+ }
135
+
136
+ def get_ram_libcell(self) -> str:
137
+ """Returns the name of the RAM library cell.
138
+
139
+ Returns:
140
+ str: The name of the RAM library cell.
141
+ """
142
+ return self.name
143
+
87
144
 
88
145
  class GF180_SRAM_64x8(_GF180SRAMLibrary):
89
146
  def __init__(self):
@@ -123,3 +180,24 @@ class GF180Lambdalib_SinglePort(LambalibTechLibrary, _LambdaPath):
123
180
  with self.active_fileset("rtl"):
124
181
  self.add_file(lib_path / "lambda" / "la_spram.v")
125
182
  self.add_depfileset(Spram(), "rtl.impl")
183
+
184
+
185
+ if __name__ == "__main__":
186
+ parser = argparse.ArgumentParser()
187
+ parser.add_argument('--verible_bin',
188
+ metavar='<verible>',
189
+ required=True,
190
+ help='path to verible-verilog-format')
191
+ args = parser.parse_args()
192
+
193
+ files = []
194
+
195
+ spram = Spram()
196
+ files.append(os.path.join(os.path.dirname(__file__), "gf180mcu_fd_ip_sram",
197
+ "lambda", f"{spram.name}.v"))
198
+ spram.write_lambdalib(
199
+ files[-1],
200
+ GF180Lambdalib_SinglePort().techlibs)
201
+
202
+ for f in files:
203
+ format_verilog(f, args.verible_bin)
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from lambdapdk import LambdaPDK, _LambdaPath
4
4
 
5
5
 
6
- pdk_rev = '62c1d640dc1c91f57bc1a8e4e08e537a7a105ae8'
6
+ pdk_rev = 'd490cfb2e3258f71f362167e74e1fcfc55381ab4'
7
7
 
8
8
 
9
9
  class _IHP130Path(_LambdaPath):
@@ -100,8 +100,7 @@ class IHP130PDK(LambdaPDK, _IHP130Path):
100
100
 
101
101
  # DRC
102
102
  drcs = {
103
- "maximal": 'ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_maximal.lydrc',
104
- "minimal": 'ihp-sg13g2/libs.tech/klayout/tech/drc/sg13g2_minimal.lydrc'
103
+ "drc": 'ihp-sg13g2/libs.tech/klayout/tech/drc/ihp-sg13g2.drc',
105
104
  }
106
105
  with self.active_dataroot("ihp130"):
107
106
  for drc, runset in drcs.items():
@@ -109,6 +108,6 @@ class IHP130PDK(LambdaPDK, _IHP130Path):
109
108
  self.add_file(runset, filetype="drc")
110
109
  self.add_runsetfileset("drc", "klayout", drc)
111
110
 
112
- self.add_klayout_drcparam(drc, "in_gds=<input>")
113
- self.add_klayout_drcparam(drc, "cell=<topcell>")
114
- self.add_klayout_drcparam(drc, "report_file=<report>")
111
+ self.add_klayout_drcparam(drc, "input=<input>")
112
+ self.add_klayout_drcparam(drc, "topcell=<topcell>")
113
+ self.add_klayout_drcparam(drc, "report=<report>")
@@ -1,12 +1,20 @@
1
+ import argparse
2
+ import math
3
+
4
+ import os.path
5
+
1
6
  from pathlib import Path
2
7
 
8
+ from typing import Dict, Tuple
9
+
3
10
  from lambdalib import LambalibTechLibrary
4
11
  from lambdapdk import LambdaLibrary, _LambdaPath
5
- from lambdalib.ramlib import Spram
12
+ from lambdalib.ramlib import Spram, RAMTechLib
6
13
  from lambdapdk.ihp130 import IHP130PDK, _IHP130Path
14
+ from lambdapdk.utils import format_verilog
7
15
 
8
16
 
9
- class _IHP130SRAMLibrary(LambdaLibrary, _IHP130Path):
17
+ class _IHP130SRAMLibrary(LambdaLibrary, _IHP130Path, RAMTechLib):
10
18
  def __init__(self, config):
11
19
  super().__init__()
12
20
  self.set_name(f'RM_IHPSG13_1P_{config}_c2_bm_bist')
@@ -46,6 +54,65 @@ class _IHP130SRAMLibrary(LambdaLibrary, _IHP130Path):
46
54
  self.add_file(path_base / "apr" / "openroad" / "global_connect.tcl")
47
55
  self.add_openroad_globalconnectfileset()
48
56
 
57
+ def __ram_props(self) -> Tuple[int, int]:
58
+ """Returns the RAM properties (width, depth) based on the configuration."""
59
+ size = self.name.split('_')[3]
60
+ width = int(size.split('x')[1])
61
+ depth = int(size.split('x')[0])
62
+ return width, depth
63
+
64
+ def get_ram_width(self) -> int:
65
+ """Returns the width of the RAM cell.
66
+
67
+ Returns:
68
+ int: The width of the RAM cell.
69
+ """
70
+ width, _ = self.__ram_props()
71
+ return width
72
+
73
+ def get_ram_depth(self) -> int:
74
+ """Returns the depth of the RAM cell.
75
+
76
+ Returns:
77
+ int: The depth of the RAM cell.
78
+ """
79
+ _, depth = self.__ram_props()
80
+ return int(math.log2(depth))
81
+
82
+ def get_ram_ports(self) -> Dict[str, str]:
83
+ """Returns the port mapping for the RAM cell.
84
+
85
+ Returns:
86
+ Dict[str, str]: A dictionary mapping port names to their expressions.
87
+ """
88
+ return {
89
+ "A_CLK": "clk",
90
+ "A_MEN": "~ce_in",
91
+ "A_WEN": "~we_in",
92
+ "A_REN": "we_in",
93
+ "A_ADDR": "mem_addr",
94
+ "A_DIN": "mem_din",
95
+ "A_DLY": "1'b1",
96
+ "A_DOUT": "mem_dout",
97
+ "A_BM": "mem_wmask",
98
+ "A_BIST_CLK": "1'b0",
99
+ "A_BIST_EN": "1'b0",
100
+ "A_BIST_MEN": "1'b0",
101
+ "A_BIST_WEN": "1'b0",
102
+ "A_BIST_REN": "1'b0",
103
+ "A_BIST_ADDR": "'b0",
104
+ "A_BIST_DIN": "'b0",
105
+ "A_BIST_BM": "'b0"
106
+ }
107
+
108
+ def get_ram_libcell(self) -> str:
109
+ """Returns the name of the RAM library cell.
110
+
111
+ Returns:
112
+ str: The name of the RAM library cell.
113
+ """
114
+ return self.name
115
+
49
116
 
50
117
  class IHP130_SRAM_1024x64(_IHP130SRAMLibrary):
51
118
  def __init__(self):
@@ -97,3 +164,24 @@ class IHP130Lambdalib_SinglePort(LambalibTechLibrary, _LambdaPath):
97
164
  with self.active_fileset("rtl"):
98
165
  self.add_file(lib_path / "lambda" / "la_spram.v")
99
166
  self.add_depfileset(Spram(), "rtl.impl")
167
+
168
+
169
+ if __name__ == "__main__":
170
+ parser = argparse.ArgumentParser()
171
+ parser.add_argument('--verible_bin',
172
+ metavar='<verible>',
173
+ required=True,
174
+ help='path to verible-verilog-format')
175
+ args = parser.parse_args()
176
+
177
+ files = []
178
+
179
+ spram = Spram()
180
+ files.append(os.path.join(os.path.dirname(__file__), "sg13g2_sram",
181
+ "lambda", f"{spram.name}.v"))
182
+ spram.write_lambdalib(
183
+ files[-1],
184
+ IHP130Lambdalib_SinglePort().techlibs)
185
+
186
+ for f in files:
187
+ format_verilog(f, args.verible_bin)
@@ -0,0 +1,141 @@
1
+ import argparse
2
+ import math
3
+
4
+ import os.path
5
+
6
+ from pathlib import Path
7
+
8
+ from typing import Dict, Tuple
9
+
10
+ from lambdalib import LambalibTechLibrary
11
+ from lambdapdk import LambdaLibrary, _LambdaPath
12
+ from lambdalib.ramlib import Spram, RAMTechLib
13
+ from lambdapdk.sky130 import Sky130PDK
14
+ from lambdapdk.utils import format_verilog
15
+
16
+
17
+ class Sky130_SRAM_64x256(LambdaLibrary, RAMTechLib):
18
+ def __init__(self):
19
+ super().__init__()
20
+ self.set_name('sky130_sram_1rw1r_64x256_8')
21
+
22
+ self.add_asic_pdk(Sky130PDK())
23
+
24
+ path_base = Path('lambdapdk', 'sky130', 'libs', "sky130sram")
25
+
26
+ with self.active_dataroot("lambdapdk"):
27
+ with self.active_fileset("models.timing.nldm"):
28
+ self.add_file(path_base / self.name / "nldm" / f"{self.name}_TT_1p8V_25C.lib")
29
+ self.add_asic_libcornerfileset("generic", "nldm")
30
+
31
+ with self.active_dataroot("lambdapdk"):
32
+ with self.active_fileset("models.physical"):
33
+ self.add_file(path_base / self.name / "lef" / f"{self.name}.lef.gz")
34
+ self.add_file(path_base / self.name / "gds" / f"{self.name}.gds")
35
+ self.add_asic_aprfileset()
36
+
37
+ with self.active_fileset("models.lvs"):
38
+ self.add_file(path_base / self.name / "spice" / f"{self.name}.lvs.sp",
39
+ filetype="cdl")
40
+ self.add_asic_aprfileset()
41
+
42
+ with self.active_fileset("models.spice"):
43
+ self.add_file(path_base / self.name / "spice" / f"{self.name}.sp")
44
+
45
+ with self.active_dataroot("lambdapdk"):
46
+ with self.active_fileset("openroad.powergrid"):
47
+ self.add_file(path_base / "apr" / "openroad" / "pdngen.tcl")
48
+ self.add_openroad_powergridfileset()
49
+ with self.active_fileset("openroad.globalconnect"):
50
+ self.add_file(path_base / "apr" / "openroad" / "global_connect.tcl")
51
+ self.add_openroad_globalconnectfileset()
52
+
53
+ def __ram_props(self) -> Tuple[int, int]:
54
+ """Returns the RAM properties (width, depth) based on the configuration."""
55
+ size = self.name.split('_')[-2]
56
+ depth = int(size.split('x')[1])
57
+ width = int(size.split('x')[0])
58
+ return width, depth
59
+
60
+ def get_ram_width(self) -> int:
61
+ """Returns the width of the RAM cell.
62
+
63
+ Returns:
64
+ int: The width of the RAM cell.
65
+ """
66
+ width, _ = self.__ram_props()
67
+ return width
68
+
69
+ def get_ram_depth(self) -> int:
70
+ """Returns the depth of the RAM cell.
71
+
72
+ Returns:
73
+ int: The depth of the RAM cell.
74
+ """
75
+ _, depth = self.__ram_props()
76
+ return int(math.log2(depth))
77
+
78
+ def get_ram_ports(self) -> Dict[str, str]:
79
+ """Returns the port mapping for the RAM cell.
80
+
81
+ Returns:
82
+ Dict[str, str]: A dictionary mapping port names to their expressions.
83
+ """
84
+ return {
85
+ "clk0": "clk",
86
+ "csb0": "ce_in && we_in",
87
+ "web0": "ce_in && we_in",
88
+ "wmask0": "{mem_wmask[24], mem_wmask[16], mem_wmask[8], mem_wmask[0]}",
89
+ "addr0": "mem_addr",
90
+ "din0": "mem_din",
91
+ "dout0": "",
92
+ "clk1": "clk",
93
+ "csb1": "ce_in && ~we_in",
94
+ "addr1": "mem_addr",
95
+ "dout1": "mem_dout",
96
+ }
97
+
98
+ def get_ram_libcell(self) -> str:
99
+ """Returns the name of the RAM library cell.
100
+
101
+ Returns:
102
+ str: The name of the RAM library cell.
103
+ """
104
+ return self.name
105
+
106
+
107
+ class Sky130Lambdalib_SinglePort(LambalibTechLibrary, _LambdaPath):
108
+ def __init__(self):
109
+ super().__init__("la_spram", [
110
+ Sky130_SRAM_64x256])
111
+ self.set_name("sky130_la_spram")
112
+
113
+ # version
114
+ self.package.set_version("v1")
115
+
116
+ lib_path = Path("lambdapdk", "sky130", "libs", "sky130sram")
117
+
118
+ with self.active_dataroot("lambdapdk"):
119
+ with self.active_fileset("rtl"):
120
+ self.add_file(lib_path / "lambda" / "la_spram.v")
121
+ self.add_depfileset(Spram(), "rtl.impl")
122
+
123
+
124
+ if __name__ == "__main__":
125
+ parser = argparse.ArgumentParser()
126
+ parser.add_argument('--verible_bin',
127
+ metavar='<verible>',
128
+ required=True,
129
+ help='path to verible-verilog-format')
130
+ args = parser.parse_args()
131
+
132
+ files = []
133
+
134
+ spram = Spram()
135
+ files.append(os.path.join(os.path.dirname(__file__), "sky130sram", "lambda", f"{spram.name}.v"))
136
+ spram.write_lambdalib(
137
+ files[-1],
138
+ Sky130Lambdalib_SinglePort().techlibs)
139
+
140
+ for f in files:
141
+ format_verilog(f, args.verible_bin)
@@ -0,0 +1,16 @@
1
+ import subprocess
2
+ import os.path
3
+ import glob
4
+
5
+
6
+ def format_verilog(path: str, verible_bin: str):
7
+ """Format Verilog files using Verible."""
8
+ if os.path.isfile(path):
9
+ paths = [os.path.abspath(path)]
10
+ elif os.path.isdir(path):
11
+ paths = glob.glob(os.path.join(path, '*.v'))
12
+ paths.extend(glob.glob(os.path.join(path, '*.vh')))
13
+
14
+ for f in paths:
15
+ print(f"Formatting: {f}")
16
+ subprocess.run([verible_bin, '--inplace', f])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambdapdk
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Library of open source Process Design Kits
5
5
  Author: Zero ASIC
6
6
  License: Apache License
@@ -199,12 +199,12 @@ Requires-Python: >=3.8
199
199
  Description-Content-Type: text/markdown
200
200
  License-File: LICENSE
201
201
  Requires-Dist: siliconcompiler>=0.35.0
202
- Requires-Dist: lambdalib>=0.5.0
202
+ Requires-Dist: lambdalib>=0.7.0
203
203
  Provides-Extra: test
204
204
  Requires-Dist: flake8==7.3.0; extra == "test"
205
- Requires-Dist: pytest==8.4.2; extra == "test"
205
+ Requires-Dist: pytest==9.0.2; extra == "test"
206
206
  Requires-Dist: pytest-timeout==2.4.0; extra == "test"
207
- Requires-Dist: tclint==0.6.2; extra == "test"
207
+ Requires-Dist: tclint==0.7.0; extra == "test"
208
208
  Requires-Dist: sc-leflib==0.5.1; extra == "test"
209
209
  Requires-Dist: Jinja2==3.1.6; extra == "test"
210
210
  Dynamic: license-file
@@ -3,6 +3,7 @@ MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
5
  lambdapdk/__init__.py
6
+ lambdapdk/utils.py
6
7
  lambdapdk.egg-info/PKG-INFO
7
8
  lambdapdk.egg-info/SOURCES.txt
8
9
  lambdapdk.egg-info/dependency_links.txt
@@ -1,10 +1,10 @@
1
1
  siliconcompiler>=0.35.0
2
- lambdalib>=0.5.0
2
+ lambdalib>=0.7.0
3
3
 
4
4
  [test]
5
5
  flake8==7.3.0
6
- pytest==8.4.2
6
+ pytest==9.0.2
7
7
  pytest-timeout==2.4.0
8
- tclint==0.6.2
8
+ tclint==0.7.0
9
9
  sc-leflib==0.5.1
10
10
  Jinja2==3.1.6
@@ -14,7 +14,7 @@ requires-python = ">= 3.8"
14
14
  license = {file = "LICENSE"}
15
15
  dependencies = [
16
16
  "siliconcompiler >= 0.35.0",
17
- "lambdalib >= 0.5.0"
17
+ "lambdalib >= 0.7.0"
18
18
  ]
19
19
  dynamic = ['version']
20
20
 
@@ -32,9 +32,9 @@ timeout = "180"
32
32
  # Test dependencies.
33
33
  test = [
34
34
  "flake8 == 7.3.0",
35
- "pytest == 8.4.2",
35
+ "pytest == 9.0.2",
36
36
  "pytest-timeout == 2.4.0",
37
- "tclint == 0.6.2",
37
+ "tclint == 0.7.0",
38
38
  "sc-leflib == 0.5.1",
39
39
  "Jinja2 == 3.1.6"
40
40
  ]
@@ -1,60 +0,0 @@
1
- from pathlib import Path
2
-
3
- from lambdalib import LambalibTechLibrary
4
- from lambdapdk import LambdaLibrary, _LambdaPath
5
- from lambdalib.ramlib import Spram
6
- from lambdapdk.sky130 import Sky130PDK
7
-
8
-
9
- class Sky130_SRAM_64x256(LambdaLibrary):
10
- def __init__(self):
11
- super().__init__()
12
- self.set_name('sky130_sram_1rw1r_64x256_8')
13
-
14
- self.add_asic_pdk(Sky130PDK())
15
-
16
- path_base = Path('lambdapdk', 'sky130', 'libs', "sky130sram")
17
-
18
- with self.active_dataroot("lambdapdk"):
19
- with self.active_fileset("models.timing.nldm"):
20
- self.add_file(path_base / self.name / "nldm" / f"{self.name}_TT_1p8V_25C.lib")
21
- self.add_asic_libcornerfileset("generic", "nldm")
22
-
23
- with self.active_dataroot("lambdapdk"):
24
- with self.active_fileset("models.physical"):
25
- self.add_file(path_base / self.name / "lef" / f"{self.name}.lef.gz")
26
- self.add_file(path_base / self.name / "gds" / f"{self.name}.gds")
27
- self.add_asic_aprfileset()
28
-
29
- with self.active_fileset("models.lvs"):
30
- self.add_file(path_base / self.name / "spice" / f"{self.name}.lvs.sp",
31
- filetype="cdl")
32
- self.add_asic_aprfileset()
33
-
34
- with self.active_fileset("models.spice"):
35
- self.add_file(path_base / self.name / "spice" / f"{self.name}.sp")
36
-
37
- with self.active_dataroot("lambdapdk"):
38
- with self.active_fileset("openroad.powergrid"):
39
- self.add_file(path_base / "apr" / "openroad" / "pdngen.tcl")
40
- self.add_openroad_powergridfileset()
41
- with self.active_fileset("openroad.globalconnect"):
42
- self.add_file(path_base / "apr" / "openroad" / "global_connect.tcl")
43
- self.add_openroad_globalconnectfileset()
44
-
45
-
46
- class Sky130Lambdalib_SinglePort(LambalibTechLibrary, _LambdaPath):
47
- def __init__(self):
48
- super().__init__("la_spram", [
49
- Sky130_SRAM_64x256])
50
- self.set_name("sky130_la_spram")
51
-
52
- # version
53
- self.package.set_version("v1")
54
-
55
- lib_path = Path("lambdapdk", "sky130", "libs", "sky130sram")
56
-
57
- with self.active_dataroot("lambdapdk"):
58
- with self.active_fileset("rtl"):
59
- self.add_file(lib_path / "lambda" / "la_spram.v")
60
- self.add_depfileset(Spram(), "rtl.impl")
File without changes
File without changes
File without changes
File without changes
File without changes