~ubuntu-branches/ubuntu/oneiric/electric/oneiric

« back to all changes in this revision

Viewing changes to com/sun/electric/tool/simulation/test/BypassJtagTester.java

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2010-01-09 16:26:04 UTC
  • mfrom: (1.1.4 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100109162604-1ypvmy8ijmlc6oq7
Tags: 8.10-1
* New upstream version.
* debian/control
  - Add libjava3d-java and quilt build dependencies.
  - Update standards version to 3.8.3.
  - Add libjava3d-java as recommends to binary package.
* debian/rules
  - Use quilt patch system instead of simple patchsys.
  - Add java3d related jar files to DEB_JARS.
* debian/patches/*
  - Update as per current upstream source. Convert to quilt.
* debian/ant.properties
  - Do not disable 3D plugin anymore.
  - Use new property to disable compilation of OS X related classes.
* debian/wrappers/electric
  - Add java3d related jar files to runtime classpath.
* debian/README.source
  - Change text to the appropriate one for quilt.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package com.sun.electric.tool.simulation.test;
 
2
 
 
3
import java.util.List;
 
4
import java.util.ArrayList;
 
5
 
 
6
/**
 
7
 * Created by IntelliJ IDEA.
 
8
 * User: gainsley
 
9
 * Date: Sep 20, 2005
 
10
 * Time: 10:00:45 AM
 
11
 
 
12
 * Copyright (c) 2004,2005 by Sun Microsystems, Inc.
 
13
 *
 
14
 * Parent class for simulation jtag testers.
 
15
 * The BypassJtagTester implements a direct read/write of scan chains,
 
16
 * taking advantage of the simulator's ability to directly set and get
 
17
 * node values within the circuit. This bypasses the costly act of
 
18
 * shifting all the scan chain bits in serially. Instead, it writes in
 
19
 * parallel at once. This mode is enabled by
 
20
 * {@link SimulationModel#setBypassScanning(boolean)}
 
21
 * <P>
 
22
 * A further optimization is to only read from elements whose state is unknown,
 
23
 * and only write to elements whose state is unknown or changing. This
 
24
 * reduces the number of direct reads and writes when few bits
 
25
 * change between shifts. Only scan chain elements with shadow registers,
 
26
 * or dual ported shadow registers, can take advantage of this functionality.
 
27
 * This option is enabled by
 
28
 * {@link SimulationModel#setOptimizedDirectReadsWrites(boolean)} 
 
29
 */
 
30
public abstract class BypassJtagTester extends JtagTester {
 
31
 
 
32
    protected final SimulationModel model;
 
33
    protected float tapVolt;      // ignored at this time
 
34
    protected double delay;       // delay in ns
 
35
 
 
36
    private static final boolean DEBUG = false;
 
37
 
 
38
    BypassJtagTester(SimulationModel nm) {
 
39
        this.model = nm;
 
40
    }
 
41
 
 
42
    void configure(float tapVolt, long kiloHerz) {
 
43
        this.tapVolt = tapVolt;
 
44
        this.delay = (1.0/kiloHerz * 1e6) / 2;
 
45
    }
 
46
 
 
47
    void disconnect() {}
 
48
 
 
49
    void setLogicOutput(int index, boolean newLevel) {
 
50
        System.out.println("Nanosim JtagTester does not support 'setLogicOutput("+index+", "+newLevel+"). Use LogicSettable instead.");
 
51
    }
 
52
 
 
53
    public boolean isBypassScanning() {
 
54
        return model.isBypassScanning();
 
55
    }
 
56
 
 
57
    // ==========================================================
 
58
 
 
59
    protected void doBypassScanning(ChainNode chain, boolean readEnable, boolean writeEnable) {
 
60
        // this mode bypasses scanning, and reads/writes directly
 
61
        // to the bits the scan chain controls, as long as those
 
62
        // nets have been defined in the XML file.
 
63
        if (DEBUG) System.out.println("Scanning in "+chain.getName()+" in bypass-scanning mode");
 
64
 
 
65
        if (readEnable) {
 
66
            chain.getOutBits().put(0, readDirect(chain));
 
67
        } else
 
68
            chain.getOutBits().putIndiscriminate(0, chain.getOutBitsExpected());
 
69
        
 
70
        if (writeEnable) {
 
71
            BitVector bitsToCheck = writeDirect(chain);
 
72
            checkDataNets(chain, 0, bitsToCheck);
 
73
            checkDataNets(chain, 1, bitsToCheck);
 
74
        }
 
75
    }
 
76
 
 
77
    /**
 
78
     * Get a list of DataNets from the chain.
 
79
     * @param chain the chain to read
 
80
     * @param set which set to get. Currently only two supported, so only 0 or 1
 
81
     * @return a list of DataNets of the (hierarchical) data out net names.
 
82
     * May contain null for undefined nets
 
83
     */
 
84
    protected static List getDataNets(SubchainNode chain, int set) {
 
85
        // get the scan chain data nets node corresponding to the chain
 
86
        MyTreeNode system = chain.getParent().getParent();    // this is the system node
 
87
        MyTreeNode scanchainnets = MyTreeNode.getNode(system, XMLIO.SCAN_CHAIN_DATA_NETS);
 
88
        if (scanchainnets == null) return getDataNetsOld(chain, set);       // must be using old version
 
89
 
 
90
        SubchainNode datachain = (SubchainNode)MyTreeNode.getNode(scanchainnets, chain.getName());
 
91
        if (datachain == null) {
 
92
            // if more than one jtag contoller, datanet chain name is prepended with chip name
 
93
            MyTreeNode chip = chain.getParent();
 
94
            datachain = (SubchainNode)MyTreeNode.getNode(scanchainnets, chip.getName()+"_"+chain.getName());
 
95
        }
 
96
        if (datachain == null) return getDataNetsOld(chain, set);
 
97
        
 
98
        List datanets = new ArrayList();
 
99
        for (int i=0; i<datachain.getChildCount(); i++) {
 
100
            SubchainNode subnode = (SubchainNode)datachain.getChildAt(i);
 
101
            if (set == 0) {
 
102
                datanets.add(subnode.getDataNet());
 
103
            } else {
 
104
                datanets.add(subnode.getDataNet2());
 
105
            }
 
106
        }
 
107
        return datanets;
 
108
    }
 
109
 
 
110
    /**
 
111
     * Get a list of DataNets from the chain.
 
112
     * @param chain the chain to read
 
113
     * @param set which set to get. Currently only two supported, so only 0 or 1
 
114
     * @return a list of DataNets of the (hierarchical) data out net names.
 
115
     * May contain null for undefined nets
 
116
     * @deprecated this was used when the xml file contains data nets specified hierarchically
 
117
     * along with the scan chain bits. I have since split the data nets out into a separate,
 
118
     * flat listing.
 
119
     */
 
120
    protected static List getDataNetsOld(SubchainNode chain, int set) {
 
121
        // get names of data out bits
 
122
        if (chain.getChildCount() == 0) {
 
123
            List list = new ArrayList();
 
124
            SubchainNode.DataNet dataNet;
 
125
            if (set == 0) dataNet = chain.getDataNet();
 
126
            else dataNet = chain.getDataNet2();
 
127
 
 
128
            if (dataNet == null || dataNet.getName().equals("")) {
 
129
                // pad list with correct number of null entries
 
130
                for (int i=0; i<chain.getLength(); i++)
 
131
                    list.add(null);
 
132
                return list;
 
133
            }
 
134
 
 
135
            MyTreeNode [] hier = chain.getParent().getHierarchy();
 
136
            StringBuffer newPath = new StringBuffer();
 
137
            for (int j=0; j<hier.length; j++) {
 
138
                // remove the chip name and the chain name (3), as they are
 
139
                // not part of the spice hierarchy.
 
140
                if (j<3) continue;
 
141
                newPath.append("X"+hier[j].getName()+".");
 
142
            }
 
143
            //newPath.append("X"+chain.getName()+".");
 
144
 
 
145
            // special case: if Fake Chain, do not use the name in the
 
146
            // hierarchical path to the dataNet. This is because schematics
 
147
            // that do not have scanChainElements must refer to data nets
 
148
            // in the schematic, which are at a level above where a scanChain.dataNet
 
149
            // net would be
 
150
            boolean fakeChain = false;
 
151
            if (chain.getParentChain().getOpcode().equals("fakeChain")) {
 
152
                // this is a fake chain
 
153
                fakeChain = true;
 
154
            }
 
155
 
 
156
            Name netName = Name.findName(dataNet.getName());
 
157
            if (fakeChain) {
 
158
                for (int j=0; j<netName.busWidth(); j++) {
 
159
                    String net = netName.subname(j).toString();
 
160
                    // create hierarchical spice net name
 
161
                    SubchainNode.DataNet singleNet = new SubchainNode.DataNet(newPath.toString() + net,
 
162
                            dataNet.isReadable(), dataNet.isWriteable(), dataNet.isInverted());
 
163
                    list.add(singleNet);
 
164
                    //System.out.println("DataNet added: "+singleNet);
 
165
                }
 
166
            } else {
 
167
                // chain may be bussed, bussed name should match length of chain
 
168
                Name dataName = Name.findName(chain.getName());
 
169
                for (int i=0; i<dataName.busWidth(); i++) {
 
170
                    netName = Name.findName(dataNet.getName());
 
171
                    for (int j=0; j<netName.busWidth(); j++) {
 
172
                        String net = "x" + dataName.subname(i).toString() + "." + netName.subname(j).toString();
 
173
                        // create hierarchical spice net name
 
174
                        SubchainNode.DataNet singleNet = new SubchainNode.DataNet(newPath.toString() + net,
 
175
                                dataNet.isReadable(), dataNet.isWriteable(), dataNet.isInverted());
 
176
                        list.add(singleNet);
 
177
                        //System.out.println("DataNet added: "+singleNet);
 
178
                    }
 
179
                }
 
180
            }
 
181
 
 
182
            if (list.size() != chain.getLength()) {
 
183
                System.out.println("Error: data net list of size "+list.size()+" does not match length of chain "+chain.getName()+" of length "+chain.getLength());
 
184
                list.clear();
 
185
                for (int i=0; i<chain.getLength(); i++)
 
186
                    list.add(null);
 
187
                return list;
 
188
            }
 
189
            return list;
 
190
        } else {
 
191
            // this just contains more sub nodes
 
192
            List list = new ArrayList();
 
193
            for (int i=0; i<chain.getChildCount(); i++) {
 
194
                SubchainNode subnode = (SubchainNode)chain.getChildAt(i);
 
195
                list.addAll(getDataNets(subnode, set));
 
196
            }
 
197
            return list;
 
198
        }
 
199
    }
 
200
 
 
201
 
 
202
    /**
 
203
     * Check that the bits in the chain have been applied to the dataNets for the
 
204
     * scan chain. This only applies for scan bits that have their "dataNet" or
 
205
     * "dataNet2" property in the XML file.
 
206
     * @param chain the scan chain
 
207
     * @param set which set of nets to check.  Only 0 and 1 currently.
 
208
     * @param bitsToCheck a map of which bits to check
 
209
     * @return true if a discrepancy found, false otherwise.
 
210
     */
 
211
    protected boolean checkDataNets(ChainNode chain, int set, BitVector bitsToCheck) {
 
212
        boolean foundDiscrepancy = false;
 
213
        List dataNets = getDataNets(chain, set);
 
214
        if (bitsToCheck.getNumBits() != dataNets.size()) {
 
215
            System.out.println("Can't check dataNets, bitsToCheck size does not match chain length");
 
216
            return false;
 
217
        }
 
218
 
 
219
        for (int i=0; i<dataNets.size(); i++) {
 
220
            SubchainNode.DataNet dataNet = (SubchainNode.DataNet)dataNets.get(i);
 
221
            //System.out.println(i+":\t"+netName);
 
222
            if (dataNet == null) continue;        // undefined net
 
223
            if (dataNet.isWriteable() && bitsToCheck.get(i)) {
 
224
                // check that data in inbits was written
 
225
                int simState = model.getNodeState(formatDataNetName(dataNet.getName()));
 
226
                int setState = chain.getInBits().get(i) ? 1 : 0;
 
227
                if (dataNet.isInverted())
 
228
                    setState = (setState==1 ? 0 : 1);
 
229
                if (simState != setState) {
 
230
                    System.out.println("Error! Attempted to set bit '"+formatDataNetName(dataNet.getName())+"' to "+setState+
 
231
                            " via the scan chain at time "+model.getSimulationTime()+", but its state is "+simState);
 
232
                    foundDiscrepancy = true;
 
233
                } else {
 
234
                    if (DEBUG) {
 
235
                        System.out.println("Checked "+formatDataNetName(dataNet.getName())+" read "+simState+": ok");
 
236
                    }
 
237
                }
 
238
            }
 
239
        }
 
240
        return foundDiscrepancy;
 
241
    }
 
242
 
 
243
    /**
 
244
     * Read directly from the data bits the scan chain controls, rather than
 
245
     * applying "read" and scanning out the data. This is much faster than
 
246
     * scanning them out.
 
247
     * @param chain the scan chain
 
248
     * @return a BitVector of the bits read directly out
 
249
     */
 
250
    protected BitVector readDirect(ChainNode chain) {
 
251
        List dataNets = getDataNets(chain, 0);
 
252
        List dataNets2 = getDataNets(chain, 1);
 
253
 
 
254
        BitVector outBits = new BitVector(chain.getOutBits().getNumBits(), "outBits");
 
255
        int bitsRead = 0;
 
256
        int numOptimizedReads = 0;
 
257
        for (int i=0; i<outBits.getNumBits(); i++) {
 
258
            SubchainNode node = chain.findNodeAtIndex(i);
 
259
            if (!node.isReadable()) continue;
 
260
 
 
261
            if (model.getOptimizedDirectReadsWrites()) {
 
262
                if (node.usesShadow() && !node.usesDualPortedShadow()) {
 
263
                    // no need to read, just use last known good value
 
264
                    if (chain.getShadowState().isValid(i)) {
 
265
                        outBits.set(i, chain.getShadowState().get(i));
 
266
                        numOptimizedReads++;
 
267
                        continue;
 
268
                    }
 
269
                }
 
270
            }
 
271
 
 
272
            SubchainNode.DataNet dataNet = (SubchainNode.DataNet)dataNets.get(i);
 
273
            SubchainNode.DataNet dataNet2 = (SubchainNode.DataNet)dataNets2.get(i);
 
274
 
 
275
            int state = readDirect(dataNet);
 
276
            int state2 = readDirect(dataNet2);
 
277
 
 
278
            if (state >=0 && state2 >= 0) {
 
279
                // both were read and are valid, check that they match
 
280
                if (state != state2) {
 
281
                    System.out.println("Error! Inconsistency reading directly from scan chain data bit "+i+
 
282
                            " of chain '"+chain.getName()+"', "+formatDataNetName(dataNet.getName())+" is "+state+" and "+
 
283
                            dataNet2.getName()+" is "+state2);
 
284
                }
 
285
            }
 
286
            if (state < 0) {
 
287
                state = state2;                 // state holds any valid state
 
288
            }
 
289
            if (state < 0) {
 
290
                // nothing valid read, set it to whatever was shifted in
 
291
                if (chain.getInBits().isValid(i))
 
292
                    state = chain.getInBits().get(i) ? 1 : 0;
 
293
                if (state == -2) bitsRead++;        // bit was read, just in undefined state
 
294
            } else {
 
295
                bitsRead++;
 
296
            }
 
297
            outBits.set(i, state==1);
 
298
        }
 
299
        String optReadsInfo = "";
 
300
        if (numOptimizedReads > 0) {
 
301
            optReadsInfo = " "+numOptimizedReads+" optimized reads.";
 
302
        }
 
303
        if (printInfo)
 
304
                System.out.println("Info: Read directly "+bitsRead+" bits from chain '"+chain.getName()+
 
305
                                "' of length "+chain.getOutBits().getNumBits()+
 
306
                                " bits (others unchanged)."+optReadsInfo);
 
307
        return outBits;
 
308
    }
 
309
 
 
310
    /**
 
311
     * Read directly from a scan chain data output
 
312
     * @param dataNet the data net to read from
 
313
     * @return the value read. 0 or 1 valid values, -1 on error
 
314
     */
 
315
    private int readDirect(SubchainNode.DataNet dataNet) {
 
316
        if (dataNet == null) return -1;
 
317
        if (!dataNet.isReadable()) return -1;
 
318
 
 
319
        int state = model.getNodeState(formatDataNetName(dataNet.getName()));
 
320
        if (DEBUG) System.out.println("Read directly "+(dataNet.isInverted()?"(inverted)":"")+" from net "+formatDataNetName(dataNet.getName())+": "+state);
 
321
        if (state == -2) System.out.println("Warning, read intermediate (undefined) voltage state from net "+formatDataNetName(dataNet.getName())+" at time "+model.getSimulationTime());
 
322
        if (state < 0) return state;
 
323
        if (dataNet.isInverted()) state = state==1 ? 0 : 1;
 
324
        return state;
 
325
    }
 
326
 
 
327
    /**
 
328
     * Write scan chain data directly to the data bits, rather than
 
329
     * scanning them in and then applying "write".  This should be much
 
330
     * faster than scanning them in.
 
331
     * @param chain the scan chain
 
332
     * @return which bits were written. True values mean the bit in that position was written.
 
333
     */
 
334
    protected BitVector writeDirect(ChainNode chain) {
 
335
        List dataNets = getDataNets(chain, 0);
 
336
        List dataNets2 = getDataNets(chain, 1);
 
337
 
 
338
        int dataNetsWritten = 0;
 
339
        int dataNet2sWritten = 0;
 
340
        int numOptimizedWrites = 0;
 
341
        List writtenDataNets = new ArrayList();
 
342
        BitVector bitsWritten = new BitVector(chain.getInBits().getNumBits(), "bitsWritten");
 
343
        for (int i=0; i<chain.getInBits().getNumBits(); i++) {
 
344
            SubchainNode node = chain.findNodeAtIndex(i);
 
345
            bitsWritten.set(i, false);
 
346
            if (!node.isWriteable()) continue;
 
347
 
 
348
            if (model.getOptimizedDirectReadsWrites()) {
 
349
                if (node.usesShadow() || node.usesDualPortedShadow()) {
 
350
                    // shadow registers can only be modified by the scan chain (or master clear)
 
351
                    // If the shadow state is valid, and is the same value as we want to write,
 
352
                    // we can just skip this write.
 
353
                    if (chain.getShadowState().isValid(i) && chain.getShadowState().get(i) == chain.getInBits().get(i)) {
 
354
                        numOptimizedWrites++;
 
355
                        continue;
 
356
                    }
 
357
                }
 
358
            }
 
359
            if (chain.getInBits().isValid(i)) {
 
360
                int state = chain.getInBits().get(i) ? 1 : 0;
 
361
                SubchainNode.DataNet dataNet = (SubchainNode.DataNet)dataNets.get(i);
 
362
                SubchainNode.DataNet dataNet2 = (SubchainNode.DataNet)dataNets2.get(i);
 
363
                if (writeDirect(dataNet, state)) {
 
364
                    writtenDataNets.add(dataNet);
 
365
                    bitsWritten.set(i, true);
 
366
                    dataNetsWritten++;
 
367
                }
 
368
                if (writeDirect(dataNet2, state)) {
 
369
                    writtenDataNets.add(dataNet);
 
370
                    bitsWritten.set(i, true);
 
371
                    dataNet2sWritten++;
 
372
                }
 
373
            } else {
 
374
                System.out.println("Could not write bit "+i+" of chain "+chain.getName()+" because it is not in a valid state");
 
375
            }
 
376
            // Code in ChainNode maintains shadowState
 
377
            //if (node.usesShadow() || node.usesDualPortedShadow())
 
378
            //    chain.shadowState.set(i, state==1);
 
379
        }
 
380
        // apply write (above writes)
 
381
        model.waitNS(delay*3);
 
382
        // release writes, unless it is a fake chain control
 
383
        if (!chain.getOpcode().equals("fakeChain")) {
 
384
            model.releaseNodes(getNames(writtenDataNets));
 
385
        }
 
386
        String optWritesInfo = "";
 
387
        if (numOptimizedWrites > 0) {
 
388
            optWritesInfo = " "+numOptimizedWrites+" optimized writes.";
 
389
        }
 
390
        model.waitNS(delay*1);
 
391
        if (printInfo)
 
392
                System.out.println("Info: Wrote directly "+dataNetsWritten+" bits and "+
 
393
                                dataNet2sWritten+" secondary bits from scan chain '"+chain.getName()+ "' of length "+
 
394
                                chain.getInBits().getNumBits()+" bits."+optWritesInfo);
 
395
        return bitsWritten;
 
396
    }
 
397
 
 
398
    /**
 
399
     * Write directly to a scan chain data output
 
400
     * @param dataNet the data net to write to
 
401
     * @param state the state to write (0 or 1)
 
402
     * @return true if written, false if not
 
403
     */
 
404
    private boolean writeDirect(SubchainNode.DataNet dataNet, int state) {
 
405
        if (dataNet == null) return false;
 
406
        if (!dataNet.isWriteable()) return false;
 
407
        if (dataNet.isInverted()) state = (state==1) ? 0 : 1;
 
408
        model.setNodeState(formatDataNetName(dataNet.getName()), state);
 
409
        if (DEBUG) System.out.println("Wrote directly "+state+" to net "+formatDataNetName(dataNet.getName()));
 
410
        return true;
 
411
    }
 
412
 
 
413
    /**
 
414
     * Perform any formatting of the data net name specific to
 
415
     * the simulator, such as replaced unallowed characters.
 
416
     * @param dataNetName the dataNetName from the XML file,
 
417
     * contains 'x' in front of each instance, delimited by '.',
 
418
     * all spice characters allowed
 
419
     * @return a fitlered dataNetName
 
420
     */
 
421
    String formatDataNetName(String dataNetName) {
 
422
        return dataNetName;
 
423
    }
 
424
 
 
425
    private List getNames(List dataNets) {
 
426
        List names = new ArrayList();
 
427
        for (int i=0; i<dataNets.size(); i++) {
 
428
            SubchainNode.DataNet dataNet = (SubchainNode.DataNet)dataNets.get(i);
 
429
            if (dataNet == null) continue;
 
430
            names.add(formatDataNetName(dataNet.getName()));
 
431
        }
 
432
        return names;
 
433
    }
 
434
}