blob: ec48636f270d530bdc2ef5dbdfc49dbc90a679d2 [file] [log] [blame]
Tim Edwardsafa7a412020-12-07 16:10:02 -05001#!/bin/env python3
agorararmard6c766a82020-12-10 18:13:12 +02002# SPDX-FileCopyrightText: 2020 Efabless Corporation
agorararmarde5780bf2020-12-09 21:27:56 +00003#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
agorararmardafa96ea2020-12-09 23:37:31 +020015# SPDX-License-Identifier: Apache-2.0
agorararmarde5780bf2020-12-09 21:27:56 +000016
Tim Edwardsafa7a412020-12-07 16:10:02 -050017#
Tim Edwards268de722020-12-08 16:32:39 -050018# compositor.py ---
Tim Edwardsafa7a412020-12-07 16:10:02 -050019#
Tim Edwards268de722020-12-08 16:32:39 -050020# Compose the final GDS for caravel from the caravel GDS, seal ring
21# GDS, and fill GDS.
22#
23
24import sys
25import os
26import re
27import subprocess
28
29def usage():
30 print("compositor.py [layout_name] [-keep]")
31 return 0
32
33if __name__ == '__main__':
34
35 if len(sys.argv) == 1:
36 usage()
37 sys.exit(0)
38
39 optionlist = []
40 arguments = []
41
42 debugmode = False
43 keepmode = False
44
45 for option in sys.argv[1:]:
46 if option.find('-', 0) == 0:
47 optionlist.append(option)
48 else:
49 arguments.append(option)
50
51 if len(arguments) > 1:
52 print("Wrong number of arguments given to compositor.py.")
53 usage()
54 sys.exit(0)
55
56 if len(arguments) == 1:
57 project = arguments[0]
58 else:
59 project = 'caravel'
60
61 if '-debug' in optionlist:
62 debugmode = True
63 if '-keep' in optionlist:
64 keepmode = True
65
66 magdir = '../mag'
67 rcfile = magdir + '/.magicrc'
68
69 with open(magdir + '/compose_final.tcl', 'w') as ofile:
70 print('#!/bin/env wish', file=ofile)
71 print('drc off', file=ofile)
72
73 print('load ' + project + ' -dereference', file=ofile)
74 print('select top cell', file=ofile)
75
76 # Ceate a cell to represent the generated fill. There are
77 # no magic layers corresponding to the fill shape data, and
78 # it's gigabytes anyway, so we don't want to deal with any
79 # actual data. So it's just a placeholder.
80
81 print('set bbox [box values]', file=ofile)
82 print('load ' + project + '_fill_pattern', file=ofile)
83 print('snap internal', file=ofile)
84 print('box values {*}$bbox', file=ofile)
85 print('paint comment', file=ofile)
86 print('property GDS_FILE ../gds/' + project + '_fill_pattern.gds', file=ofile)
87 print('property GDS_START 0', file=ofile)
88 print('property FIXED_BBOX "$bbox"', file=ofile)
89
90 # Now go back to the project top level and place the fill cell.
91 print('load ' + project, file=ofile)
Tim Edwardsa4dae5a2020-12-09 09:30:42 -050092 print('select top cell', file=ofile)
Tim Edwards268de722020-12-08 16:32:39 -050093 print('getcell ' + project + '_fill_pattern child 0 0', file=ofile)
94
95 # Move existing origin to (6um, 6um) for seal ring placement
96 print('move origin -6um -6um', file=ofile)
97
98 # Read in abstract view of seal ring
99 print('box position 0 0', file=ofile)
100 print('getcell advSeal_6um_gen', file=ofile)
101
102 # Generate final GDS
103 print('puts stdout "Writing final GDS. . . "', file=ofile)
104 print('flush stdout', file=ofile)
105 print('gds write ../gds/' + project + '_final.gds', file=ofile)
106 print('quit -noprompt', file=ofile)
107
108 myenv = os.environ.copy()
109 # Abstract views are appropriate for final composition
110 myenv['MAGTYPE'] = 'maglef'
111
112 mproc = subprocess.run(['magic', '-dnull', '-noconsole',
113 '-rcfile', rcfile, magdir + '/compose_final.tcl'],
114 stdin = subprocess.DEVNULL,
115 stdout = subprocess.PIPE,
116 stderr = subprocess.PIPE,
117 cwd = magdir,
118 env = myenv,
119 universal_newlines = True)
120 if mproc.stdout:
121 for line in mproc.stdout.splitlines():
122 print(line)
123 if mproc.stderr:
124 print('Error message output from magic:')
125 for line in mproc.stderr.splitlines():
126 print(line)
127 if mproc.returncode != 0:
128 print('ERROR: Magic exited with status ' + str(mproc.returncode))
129
130 if not keepmode:
131 os.remove(magdir + '/compose_final.tcl')
132
133 exit(0)