blob: e3885be0ad7037878d7d9e1758fda5cdd719a539 [file] [log] [blame]
emayecs5656b2b2021-08-04 12:44:13 -04001#!/usr/bin/env python3
emayecs5966a532021-07-29 10:07:02 -04002#
3#-----------------------------------------------------------
emayecs14748312021-08-05 14:21:26 -04004# Simulation hints management for the
emayecs5966a532021-07-29 10:07:02 -04005# characterization tool
6#-----------------------------------------------------------
7# Written by Tim Edwards
8# efabless, inc.
9# March 21, 2017
10# Version 0.1
11#--------------------------------------------------------
12
13import re
14import tkinter
15from tkinter import ttk
16
17class SimHints(tkinter.Toplevel):
18 """Characterization tool simulation hints management."""
19
20 def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
21 '''See the __init__ for Tkinter.Toplevel.'''
22 tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
23
24 s = ttk.Style()
25 s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
26 self.protocol("WM_DELETE_WINDOW", self.close)
27 self.parent = parent
28 self.withdraw()
29 self.title('Simulation hints management')
30 self.sframe = tkinter.Frame(self)
31 self.sframe.grid(column = 0, row = 0, sticky = "news")
32
33 self.sframe.stitle = ttk.Label(self.sframe,
34 style='title.TLabel', text = 'Hints')
35 self.sframe.stitle.pack(side = 'top', fill = 'x', expand = 'true')
36 self.sframe.sbar = ttk.Separator(self.sframe, orient='horizontal')
37 self.sframe.sbar.pack(side = 'top', fill = 'x', expand = 'true')
38
39 self.sframe.curparam = ttk.Label(self.sframe,
40 style='title.TLabel', text = 'None')
41 self.sframe.curparam.pack(side = 'top', fill = 'x', expand = 'true')
42 self.sframe.sbar2 = ttk.Separator(self.sframe, orient='horizontal')
43 self.sframe.sbar2.pack(side = 'top', fill = 'x', expand = 'true')
44
45 # Keep current parameter
46 self.param = None
47
48 #--------------------------------------------------------
49 # reltol option
50 #--------------------------------------------------------
51
52 self.sframe.do_reltol = tkinter.Frame(self.sframe)
53 self.sframe.do_reltol.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
54
55 self.do_reltol = tkinter.IntVar(self.sframe)
56 self.do_reltol.set(0)
57 self.sframe.do_reltol.enable = ttk.Checkbutton(self.sframe.do_reltol,
58 text='Set reltol', variable = self.do_reltol,
59 command=self.apply_reltol)
60 self.sframe.do_reltol.value = ttk.Entry(self.sframe.do_reltol)
61 self.sframe.do_reltol.value.delete(0, 'end')
62 self.sframe.do_reltol.value.insert(0, '1.0E-3')
63 # Return or leave window applies hint, if enabled
64 self.sframe.do_reltol.value.bind('<Return>', self.apply_reltol)
65 self.sframe.do_reltol.value.bind('<Leave>', self.apply_reltol)
66 self.sframe.do_reltol.enable.pack(side = 'left', anchor = 'w')
67 self.sframe.do_reltol.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
68
69 #--------------------------------------------------------
70 # rshunt option
71 #--------------------------------------------------------
72
73 self.sframe.do_rshunt = tkinter.Frame(self.sframe)
74 self.sframe.do_rshunt.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
75
76 self.do_rshunt = tkinter.IntVar(self.sframe)
77 self.do_rshunt.set(0)
78 self.sframe.do_rshunt.enable = ttk.Checkbutton(self.sframe.do_rshunt,
79 text='Use shunt resistance', variable = self.do_rshunt,
80 command=self.apply_rshunt)
81 self.sframe.do_rshunt.value = ttk.Entry(self.sframe.do_rshunt)
82 self.sframe.do_rshunt.value.delete(0, 'end')
83 self.sframe.do_rshunt.value.insert(0, '1.0E20')
84 # Return or leave window applies hint, if enabled
85 self.sframe.do_rshunt.value.bind('<Return>', self.apply_rshunt)
86 self.sframe.do_rshunt.value.bind('<Leave>', self.apply_rshunt)
87 self.sframe.do_rshunt.enable.pack(side = 'left', anchor = 'w')
88 self.sframe.do_rshunt.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
89
90 #--------------------------------------------------------
91 # nodeset option
92 #--------------------------------------------------------
93
94 self.sframe.do_nodeset = tkinter.Frame(self.sframe)
95 self.sframe.do_nodeset.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
96
97 self.do_nodeset = tkinter.IntVar(self.sframe)
98 self.do_nodeset.set(0)
99 self.sframe.do_nodeset.enable = ttk.Checkbutton(self.sframe.do_nodeset,
100 text='Use nodeset', variable = self.do_nodeset,
101 command=self.apply_nodeset)
102 self.sframe.do_nodeset.value = ttk.Entry(self.sframe.do_nodeset)
103 self.sframe.do_nodeset.value.delete(0, 'end')
104 # Return or leave window applies hint, if enabled
105 self.sframe.do_nodeset.value.bind('<Return>', self.apply_nodeset)
106 self.sframe.do_nodeset.value.bind('<Leave>', self.apply_nodeset)
107 self.sframe.do_nodeset.enable.pack(side = 'left', anchor = 'w')
108 self.sframe.do_nodeset.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
109
110 #--------------------------------------------------------
111 # itl1 option
112 #--------------------------------------------------------
113
114 self.sframe.do_itl1 = tkinter.Frame(self.sframe)
115 self.sframe.do_itl1.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
116
117 self.do_itl1 = tkinter.IntVar(self.sframe)
118 self.do_itl1.set(0)
119 self.sframe.do_itl1.enable = ttk.Checkbutton(self.sframe.do_itl1,
120 text='Set gmin iterations', variable = self.do_itl1,
121 command=self.apply_itl1)
122 self.sframe.do_itl1.value = ttk.Entry(self.sframe.do_itl1)
123 self.sframe.do_itl1.value.delete(0, 'end')
124 self.sframe.do_itl1.value.insert(0, '100')
125 # Return or leave window applies hint, if enabled
126 self.sframe.do_itl1.value.bind('<Return>', self.apply_itl1)
127 self.sframe.do_itl1.value.bind('<Leave>', self.apply_itl1)
128 self.sframe.do_itl1.enable.pack(side = 'left', anchor = 'w')
129 self.sframe.do_itl1.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
130
131 #--------------------------------------------------------
132 # include option
133 # Disabled for now. This needs to limit the selection of
134 # files to include to a drop-down selection list.
135 #--------------------------------------------------------
136 self.sframe.do_include = tkinter.Frame(self.sframe)
137 # self.sframe.do_include.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
138
139 self.do_include = tkinter.IntVar(self.sframe)
140 self.do_include.set(0)
141 self.sframe.do_include.enable = ttk.Checkbutton(self.sframe.do_include,
142 text='Include netlist', variable = self.do_include,
143 command=self.apply_include)
144 self.sframe.do_include.value = ttk.Entry(self.sframe.do_include)
145 self.sframe.do_include.value.delete(0, 'end')
146 # Return or leave window applies hint, if enabled
147 self.sframe.do_include.value.bind('<Return>', self.apply_include)
148 self.sframe.do_include.value.bind('<Leave>', self.apply_include)
149 self.sframe.do_include.enable.pack(side = 'left', anchor = 'w')
150 self.sframe.do_include.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
151
152 #--------------------------------------------------------
153 # alternative method option
154 #--------------------------------------------------------
155
156 self.sframe.do_method = tkinter.Frame(self.sframe)
157 self.sframe.do_method.pack(side = 'top', anchor = 'w', fill = 'x', expand = 'true')
158
159 self.do_method = tkinter.IntVar(self.sframe)
160 self.do_method.set(0)
161 self.sframe.do_method.enable = ttk.Checkbutton(self.sframe.do_method,
162 text='Use alternate method', variable = self.do_method,
163 command=self.apply_method)
164 self.sframe.do_method.value = ttk.Entry(self.sframe.do_method)
165 self.sframe.do_method.value.delete(0, 'end')
166 self.sframe.do_method.value.insert(0, '0')
167 # Return or leave window applies hint, if enabled
168 self.sframe.do_method.value.bind('<Return>', self.apply_method)
169 self.sframe.do_method.value.bind('<Leave>', self.apply_method)
170 self.sframe.do_method.enable.pack(side = 'left', anchor = 'w')
171 self.sframe.do_method.value.pack(side = 'left', anchor = 'w', fill='x', expand='true')
172
173 #--------------------------------------------------------
174
175 self.bbar = ttk.Frame(self)
176 self.bbar.grid(column = 0, row = 1, sticky = "news")
177
178 self.bbar.apply_button = ttk.Button(self.bbar, text='Apply',
179 command=self.apply_hints, style = 'normal.TButton')
180 self.bbar.apply_button.grid(column=0, row=0, padx = 5)
181
182 self.bbar.close_button = ttk.Button(self.bbar, text='Close',
183 command=self.close, style = 'normal.TButton')
184 self.bbar.close_button.grid(column=1, row=0, padx = 5)
185
186 def apply_reltol(self, value = ''):
187 # "value" is passed from binding callback but is not used
188 have_reltol = self.do_reltol.get()
189 if have_reltol:
190 if not 'hints' in self.param:
191 phints = {}
192 else:
193 phints = self.param['hints']
194 phints['reltol'] = self.sframe.do_reltol.value.get()
195 self.param['hints'] = phints
196 else:
197 if 'hints' in self.param:
198 self.param['hints'].pop('reltol', None)
199
200 def apply_rshunt(self, value = ''):
201 # "value" is passed from binding callback but is not used
202 have_rshunt = self.do_rshunt.get()
203 if have_rshunt:
204 if not 'hints' in self.param:
205 phints = {}
206 else:
207 phints = self.param['hints']
208 phints['rshunt'] = self.sframe.do_rshunt.value.get()
209 self.param['hints'] = phints
210 else:
211 if 'hints' in self.param:
212 self.param['hints'].pop('rshunt', None)
213
214 def apply_itl1(self, value = ''):
215 # "value" is passed from binding callback but is not used
216 have_itl1 = self.do_itl1.get()
217 if have_itl1:
218 if not 'hints' in self.param:
219 phints = {}
220 else:
221 phints = self.param['hints']
222 phints['itl1'] = self.sframe.do_itl1.value.get()
223 self.param['hints'] = phints
224 else:
225 if 'hints' in self.param:
226 self.param['hints'].pop('itl1', None)
227
228
229 def apply_nodeset(self, value = ''):
230 # "value" is passed from binding callback but is not used
231 have_nodeset = self.do_nodeset.get()
232 if have_nodeset:
233 if not 'hints' in self.param:
234 phints = {}
235 else:
236 phints = self.param['hints']
237 phints['nodeset'] = self.sframe.do_nodeset.value.get()
238 self.param['hints'] = phints
239 else:
240 if 'hints' in self.param:
241 self.param['hints'].pop('nodeset', None)
242
243 def apply_include(self, value = ''):
244 # "value" is passed from binding callback but is not used
245 have_include = self.do_include.get()
246 if have_include:
247 if not 'hints' in self.param:
248 phints = {}
249 else:
250 phints = self.param['hints']
251 phints['include'] = self.sframe.do_include.value.get()
252 self.param['hints'] = phints
253 else:
254 if 'hints' in self.param:
255 self.param['hints'].pop('include', None)
256
257 def apply_method(self, value = ''):
258 # "value" is passed from binding callback but is not used
259 have_method = self.do_method.get()
260 if have_method:
261 if not 'hints' in self.param:
262 phints = {}
263 else:
264 phints = self.param['hints']
265 phints['method'] = self.sframe.do_method.value.get()
266 self.param['hints'] = phints
267 else:
268 if 'hints' in self.param:
269 self.param['hints'].pop('method', None)
270
271 def apply_hints(self, value = ''):
272 self.apply_reltol(value)
273 self.apply_rshunt(value)
274 self.apply_itl1(value)
275 self.apply_nodeset(value)
276 self.apply_include(value)
277 self.apply_method(value)
278
279 # Update 'Simulate' button in characterization tool with a mark
280 # indicating hints are present. Also remove the hints record
281 # from the parameter dictionary if it is empty.
282 if 'method' in self.param:
283 if 'hints' in self.param:
284 if self.param['hints'] == {}:
285 self.param.pop('hints', None)
286 simtext = 'Simulate'
287 else:
288 simtext = '\u2022Simulate'
289 else:
290 simtext = 'Simulate'
291 self.simbutton.config(text=simtext)
292
293 def grid_configure(self, padx, pady):
294 pass
295
296 def redisplay(self):
297 pass
298
299 def populate(self, param, simbutton = False):
300 if 'display' in param:
301 self.sframe.curparam.config(text=param['display'])
302 else:
303 self.sframe.curparam.config(text=param['method'])
304
305 # Set the current parameter
306 self.param = param
307
308 # Remember the simulate button so we can mark or unmark hints
309 self.simbutton = simbutton
310
311 # Regenerate view and update for the indicated param.
312 if 'hints' in param:
313 phints = param['hints']
314 if 'reltol' in phints:
315 # (1) Reltol adjustment
316 self.do_reltol.set(1)
317 self.sframe.do_reltol.value.delete(0, 'end')
318 self.sframe.do_reltol.value.insert(0, phints['reltol'])
319 else:
320 self.do_reltol.set(0)
321 if 'rshunt' in phints:
322 # (2) Gshunt option
323 self.do_rshunt.set(1)
324 self.sframe.do_rshunt.value.delete(0, 'end')
325 self.sframe.do_rshunt.value.insert(0, phints['rshunt'])
326 else:
327 self.do_rshunt.set(0)
328 if 'nodeset' in phints:
329 # (3) Nodeset
330 self.do_nodeset.set(1)
331 self.sframe.do_nodeset.value.delete(0, 'end')
332 self.sframe.do_nodeset.value.insert(0, phints['nodeset'])
333 else:
334 self.do_nodeset.set(0)
335 if 'itl1' in phints:
336 # (4) Gmin iterations (ITL1)
337 self.do_itl1.set(1)
338 self.sframe.do_itl1.value.delete(0, 'end')
339 self.sframe.do_itl1.value.insert(0, phints['itl1'])
340 else:
341 self.do_itl1.set(0)
342 if 'include' in phints:
343 # (5) Include library (from dropdown list)
344 self.do_include.set(1)
345 self.sframe.do_include.value.delete(0, 'end')
346 self.sframe.do_include.value.insert(0, phints['include'])
347 else:
348 self.do_include.set(0)
349 if 'method' in phints:
350 # (6) Alternative method (where indicated)
351 self.do_method.set(1)
352 self.sframe.do_method.value.delete(0, 'end')
353 self.sframe.do_method.value.insert(0, phints['method'])
354 else:
355 self.do_method.set(0)
356 else:
357 # No hints, so set everything to unchecked
358 self.do_reltol.set(0)
359 self.do_rshunt.set(0)
360 self.do_nodeset.set(0)
361 self.do_itl1.set(0)
362 self.do_include.set(0)
363 self.do_method.set(0)
364
365 def close(self):
366 # pop down settings window
367 self.withdraw()
368
369 def open(self):
370 # pop up settings window
371 self.deiconify()
372 self.lift()