blob: 11ad1bc5e6c52fb168e17f47affe6b82a5274454 [file] [log] [blame]
Tim Edwards10aa9ab2021-03-15 17:46:29 -04001#!/usr/bin/env python3
2#-----------------------------------------------------------------------
3# create_project.py
4#-----------------------------------------------------------------------
5#
6# Create a project in the form preferred by open_pdks.
7#
8#---------------------------------------------------------------------
9# Written by Tim Edwards
10# March 15, 2021
11# Version 1.0
12#---------------------------------------------------------------------
13
14import os
15import re
16import sys
17import json
emayecsb2487ae2021-08-05 10:30:13 -040018import yaml
Tim Edwards10aa9ab2021-03-15 17:46:29 -040019
20def usage():
21 print('Usage:')
22 print(' create_project.py <project_name> [<pdk_name>] [-options]')
23 print('')
24 print('Arguments:')
25 print(' <project_name> is the name of the project and the top-level directory')
26 print(' <pdk_name> is the name of the PDK')
27 print('')
28 print(' <pdk_name> can be a full path to the PDK')
29 print(' <project_name> can be a full path to the project, otherwise use cwd.')
30 print('')
31 print('Options:')
32 print(' -help Print this help text.')
33
34# Main procedure
35
36if __name__ == '__main__':
37
38 # Parse command line for options and arguments
39 optionlist = []
40 arguments = []
41 for item in sys.argv[1:]:
42 if item.find('-', 0) == 0:
43 optionlist.append(item)
44 else:
45 arguments.append(item)
46
47 if len(arguments) > 0:
48 projectname = arguments[0]
49 if len(arguments) > 1:
50 pdkname = arguments[1]
51 else:
52 pdkname = None
53 else:
54 usage()
55 sys.exit(0)
56
57 if pdkname:
58 if pdkname.startswith('/'):
59 pdkpath = pdkname
emayecs5966a532021-07-29 10:07:02 -040060 pdkname = os.path.split(pdkpath)[1]
Tim Edwards10aa9ab2021-03-15 17:46:29 -040061 else:
emayecs14748312021-08-05 14:21:26 -040062 pdkpath = os.path.join('PREFIX', 'pdk', pdkname)
Tim Edwards10aa9ab2021-03-15 17:46:29 -040063 else:
64 try:
65 pdkpath = os.getenv()['PDK_PATH']
66 except:
67 try:
68 pdkpath = os.getenv()['PDKPATH']
69 except:
70 print('If PDK name is not specified, then PDKPATH must be set.')
71 sys.exit(1)
72
73 if not os.path.isdir(pdkpath):
74 print('Path to PDK ' + pdkpath + ' does not exist or is not readable.')
75 sys.exit(1)
76
77 for item in optionlist:
78 result = item.split('=')
79 if result[0] == '-help':
80 usage()
81 sys.exit(0)
82 else:
83 usage()
84 sys.exit(1)
85
86 if projectname.startswith('/'):
87 projectpair = os.path.split(projectname)
88 projectparent = projectpair[0]
89 projectname = projectpair[1]
90 else:
91 projectparent = os.getcwd()
92
93 if not os.path.isdir(projectparent):
94 print('Path to project ' + projectpath + ' does not exist or is not readable.')
95 sys.exit(1)
96
97 projectpath = os.path.join(projectparent, projectname)
98
99 # Check that files to be linked to exist in the PDK
100 if not os.path.isfile(pdkpath + '/libs.tech/magic/' + pdkname + '.magicrc'):
101 print(pdkname + '.magicrc not found; not installing.')
102 domagic = False
103 else:
104 domagic = True
105
106 if not os.path.isfile(pdkpath + '/libs.tech/netgen/' + pdkname + '_setup.tcl'):
107 print(pdkname + '_setup.tcl for netgen not found; not installing.')
108 donetgen = False
109 else:
110 donetgen = True
111
112 if not os.path.isfile(pdkpath + '/libs.tech/xschem/xschemrc'):
113 print('xschemrc for xschem not found; not installing.')
114 doxschem = False
115 else:
116 doxschem = True
117
118 if not os.path.isfile(pdkpath + '/libs.tech/ngspice/spinit'):
119 print('spinit for ngspice not found; not installing.')
120 dongspice = False
121 else:
122 dongspice = True
123
emayecs5966a532021-07-29 10:07:02 -0400124 if not os.path.isdir(pdkpath + '/.ef-config') and not os.path.isdir(pdkpath + '/.config'):
125 print('PDK does not contain .config or .ef-config directory, cannot create project.')
126 sys.exit(1)
127
Tim Edwards10aa9ab2021-03-15 17:46:29 -0400128 if domagic or donetgen or doxschem or dongspice:
129 print('Creating project ' + projectname)
130 os.makedirs(projectpath)
131 else:
132 print('No setup files were found . . . bailing.')
133 sys.exit(1)
134
emayecs5966a532021-07-29 10:07:02 -0400135 if os.path.isdir(pdkpath + '/.ef-config'):
136 os.makedirs(projectpath + '/.ef-config')
137 os.symlink(pdkpath, projectpath + '/.ef-config/techdir')
138 elif os.path.isdir(pdkpath + '/.config'):
139 os.makedirs(projectpath + '/.config')
140 os.symlink(pdkpath, projectpath + '/.config/techdir')
141
142
Tim Edwards10aa9ab2021-03-15 17:46:29 -0400143 if domagic:
144 magpath = os.path.join(projectpath, 'mag')
145 os.makedirs(magpath)
146 os.symlink(pdkpath + '/libs.tech/magic/' + pdkname + '.magicrc',
147 magpath + '/.magicrc')
148
149 if doxschem:
150 xschempath = os.path.join(projectpath, 'xschem')
151 os.makedirs(xschempath)
152 os.symlink(pdkpath + '/libs.tech/xschem/xschemrc',
153 xschempath + '/xschemrc')
154
155 if donetgen:
156 netgenpath = os.path.join(projectpath, 'netgen')
157 os.makedirs(netgenpath)
158 os.symlink(pdkpath + '/libs.tech/netgen/' + pdkname + '_setup.tcl',
159 netgenpath + '/setup.tcl')
160
161 if dongspice:
162 ngspicepath = os.path.join(projectpath, 'ngspice')
163 os.makedirs(ngspicepath)
164 os.symlink(pdkpath + '/libs.tech/ngspice/spinit',
165 ngspicepath + '/.spiceinit')
emayecsb2487ae2021-08-05 10:30:13 -0400166
167 data = {}
168 project={}
169 project['description'] = "(Add project description here)"
170
171 infofile = pdkpath + '/.config/nodeinfo.json'
172 if os.path.exists(infofile):
173 with open(infofile, 'r') as ifile:
174 nodeinfo = json.load(ifile)
175 if 'foundry' in nodeinfo:
176 project['foundry'] = nodeinfo['foundry']
177
178 project['process']=pdkname
179 project['project_name'] = projectname
180 data['project']=project
181
Tim Edwards10aa9ab2021-03-15 17:46:29 -0400182 with open(projectpath + '/info.yaml', 'w') as ofile:
183 print('---', file=ofile)
emayecsb2487ae2021-08-05 10:30:13 -0400184 yaml.dump(data, ofile)
185
Tim Edwards10aa9ab2021-03-15 17:46:29 -0400186 print('Done!')
187 sys.exit(0)