1
+ from siliconcompiler import Chip
2
+ from siliconcompiler .package import path as sc_package
3
+ import glob
1
4
import os
2
-
5
+ import shutil
3
6
__version__ = "0.1.2"
4
7
5
8
@@ -17,3 +20,126 @@ def register_data_source(chip):
17
20
chip .register_package_source (name = 'lambdalib' ,
18
21
path = path ,
19
22
ref = ref )
23
+
24
+
25
+ def __get_lambdalib_dir (la_lib ):
26
+ path_assert = Chip ('lambdalib' )
27
+ register_data_source (path_assert )
28
+ lambdalib_path = sc_package (path_assert , 'lambdalib' )
29
+ return f'{ lambdalib_path } /lambdalib/{ la_lib } /rtl'
30
+
31
+
32
+ def check (outputpath , la_lib = 'stdlib' ):
33
+ cells_dir = __get_lambdalib_dir (la_lib )
34
+
35
+ lambda_cells = set ()
36
+ for cell in glob .glob (f'{ cells_dir } /la_*.v' ):
37
+ lambda_cells .add (os .path .basename (cell ))
38
+
39
+ lib_cells = set ()
40
+ for cell in glob .glob (f'{ outputpath } /la_*.v' ):
41
+ lib_cells .add (os .path .basename (cell ))
42
+
43
+ if lambda_cells == lib_cells :
44
+ return True
45
+
46
+ missing_cells = lambda_cells - lib_cells
47
+ extra_cells = lib_cells - lambda_cells
48
+
49
+ if missing_cells :
50
+ for cell in missing_cells :
51
+ print (f'Missing: { cell } ' )
52
+ if extra_cells :
53
+ for cell in extra_cells :
54
+ print (f'Excess cell: { cell } ' )
55
+
56
+ return False
57
+
58
+
59
+ def copy (outputpath , la_lib = 'stdlib' , exclude = None ):
60
+ cells_dir = __get_lambdalib_dir (la_lib )
61
+
62
+ if not exclude :
63
+ exclude = []
64
+
65
+ os .makedirs (outputpath , exist_ok = True )
66
+
67
+ # Generate list of cells to produce
68
+ for cell in glob .glob (f'{ cells_dir } /la_*.v' ):
69
+ cell_file = os .path .basename (cell )
70
+ cell_name , _ = os .path .splitext (cell_file )
71
+
72
+ if cell_name in exclude :
73
+ continue
74
+
75
+ shutil .copy (cell , os .path .join (outputpath , cell_file ))
76
+
77
+
78
+ def generate (target , logiclib , outputpath , la_lib = 'stdlib' , exclude = None ):
79
+ exclude_default = (
80
+ 'la_decap' ,
81
+ 'la_keeper' ,
82
+ 'la_footer' ,
83
+ 'la_header' ,
84
+ 'la_antenna'
85
+ )
86
+
87
+ full_exclude = []
88
+ if exclude :
89
+ full_exclude .extend (exclude )
90
+
91
+ full_exclude .extend (exclude_default )
92
+
93
+ # Ensure files are loaded
94
+ cells_dir = __get_lambdalib_dir (la_lib )
95
+
96
+ # Generate list of cells to produce
97
+ org_cells = set ()
98
+ cells = []
99
+ for cell in glob .glob (f'{ cells_dir } /la_*.v' ):
100
+ cell_name , _ = os .path .splitext (os .path .basename (cell ))
101
+
102
+ if cell_name in full_exclude :
103
+ continue
104
+
105
+ cells .append (cell )
106
+ org_cells .add (cell_name )
107
+
108
+ # Remove old implementations
109
+ for cell in cells :
110
+ new_path = os .path .join (outputpath , os .path .basename (cell ))
111
+ try :
112
+ os .remove (new_path )
113
+ except FileNotFoundError :
114
+ pass
115
+
116
+ os .makedirs (outputpath , exist_ok = True )
117
+
118
+ if isinstance (target , str ):
119
+ target_name = target
120
+ else :
121
+ target_name = target .__name__
122
+
123
+ for cell in cells :
124
+ cell_file = os .path .basename (cell )
125
+ cell_name , _ = os .path .splitext (cell_file )
126
+
127
+ chip = Chip (cell_name )
128
+ chip .input (cell )
129
+ chip .load_target (target )
130
+ chip .set ('asic' , 'logiclib' , logiclib )
131
+ chip .set ('option' , 'flow' , 'asicflow' )
132
+ chip .set ('option' , 'to' , 'syn' )
133
+ chip .set ('option' , 'quiet' , True )
134
+ chip .set ('option' , 'resume' , True )
135
+ chip .set ('option' , 'jobname' , f"{ target_name } -{ logiclib } " )
136
+
137
+ chip .add ('option' , 'ydir' , cells_dir )
138
+ chip .run ()
139
+
140
+ result = chip .find_result ("vg" , step = "syn" , index = 0 )
141
+ shutil .copy (result , os .path .join (outputpath , cell_file ))
142
+
143
+ if exclude :
144
+ org_cells .update (exclude )
145
+ copy (outputpath , la_lib , org_cells )
0 commit comments