~ubuntu-branches/ubuntu/maverick/electric/maverick

« back to all changes in this revision

Viewing changes to com/sun/electric/tool/simulation/test/NanosimModel.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.*;
 
4
import java.util.regex.Pattern;
 
5
import java.util.regex.Matcher;
 
6
import java.io.*;
 
7
 
 
8
/**
 
9
 * Created by IntelliJ IDEA.
 
10
 * User: gainsley
 
11
 * Date: Jun 29, 2005
 
12
 * Time: 4:03:18 PM
 
13
 * Copyright (c) 2004,2005 by Sun Microsystems, Inc.
 
14
 *
 
15
 */
 
16
public class NanosimModel extends SimulationModel {
 
17
 
 
18
    protected static final boolean DEBUG = false;
 
19
 
 
20
    /** list of jtag testers */
 
21
    protected final List jtagTesters;
 
22
    /** list of logic settables */
 
23
    protected final List logicSettables;
 
24
 
 
25
    protected double simTime;         // current simulation time in ns
 
26
    protected double vdd;
 
27
    protected double timeStep;        // simulation time step in ns
 
28
    protected final HashMap nodesToSet = new HashMap();   // key: node name, value: Double voltage
 
29
    protected boolean assuraRCXNetlist = false;
 
30
    protected boolean starRCXTNetlist = false;
 
31
 
 
32
    /**
 
33
     * Create a new NanosimModel to simulate the behavior of the real chip
 
34
     */
 
35
    public NanosimModel() {
 
36
        super("Nanosim", "quit", "ERROR", "");
 
37
        jtagTesters = new ArrayList();
 
38
        logicSettables = new ArrayList();
 
39
        simTime = 0;
 
40
        vdd = 0;
 
41
    }
 
42
 
 
43
    public JtagTester createJtagTester(String tckName, String tmsName, String trstbName, String tdiName, String tdobName) {
 
44
        if (isProcessRunning()) {
 
45
            System.out.println("Error: JtagTester test device must be created before process is started.");
 
46
            return null;
 
47
        }
 
48
        NanosimJtagTester tester = new NanosimJtagTester(this, tckName, tmsName, trstbName, tdiName, tdobName);
 
49
        jtagTesters.add(tester);
 
50
        return tester;
 
51
    }
 
52
 
 
53
    /**
 
54
     * Create a subchain tester based on the 8- or 9-wire jtag interface.
 
55
     * jtag[8:0] = {scan_data_return, phi2_return, phi1_return, rd, wr, phi1, phi2, sin, mc*}
 
56
     * Note that mc is not present on older designs, so they are jtag[8:1].
 
57
     * @param jtagInBus the name of the 9-bit wide input bus, i.e. "jtagIn" or "jtagIn[8:0]"
 
58
     * @param jtagOutBus the name of the 9-bit wide output bus, i.e. "jtagOut" or "jtagOut[8:0]"
 
59
     */
 
60
    public JtagTester createJtagSubchainTester(String jtagInBus, String jtagOutBus) {
 
61
        if (isProcessRunning()) {
 
62
            System.out.println("Error: JtagTester test device must be created before process is started.");
 
63
            return null;
 
64
        }
 
65
        NanosimJtagSubchainTester tester = new NanosimJtagSubchainTester(this, jtagInBus, jtagOutBus);
 
66
        jtagTesters.add(tester);
 
67
        return tester;
 
68
    }
 
69
 
 
70
    /**
 
71
     * Create a subchain tester based on the 5-wire jtag interface.
 
72
     * @param phi2 name of the phi2 signal
 
73
     * @param phi1 name of the phi1 signal
 
74
     * @param write name of the write signal
 
75
     * @param read name of the read signal
 
76
     * @param sin name of the scan data in signal
 
77
     * @param sout name of the scan data out signal
 
78
     */
 
79
    public JtagTester createJtagSubchainTester(String phi2, String phi1, String write, String read, String sin, String sout) {
 
80
        if (isProcessRunning()) {
 
81
            System.out.println("Error: JtagTester test device must be created before process is started.");
 
82
            return null;
 
83
        }
 
84
        NanosimJtagSubchainTester tester = new NanosimJtagSubchainTester(this, phi2, phi1, write, read, sin, sout);
 
85
        jtagTesters.add(tester);
 
86
        return tester;
 
87
    }
 
88
 
 
89
    public LogicSettable createLogicSettable(String portName) {
 
90
        if (isProcessRunning()) {
 
91
            System.out.println("Error: LogicSettable test device must be created before process is started.");
 
92
            return null;
 
93
        }
 
94
        NanosimLogicSettable ls = new NanosimLogicSettable(this, portName);
 
95
        logicSettables.add(ls);
 
96
        return ls;
 
97
    }
 
98
 
 
99
    public LogicSettable createLogicSettable(List portNames) {
 
100
        if (portNames == null || portNames.size() < 1) {
 
101
            System.out.println("Error: createLogicSettable given null or empty list of ports");
 
102
            return null;
 
103
        }
 
104
        System.out.println("Error: createLogicSettable(List) is not supported by Nanosim, only using first port "+portNames.get(0));
 
105
        return new NanosimLogicSettable(this, (String)portNames.get(0));
 
106
    }
 
107
 
 
108
    public void disableNode(String node) {
 
109
        issueCommand("force_node_v v=0 no="+node);
 
110
        waitNS(timeStep);
 
111
    }
 
112
 
 
113
    public void enableNode(String node) {
 
114
        issueCommand("rel_node_v no="+node);
 
115
        waitNS(timeStep);
 
116
    }
 
117
 
 
118
    public double getSimulationTime() {
 
119
        return simTime;
 
120
    }
 
121
 
 
122
    boolean start_(String command, String simFile, int recordSim) {
 
123
        // first, find out the nanosim version, as that determines the prompt in interactive mode
 
124
        // setup the reader which will read the output of the process
 
125
        PipedOutputStream ostream = new PipedOutputStream();
 
126
        BufferedReader reader;
 
127
        try {
 
128
            PipedInputStream istream = new PipedInputStream(ostream);
 
129
            reader = new BufferedReader(new InputStreamReader(istream));
 
130
        } catch (java.io.IOException e) {
 
131
            System.out.println("Unable to create pipe to process output: "+e.getMessage());
 
132
            return false;
 
133
        }
 
134
        ExecProcess process = new ExecProcess(command+" --version", null, null, ostream, ostream);
 
135
        process.start();
 
136
        boolean found = false;
 
137
        String version = null;
 
138
        StringBuffer buf = new StringBuffer();
 
139
        try {
 
140
            String line;
 
141
            while ((line = reader.readLine()) != null) {
 
142
                buf.append(line+"\n");
 
143
                if (found) continue;
 
144
                String [] args = line.split("\\s+");
 
145
                if (args.length < 4) continue;
 
146
                if (args[1].equals("Version")) {
 
147
                    version = args[3];
 
148
                    setPrompt("Ver "+version+" >");
 
149
                    found = true;
 
150
                }
 
151
            }
 
152
            reader.close();
 
153
        } catch (java.io.IOException e) {
 
154
            if (!found) {
 
155
                System.out.println("Error determining nanosim version: "+e.getMessage());
 
156
                System.out.println(buf);
 
157
                return false;
 
158
            }
 
159
        }
 
160
        if (!found) {
 
161
            System.out.println("Error determining nanosim version");
 
162
            System.out.println(buf);
 
163
            return false;
 
164
        }
 
165
        if (DEBUG)
 
166
            System.out.println("Using nanosim version "+version);
 
167
 
 
168
        // check if simfile is from assura RCX
 
169
        // if it is, we will have to replace hierarchy delimiter '.' with '/'
 
170
        try {
 
171
            BufferedReader freader = new BufferedReader(new FileReader(simFile));
 
172
            // PROGRAM will be in the first 10 or so lines, so search up till line 20
 
173
            for (int i=0; i<20; i++) {
 
174
                String line = freader.readLine();
 
175
                if (line == null) break;
 
176
                if (line.matches("\\*  PROGRAM .*?assura.*")) {
 
177
                    assuraRCXNetlist = true;
 
178
                    System.out.println("Info: Running on Assura extracted netlist, will replace all '.' in net names with '/'");
 
179
                    break;
 
180
                } else if (line.matches("\\*|PROGRAM .*?Star-RCXT.*")) {
 
181
                    starRCXTNetlist = true;
 
182
                    System.out.println("Info: Running on Star-RCXT extracted netlist, will replace all '.x' in net names with '/'");
 
183
                    break;
 
184
                }
 
185
            }
 
186
        } catch (IOException e) {
 
187
            System.out.println(e.getMessage());
 
188
            return false;
 
189
        }
 
190
 
 
191
        // max sim time (-t) is 90071s
 
192
        String cmd = command+" -n "+simFile+" -i -t 90071s -o "+simFile;
 
193
        if (!startProcess(cmd, null, null, simFile+".run"))
 
194
            return false;
 
195
 
 
196
        // get value of vdd
 
197
        vdd = getNodeVoltage("vdd");
 
198
        if (DEBUG)
 
199
            System.out.println("Using VDD of "+vdd);
 
200
        timeStep = getSimTres();
 
201
        if (DEBUG)
 
202
            System.out.println("Using time step of "+timeStep+" ns");
 
203
 
 
204
        // initialize test devices
 
205
        for (Iterator it = logicSettables.iterator(); it.hasNext(); ) {
 
206
            NanosimLogicSettable ls = (NanosimLogicSettable)it.next();
 
207
            if (!ls.init()) {
 
208
                System.out.println("LogicSettable initialization failed, aborting.");
 
209
                return false;
 
210
            }
 
211
        }
 
212
        for (Iterator it = jtagTesters.iterator(); it.hasNext(); ) {
 
213
            JtagTester tester = (JtagTester)it.next();
 
214
            tester.reset();
 
215
        }
 
216
        return true;
 
217
    }
 
218
 
 
219
    /**
 
220
     * Get the voltage of VDD for the simulation.  The simulation must have been
 
221
     * started for this method to return a valid value.
 
222
     * @return the VDD voltage, in volts.
 
223
     */
 
224
    public double getVdd() { return vdd; }
 
225
 
 
226
    protected static final Pattern patSimTime = Pattern.compile("The simulation time is\\s+: ([0-9\\.]+) ns");
 
227
 
 
228
    public void wait(float seconds) {
 
229
        waitNS(seconds*1.0e9);
 
230
    }
 
231
 
 
232
    /**
 
233
     * Wait the specified number of nano-seconds.  In this case, this means
 
234
     * run the simulator until that point in time, when control will return
 
235
     * to the test software.
 
236
     * @param nanoseconds the time to wait (simulate) in nanoseconds
 
237
     */
 
238
    public void waitNS(double nanoseconds) {
 
239
        waitNS(nanoseconds, true);
 
240
    }
 
241
 
 
242
    // internal only method; applyVoltages calls this with the boolean false so no infinite recursion
 
243
    protected void waitNS(double nanoseconds, boolean applyVoltages) {
 
244
/*
 
245
        issueCommand("get_sim_time");
 
246
        StringBuffer buf = getLastCommandOutput();
 
247
        Matcher m = patSimTime.matcher(buf.toString());
 
248
        double cur_time = 0;
 
249
        if (m.find()) {
 
250
            try {
 
251
                cur_time = Double.parseDouble(m.group(1));
 
252
            } catch (NumberFormatException e) {
 
253
                System.out.println("Error in get_sim_time, could not parse time "+m.group(1)+" from:\n"+buf);
 
254
                return;
 
255
            }
 
256
        } else {
 
257
            System.out.println("Error determining current time, get_sim_time returned: "+buf);
 
258
            return;
 
259
        }
 
260
*/
 
261
        // first apply any voltages that have been set
 
262
        if (applyVoltages)
 
263
            applyVoltages();
 
264
 
 
265
        if (nanoseconds < timeStep) {
 
266
            System.out.println("Warning: cannot run simulator in increments less than time step (currently "+timeStep+" ns), setting it to "+timeStep+" ns");
 
267
            nanoseconds = timeStep;
 
268
        }
 
269
        // round wait time to the nearest time step, otherwise nanosim gets confused
 
270
        nanoseconds = (int)(nanoseconds/timeStep) * timeStep;
 
271
 
 
272
        // calculate stop time (time at which to set breakpoint)
 
273
        double stopTime = simTime + nanoseconds;
 
274
        // set break point
 
275
        issueCommand("set_time_break "+stopTime+"ns");
 
276
        issueCommand("cont_sim");
 
277
        simTime = stopTime;
 
278
    }
 
279
 
 
280
    public void waitPS(double ps) {
 
281
        waitNS(ps/1000.0);
 
282
    }
 
283
 
 
284
    public double getTimeNS() {
 
285
        return simTime;
 
286
/*
 
287
        issueCommand("get_sim_time");
 
288
        StringBuffer buf = getLastCommandOutput();
 
289
        Matcher m = patSimTime.matcher(buf.toString());
 
290
        double cur_time = 0;
 
291
        if (m.find()) {
 
292
            try {
 
293
                cur_time = Double.parseDouble(m.group(1));
 
294
            } catch (NumberFormatException e) {
 
295
                System.out.println("Error in get_sim_time, could not parse time "+m.group(1)+" from:\n"+buf);
 
296
                return cur_time;
 
297
            }
 
298
        } else {
 
299
            System.out.println("Error determining current time, get_sim_time returned: "+buf);
 
300
            return cur_time;
 
301
        }
 
302
        return cur_time;
 
303
*/
 
304
    }
 
305
 
 
306
    protected static final Pattern getSimTime_tres = Pattern.compile("The engine time resolution is\\s+: ([0-9\\.]+) ns");
 
307
    /**
 
308
     * Get the simulation's time step
 
309
     * @return the simulation time step in nanoseconds
 
310
     */
 
311
    protected double getSimTres() {
 
312
        issueCommand("get_sim_time");
 
313
        StringBuffer buf = getLastCommandOutput();
 
314
        Matcher m = getSimTime_tres.matcher(buf);
 
315
        if (m.find()) {
 
316
            try {
 
317
                double d = Double.parseDouble(m.group(1));
 
318
                return d;
 
319
            } catch (NumberFormatException e) {
 
320
                System.out.println("Error converting string to double in "+m.group(0)+": "+e.getMessage());
 
321
            }
 
322
        }
 
323
        double d = 0.01;    // default is 10ps
 
324
        System.out.println("Cannot determine time step, using default of "+d+" ns");
 
325
        return d;
 
326
    }
 
327
 
 
328
    // ====================================================================
 
329
    // ====================================================================
 
330
 
 
331
    //                      Get/Set voltages
 
332
 
 
333
    // ====================================================================
 
334
    // ====================================================================
 
335
 
 
336
    /**
 
337
     * Force node to a state.  Note that 1 is high and 0 is low.
 
338
     * The node is
 
339
     * case-insensitive, and may be a hierarchical spice name, such as 'Xtop.Xfoo.net@12'.
 
340
     * It should match the name from the spice file that nanosim is simulating.
 
341
     * @param node the hierarchical spice node name
 
342
     * @param state the state to set to, must be 1 or 0.
 
343
     */
 
344
    public void setNodeState(String node, int state) {
 
345
        node = node.toLowerCase();
 
346
        if (state != 0 && state != 1) {
 
347
            System.out.println("Illegal state passed to setNodeState: "+state+". Expected 0 or 1.");
 
348
            return;
 
349
        }
 
350
        setNodeVoltage(node, state*vdd);
 
351
    }
 
352
 
 
353
    /**
 
354
     * Set a node in the nanosim simulation to the specified voltage.
 
355
     * The node is
 
356
     * case-insensitive, and may be a hierarchical spice name, such as 'Xtop.Xfoo.net@12'.
 
357
     * It should match the name from the spice file that nanosim is simulating.
 
358
     * @param node the hierarchical spice node name
 
359
     * @param voltage the voltage to set the node to
 
360
     */
 
361
    public void setNodeVoltage(String node, double voltage) {
 
362
        node = node.toLowerCase();
 
363
        //issueCommand("set_node_v "+node+" "+voltage+" r=5 l=1n");
 
364
        nodesToSet.put(node, new Double(voltage));
 
365
    }
 
366
 
 
367
    /**
 
368
     * This is used to apply all voltages at the same time for the current time step.
 
369
     */
 
370
    protected void applyVoltages() {
 
371
        // release all forced nodes
 
372
        releaseNodes(new ArrayList(nodesToSet.keySet()));
 
373
 
 
374
        // all nodes are released, now apply all the values
 
375
        for (Iterator it = nodesToSet.entrySet().iterator(); it.hasNext(); ) {
 
376
            Map.Entry entry = (Map.Entry)it.next();
 
377
            String node = (String)entry.getKey();
 
378
            Double voltage = (Double)entry.getValue();
 
379
            if (assuraRCXNetlist) {
 
380
                node = node.replaceAll("\\.", "/");
 
381
            } else if (starRCXTNetlist) {
 
382
                if (node.startsWith("x")) node = node.substring(1);
 
383
                node = node.replaceAll("\\.x?", "/");
 
384
            }
 
385
            issueCommand("force_node_v v="+voltage.doubleValue()+" no="+node);
 
386
        }
 
387
        nodesToSet.clear();
 
388
        waitNS(timeStep, false);
 
389
    }
 
390
 
 
391
    // release the list of nodes (Strings)
 
392
    public void releaseNodes(List nodes) {
 
393
        // NOTE JKG 7/21/05:
 
394
        // Ajanta and I have found that release does not always work,
 
395
        // and sometimes the node remains "forced". Issuing another
 
396
        // release seems to remove the forced state, though, so the
 
397
        // following code issues releases until it is released
 
398
        // (or stops after 10 tries)
 
399
        int i=0;
 
400
        int nodesReleased = 0;
 
401
        while (nodesReleased < nodes.size() && i<10) {
 
402
            // make sure all nodes to set are not forced
 
403
            nodesReleased = 0;
 
404
            boolean releasedIssued = false;
 
405
            for (Iterator it = nodes.iterator(); it.hasNext(); ) {
 
406
                String node = (String)it.next();
 
407
                if (assuraRCXNetlist) {
 
408
                    node = node.replaceAll("\\.", "/");
 
409
                } else if (starRCXTNetlist) {
 
410
                    if (node.startsWith("x")) node = node.substring(1);
 
411
                    node = node.replaceAll("\\.x?", "/");
 
412
                }
 
413
                issueCommand("get_node_info detail=on "+node);
 
414
                StringBuffer output = getLastCommandOutput();
 
415
                if (output.indexOf("IS_FORCED: 1") != -1) {
 
416
                    // we need to release node
 
417
                    issueCommand("rel_node_v no="+node);
 
418
                    releasedIssued = true;
 
419
                } else {
 
420
                    nodesReleased++;            // this node is already released
 
421
                }
 
422
            }
 
423
            if (releasedIssued) {
 
424
                // advance time to try apply release
 
425
                waitNS(timeStep, false);
 
426
            }
 
427
            i++;
 
428
        }
 
429
    }
 
430
 
 
431
    List getNodeVoltages(List nodes) {
 
432
        return getNodeInfo(nodes, false);
 
433
    }
 
434
 
 
435
    List getNodeStates(List nodes) {
 
436
        return getNodeInfo(nodes, true);
 
437
    }
 
438
 
 
439
    /**
 
440
     * Get the state of a node.  Returns 1 or 0.
 
441
     * The node is
 
442
     * case-insensitive, and may be a hierarchical spice name, such as 'Xtop.Xfoo.net@12'.
 
443
     * It should match the name from the spice file that nanosim is simulating.
 
444
     * May return -1 if not a valid state.
 
445
     * @param node the hierarchical spice node name
 
446
     */
 
447
    public int getNodeState(String node) {
 
448
        List list = new ArrayList();
 
449
        list.add(node);
 
450
        List vals = getNodeInfo(list, true);
 
451
        if (vals != null && vals.size() > 0)
 
452
            return ((Number)vals.get(0)).intValue();
 
453
        return -1;
 
454
    }
 
455
 
 
456
    /**
 
457
     * Get the voltage on a node.
 
458
     * The node is
 
459
     * case-insensitive, and may be a hierarchical spice name, such as 'Xtop.Xfoo.net@12'.
 
460
     * It should match the name from the spice file that nanosim is simulating.
 
461
     * @param node the hierarchical spice node name
 
462
     * @return the voltage, or -1 if error
 
463
     */
 
464
    public double getNodeVoltage(String node) {
 
465
        List list = new ArrayList();
 
466
        list.add(node);
 
467
        List vals = getNodeInfo(list, false);
 
468
        if (vals != null && vals.size() > 0)
 
469
            return ((Double)vals.get(0)).doubleValue();
 
470
        return -1;
 
471
    }
 
472
 
 
473
    protected static final Pattern patNodeInfo = Pattern.compile("Node status of (.*?)\\((\\d+)\\): (.*?) \\(([0-9\\.\\-]+) V\\)");
 
474
    // digital only
 
475
    protected static final Pattern patNodeInfo2 = Pattern.compile("Node status of (.*?)\\((\\d+)\\): (\\d+)");
 
476
 
 
477
    /**
 
478
     * Gets the voltages on the nodes, unless returnState is true, in
 
479
     * which case it returns a list of 1's and 0's representing the logic state,
 
480
     * rather than the actual voltages.  Also returns -2 for undefined logic state, or -1 on error.
 
481
     * @param nodes the nodes to query
 
482
     * @param returnState true to convert voltages to 1 or 0 logic states
 
483
     * @return a list of voltages/states, or null on error
 
484
     */
 
485
    protected List getNodeInfo(List nodes, boolean returnState) {
 
486
        // apply any outstanding voltages
 
487
        if (nodesToSet.size() > 0)
 
488
            applyVoltages();
 
489
        if (assuraRCXNetlist || starRCXTNetlist) {
 
490
            List nodesfixed = new ArrayList();
 
491
            for (Iterator it = nodes.iterator(); it.hasNext(); ) {
 
492
                String node = (String)it.next();
 
493
                if (assuraRCXNetlist) {
 
494
                    node = node.replaceAll("\\.", "/");
 
495
                } else if (starRCXTNetlist) {
 
496
                    if (node.startsWith("x")) node = node.substring(1);
 
497
                    node = node.replaceAll("\\.x?", "/");
 
498
                }
 
499
                nodesfixed.add(node);
 
500
            }
 
501
            nodes = nodesfixed;
 
502
        }
 
503
 
 
504
 
 
505
        List nodeslc = new ArrayList();
 
506
        StringBuffer cmd = new StringBuffer();
 
507
        cmd.append("get_node_info ");
 
508
        for (Iterator it = nodes.iterator(); it.hasNext(); ) {
 
509
            String node = (String)it.next();
 
510
            node = node.toLowerCase();
 
511
            nodeslc.add(node);
 
512
            cmd.append(node+" ");
 
513
        }
 
514
        nodes = nodeslc;
 
515
 
 
516
        issueCommand(cmd.toString());
 
517
        StringBuffer result = getLastCommandOutput();
 
518
        String [] results = result.toString().trim().split("\n");
 
519
 
 
520
        List voltages = new ArrayList();
 
521
        List states = new ArrayList();
 
522
        int nodeIndex = 0;
 
523
        for (int i=0; i<results.length; i++) {
 
524
            if (!results[i].startsWith("Node status")) continue;        // quick check
 
525
            Matcher m = patNodeInfo.matcher(results[i]);
 
526
            Matcher m2 = patNodeInfo2.matcher(results[i]);
 
527
            String node = (String)nodes.get(nodeIndex);
 
528
            if (m.find()) {
 
529
                // don't do this check anymore, as nanosim can map the hierarchical name to the real name
 
530
                //if (!m.group(1).equals(node)) {
 
531
                //    System.out.println("Error on get_info_node: expected info for node "+node+" but got info for node "+m.group(1));
 
532
                //    return null;
 
533
                //}
 
534
                Integer state;
 
535
                // state can be one of 1, 0, or U
 
536
                if (m.group(3).equals("1"))
 
537
                    state = new Integer(1);
 
538
                else if (m.group(3).equals("0"))
 
539
                    state = new Integer(0);
 
540
                else if (m.group(3).equals("U"))
 
541
                    state = new Integer(-2);
 
542
                else {
 
543
                    System.out.println("Uknown state of "+node+": "+m.group(3)+", setting it to -1 (Undefined)");
 
544
                    state = new Integer(-1);
 
545
                }
 
546
                Double voltage;
 
547
                try {
 
548
                    voltage = new Double(m.group(4));
 
549
                } catch (NumberFormatException e) {
 
550
                    System.out.println("Error on get_info_node: NumberFormatException converting node "+node+" state/voltage ("+m.group(3)+"/"+m.group(4)+") to integer/double");
 
551
                    return null;
 
552
                }
 
553
 
 
554
                voltages.add(voltage);
 
555
                states.add(state);
 
556
                nodeIndex++;
 
557
                if (DEBUG) System.out.println("get_info_node "+node+": \tstate="+state+"\tvoltage="+voltage);
 
558
            } else if (m2.find() && returnState) {
 
559
                // digial only
 
560
                if (!m2.group(1).equals(node)) {
 
561
                    System.out.println("Error on get_info_node: expected info for node "+node+" but got info for node "+m.group(1));
 
562
                    return null;
 
563
                }
 
564
                Integer state;
 
565
                // state can be one of 1, 0, or U
 
566
                if (m2.group(3).equals("1"))
 
567
                    state = new Integer(1);
 
568
                else if (m2.group(3).equals("0"))
 
569
                    state = new Integer(0);
 
570
                else if (m2.group(3).equals("U"))
 
571
                    state = new Integer(-2);
 
572
                else {
 
573
                    System.out.println("Uknown state of "+node+": "+m2.group(3)+", setting it to -1 (Undefined)");
 
574
                    state = new Integer(-1);
 
575
                }
 
576
                states.add(state);
 
577
                nodeIndex++;
 
578
                if (DEBUG) System.out.println("get_info_node "+node+": \tstate="+state);
 
579
            }
 
580
        }
 
581
        if (returnState) return states;
 
582
        return voltages;
 
583
    }
 
584
 
 
585
    /**
 
586
     * Saves the state of all nodes at the given time to an external .ic file,
 
587
     * using the report_node_ic command.
 
588
     * @param time time in nanoseconds
 
589
     */
 
590
    public void reportNodeIC(double time) {
 
591
        issueCommand("report_node_ic all "+time+"ns");
 
592
    }
 
593
 
 
594
    /**
 
595
     * Saves the state of all nodes at the current time to an external .ic file,
 
596
     * using the report_node_ic command.
 
597
     */
 
598
    public void reportNodeIC() {
 
599
        issueCommand("report_node_ic all");
 
600
    }
 
601
 
 
602
    /** Unit Test
 
603
     * This test requires the file sim.spi in your working dir
 
604
     * */
 
605
    public static void main(String[] args) {
 
606
        NanosimModel nm = new NanosimModel();
 
607
        // the example file sim.spi needs to be in your working dir
 
608
        nm.start("nanosim", "sim.spi", 0);
 
609
        nm.issueCommand("get_sim_time");
 
610
        nm.finish();
 
611
    }
 
612
}