1
package com.sun.electric.tool.simulation.test;
3
import java.io.FileWriter;
4
import java.io.IOException;
5
import java.io.PrintWriter;
11
* Copyright (c) 2005 by Sun Microsystems, Inc.
13
* Created on 1/10/05, by extraction from ChainModel
17
* Main API for sampler programming and calibration. The code assumes that a
18
* node controls a sampler if and only if it satisfies the following conditions:
20
* <li>It is an instance of <code>SubchainNode</code> (e.g, it is a
21
* <code>ChainNode</code>)</li>
22
* <li>The node includes a <tt>pin</tt> attribute</li>
23
* <li>The node contains one each of <tt>calibrate</tt>,<tt>enable</tt>,
24
* and <tt>enable_f</tt>
25
* <code>Subchain</code> nodes. (Other nodes are
26
* allowed as well.)</li>
27
* <li>The <tt>calibrate</tt>,<tt>enable</tt>, and <tt>enable_f</tt>
28
* nodes each contain a single scan chain element.
30
* If the pin attribute cannot be set in the XML file, it may be set using
31
* <code>ChainControl.setSubchainPin()</code>.
34
* @author Tom O'Neill (toneill)
37
public class SamplerControl extends Logger {
39
/** Object containing scan chain model/APIs */
43
* Specifies whether chain control elements must be set <tt>HI</tt> to
44
* enable the corresponding on-chip signal.
46
private final int polarity;
48
/** Mapping from scan chain paths to pin names */
52
* For each sampler control node, the value of the scan chain element
53
* required to enable the control setting
55
private final String[] controlEnable = new String[CONTROL_NODES.length];
58
* For each sampler control node, the value of the scan chain element
59
* required to disable the control setting
61
private final String[] controlDisable = new String[CONTROL_NODES.length];
63
/** Name of calibrate sampler control node */
64
public final static String[] CONTROL_NODES = { "calibrate", "enable",
67
/** index of calibrate control node */
68
public final static int IND_CALIBRATE = 0;
70
public final static int IND_ENABLE = 1;
72
public final static int IND_ENABLE_F = 2;
75
* <code>polarity</code> value when calibrate, enable, enable_f scan chain
76
* elements are set <tt>HI</tt> to set these signals true on chip.
78
public final static int POLARITY_NORMAL = 0;
81
* <code>polarity</code> value when calibrate, enable, enable_f scan chain
82
* elements are set <tt>LO</tt> to set these signals true on chip.
84
public final static int POLARITY_INVERTED = 1;
87
* Scan chain value required to enable a sampler control signal, depends on
90
private final static String[] CONTROL_ENABLE = { "1", "0" };
93
* Scan chain value required to disable a sampler control signal, depends on
96
private final static String[] CONTROL_DISABLE = { "0", "1" };
99
* Constructor. Identifies samplers in <code>control</code> using the
100
* conditions described at top. For each sampler, sets <code>inBits</code>
101
* necessary to disable it. Does not shift any data, since the rest of the
102
* chip state may not be specified.
104
* Currently <code>polarity</code> value may be
105
* <code>POLARITY_NORMAL</code> or <code>POLARITY_INVERTED</code>.
108
* Object containing scan chain model/APIs
110
* whether sampler control signals come from non-inverting scan
113
public SamplerControl(ChainControl control, int polarity) {
115
this.control = control;
116
if (polarity != POLARITY_NORMAL && polarity != POLARITY_INVERTED) {
117
Infrastructure.fatal("Bad polarity value " + polarity
118
+ ", only POLARITY_NORMAL and POLARITY_INVERTED are "
121
this.polarity = polarity;
122
this.map = new java.util.HashMap();
124
// Fill controlEnable array according to polarity
125
java.util.Arrays.fill(controlEnable, CONTROL_ENABLE[polarity]);
126
java.util.Arrays.fill(controlDisable, CONTROL_DISABLE[polarity]);
128
// Get all nodes in the experimental system
129
String[] paths = control.getDescendents("");
130
for (int ind = 0; ind < paths.length; ind++) {
131
if (isSampler(paths[ind])) {
132
map.put(paths[ind], control.getSubchainPin(paths[ind]));
133
preclear(paths[ind]);
139
* Prints some information about the sampler object, including which
140
* samplers are on each pin.
142
public String toString() {
143
StringBuffer buffy = new StringBuffer("SamplerControl, control="
145
buffy.append("\n Samplers on each pin:");
147
// Convert Collection of values to TreeSet for unique + ordered
148
java.util.Set pins = new java.util.TreeSet(map.values());
150
// For each pin, add which samplers are on it
151
for (java.util.Iterator iter = pins.iterator(); iter.hasNext();) {
152
String pin = (String) iter.next();
153
buffy.append("\n " + pin + ": ");
154
String[] samplers = getSamplersOnPin(pin);
155
for (int ind = 0; ind < samplers.length; ind++) {
156
buffy.append(" " + samplers[ind]);
160
return buffy.toString();
164
* Checks if path to sampler scan chain node has correct format and
165
* identifies an actual sampler.
168
* Path to the scan chain node for the sampler
170
void checkPath(String path) {
171
if (map.containsKey(path) == false) {
172
Infrastructure.fatal("Path " + path + " is not a recognized "
173
+ "sampler" + "\nSee SamplerControl javadoc for how to "
174
+ "identify sampler nodes");
179
* Disable the sampler at the specified <code>SubchainNode</code> by
180
* setting the <tt>calibrate</tt>,<tt>enable</tt>, and
181
* <tt>enable_f</tt> scan chain elements according to the sampler
185
* Path to the scan chain node for the sampler
187
public void clear(String path) {
189
logSet("SamplerControl.clear(): clearing " + path);
190
control.shift(control.getParentChain(path), false, true);
194
* Set the <code>inBits</code> values to disable the sampler at the
195
* specified <code>SubchainNode</code>, but do not shift the data into
196
* the chip. The <tt>calibrate</tt>,<tt>enable</tt>, and
197
* <tt>enable_f</tt> scan chain elements are set according to the sampler
201
* Path to the subchain node for the sampler
203
private void preclear(String path) {
206
for (int ind = 0; ind < CONTROL_NODES.length; ind++) {
207
control.setInBits(path + "." + CONTROL_NODES[ind],
208
controlDisable[ind]);
213
* Enable the sampler at the specified <code>SubchainNode</code> by
214
* setting the <tt>enable</tt> and <tt>enable_f</tt> scan chain elements
215
* according to the sampler polarity. Disables the <tt>calibrate</tt> scan
218
* If <code>enable</code> or <code>enable_f</code> is <tt>true</tt>,
219
* all samplers on the same output pin are disabled before setting the
220
* requested sampler. This is to prevent interference with the measurement.
223
* Path to the scan chain node for the sampler
225
* Whether to enable the standard version of the sampler
227
* Whether to enable the source-follower version of the sampler
229
public void setEnables(String path, boolean enable, boolean enable_f) {
232
if (enable || enable_f) {
236
setOne(path, false, enable, enable_f);
240
* Enable or disable calibration for the sampler at the specified
241
* <code>SubchainNode</code> by setting the <tt>calibrate</tt> scan
242
* chain element according to the sampler polarity.
245
* Path to the scan chain node for the sampler
247
* Whether to configure the sampler for calibration
249
public void setCalibrate(String path, boolean calibrate) {
252
setControl(path, IND_CALIBRATE, calibrate);
253
logSet("SamplerControl.setCalibrate(): setting " + path
255
control.shift(control.getParentChain(path), false, true);
259
* Clears all samplers on same pin as specified sampler.
262
* Path to the scan chain node for the sampler
264
private void clearSiblings(String path) {
265
String targetPin = (String) map.get(path);
266
String[] paths = getSamplersOnPin(targetPin);
267
for (int ind = 0; ind < paths.length; ind++) {
273
* Calibrates the specified sampler, writing the current versus voltage to
274
* the provided file. Assumes that <code>setEnables()</code> has been used
275
* to set at least one of <code>enable</code> and <code>enable_f</code>.
278
* File to write the calibration data to
280
* Path to the scan chain node for the sampler
282
* Object specifying the IV curve to measure
283
* @throws IOException
285
public void calibrate(String fileName, String path, AmpsVsVolts ivspec)
287
PrintWriter file = new PrintWriter(new FileWriter(fileName));
288
file.println("# calibration (voltage, current) for sampler at path "
290
setCalibrate(path, true);
291
ivspec.measure(file);
292
setCalibrate(path, false);
297
* Returns <tt>true</tt> if the node at the specified path controls a
298
* sampler. See comments at top for the necessary conditions.
301
* path name to potential sampler control
302
* @return whether specified node controls a sampler
304
private boolean isSampler(String path) {
305
TestNode node = (TestNode) control.findNode(path);
306
if (node.getChildCount() < 3 || (node instanceof SubchainNode == false))
309
int[] numInstances = getNumInstances(node);
311
boolean oneOfEach = true, anyPresent = false;
312
for (int ind = 0; ind < CONTROL_NODES.length; ind++) {
313
if (numInstances[ind] != 1)
315
if (numInstances[ind] > 0)
320
if (control.getSubchainPin(path).length() <= 0) {
321
System.err.println("*** SamplerControl warning: node " + path
322
+ "\nappears to be a sampler, but does not have"
323
+ " a valid pin name. Please set the "
324
+ "\n'pin' attribute in the XML file or use"
325
+ " ChainControl.setSubchainPin()");
333
System.err.println("*** SamplerControl warning: node " + path
334
+ "\nmay be a sampler that does not contain "
336
+ "\nSamplers must contain exactly one each of '"
337
+ CONTROL_NODES[0] + "', '" + CONTROL_NODES[1] + "', and '"
338
+ CONTROL_NODES[2] + "'");
346
* Return path strings of all samplers on specified pin
349
* name of sampler current output pin
350
* @return path strings of all samplers on <code>targetPin</code>
352
public String[] getSamplersOnPin(String targetPin) {
353
java.util.List list = new java.util.ArrayList();
354
for (java.util.Iterator iter = map.keySet().iterator(); iter.hasNext();) {
355
String path = (String) iter.next();
356
String pin = (String) map.get(path);
357
if (pin.equals(targetPin)) {
361
String[] paths = new String[list.size()];
362
for (int ind = 0; ind < paths.length; ind++) {
363
paths[ind] = (String) list.get(ind);
369
* Enable or disable the specified sampler control
374
* Index of control in CONTROL_NODES array
376
* Whether to enable the control
378
private void setControl(String path, int ind, boolean enable) {
380
control.setInBits(path + "." + CONTROL_NODES[ind],
383
control.setInBits(path + "." + CONTROL_NODES[ind],
384
controlDisable[ind]);
389
* Enable the sampler at the specified <code>SubchainNode</code> by
390
* setting the <tt>calibrate</tt>,<tt>enable</tt>, and
391
* <tt>enable_f</tt> scan chain elements according to the sampler
392
* polarity. Does not affect any other samplers.
395
* Path to the scan chain node for the sampler
397
* Whether to configure the sampler for calibration
399
* Whether to enable the standard version of the sampler
401
* Whether to enable the source-follower version of the sampler
403
private void setOne(String path, boolean calibrate, boolean enable,
406
if (calibrate && !enable && !enable_f) {
407
System.out.println("WARNING: Odd setting for sampler at " + path
408
+ ": calibrate true, but enable and enable_f false.");
411
setControl(path, IND_CALIBRATE, calibrate);
412
setControl(path, IND_ENABLE, enable);
413
setControl(path, IND_ENABLE_F, enable_f);
415
logSet("SamplerControl.setOne(): setting " + path);
416
control.shift(control.getParentChain(path), false, true);
420
* Count number of children that are named after each of the required nodes
423
* @return number of children that have each of the required names
425
private int[] getNumInstances(TestNode node) {
426
int numInstances[] = new int[CONTROL_NODES.length];
427
for (int kidIndex = 0; kidIndex < node.getChildCount(); kidIndex++) {
428
TestNode kid = (TestNode) node.getChildAt(kidIndex);
429
String kidName = kid.getName();
430
for (int ind = 0; ind < CONTROL_NODES.length; ind++) {
431
if (kidName.equals(CONTROL_NODES[ind])) {
432
String kidPath = kid.getPathString(1);
433
int length = control.getLength(kidPath);
435
numInstances[ind] += 1;
437
System.err.println("*** SamplerControl warning: node "
438
+ kidPath + " has length " + length
439
+ ", should have length 1");
448
public static void main(String[] args) {
449
ChainControl control = new ChainControl("heater.xml");
451
control.setSubchainPin("heater.SW_expC.transmit.sample_cT", "frog");
452
control.setSubchainPin("heater.NW_expC.transmit.sample_cT", "frog");
453
control.setSubchainPin("heater.SE_expC.transmit.sample_cT", "toad");
454
control.setSubchainPin("heater.NE_expC.transmit.sample_cT", "bar");
456
SamplerControl samplers = new SamplerControl(control, POLARITY_INVERTED);