Gates Version 1

Download: jar file

This verison of the gates1 program uses a TextAreaPrintStream class for output. It can now be run as an applet or window application.

Demonstration

This version also illustrates the use of parameter fields for applets:

<applet code="gates1.class" archive="gates1.jar" width=640 height=200>
<param name="url" value="https://johnloomis.org/ece538/notes/gates1/logic1.net">
</applet>

See line 139 to see how the value of the parameter "url" is read.

Contents

gates1.java
Circuit.java
TextAreaPrintStream.java

gates1.java


001: // gates1.java
002: 
003: import java.io.*;
004: import java.net.*;
005: import java.util.ArrayList;
006: import java.awt.EventQueue;
007: import javax.swing.*;
008: 
009: 
010: // This class is a modified version of netlist3.java
011: class Process {
012:     JTextArea area;
013:     TextAreaPrintStream out;
014:     String filename;
015:     boolean isURL;
016:     Circuit ckt;
017: 
018:     Process(String filename)
019:     {
020:         this.filename = filename;
021:         area = new JTextArea(16,70);
022:         out = new TextAreaPrintStream(area,System.out);
023:         isURL = false;
024:         
025:         //    out = System.out;
026:     }
027: 
028:     public void run()
029:     {
030:         InputStream instream;
031:         BufferedReader in;
032:
033:         out.println("Filename: " + filename);
034: 
035:         try {
036:             if (isURL) {
037:                 URL url = new URL(filename);
038:                 instream = url.openStream();
039:             }
040:             else instream = new FileInputStream(filename);
041:             in = new BufferedReader(new InputStreamReader(instream));
042:             ckt = new Circuit();
043:             ckt.read(in,out);
044:             in.close();
045:             out.println("\nDevice list:\n");
046:             ckt.list_devices(out);
047:             ckt.build_node_list();
048:             out.println("\nNode list:\n");
049:             ckt.list_nodes(out);
050:             if (ckt.inputs!=null || ckt.outputs!= null) out.println("\n\n");
051:             if (ckt.inputs!=null) show("inputs",ckt.inputs);
052:             if (ckt.outputs!=null) show("outputs",ckt.outputs);
053:             showTable();
054:         } catch (IOException e) {  
055:             out.println( e);
056:         }       
057:     }
058: 
059:     void show(String name, String vals[])
060:     {
061:         int j, nvals;
062:         String str = name;
063:         for (String val: vals) str += "\t" + val;
064:         out.println(str);
065:     }
066: 
067:     void showTable()
068:     {
069:         String [] inputs = ckt.inputs;
070:         String [] outputs = ckt.outputs;
071:         int ninp = inputs.length;
072:         int noup = outputs.length;
073:         int ncases = (int) Math.pow(2,ninp);
074:         int j, k, v;
075:         String str = "";
076:         out.println("\n");
077:         for (j=0; j<ninp; j++) {
078:             if (j>0) str += "\t" + inputs[j];
079:             else str = inputs[j];
080:         }
081:         for (j=0; j<noup; j++) str += "\t" + outputs[j];
082:         out.println(str + "\tcycles\tmax_changed");
083:         
084:         Node [] input_nodes = new Node[ninp];
085:         ArrayList<Node> changed_in = new ArrayList<Node>();
086:         ArrayList<Node> changed_out = new ArrayList<Node>();
087:         for (j=0; j<ninp; j++) {
088:             Node node = ckt.find_node(inputs[j]);
089:             if (node==null) out.printf("node %s not found\n",inputs[j]);
090:             input_nodes[j] = node;
091:         }
092:         
093:         Node [] output_nodes = new Node[noup];
094:         for (j=0; j<noup; j++) {
095:             Node node = ckt.find_node(outputs[j]);
096:             if (node==null) out.printf("node %s not found\n",outputs[j]);
097:             output_nodes[j] = node;
098:         }
099:         // cycle through the possible input values (for a truth table)
100:         for (k=0; k<ncases; k++) {
101:             for (j = 0; j<ninp; j++) {
102:                 v = (k>>(ninp-1-j))&1;
103:                 if (j>0) str += "\t" + v;
104:                 else str = "" + v;
105:                 Node node = input_nodes[j];
106:                 node.setValue(v);
107:                 changed_in.add(node);
108:                 
109:             }
110:             
111:             // evaluate the circuit until nothing changes
112:             int ncycles, change;
113:             ncycles = 0;
114:             change = ckt.eval(changed_in,changed_out);
115:             int max_change = change;        
116:             while (change>0) {
117:                 ncycles++;
118:                 changed_in.clear();
119:                 changed_in.addAll(changed_out);
120:                 changed_out.clear();
121:                 change = ckt.eval(changed_in,changed_out);
122:                 if (change>max_change) max_change = change;
123:             }
124:             
125:             // print the output values
126:             for (j=0; j<noup; j++) str += "\t" + output_nodes[j].getLogic();
127:             out.println(str + "\t" + ncycles + "\t" + max_change);
128:         }
129:     }
130: }
131: 
132: public class gates1 extends JApplet {
133: 
134:     public void init()
135:     {
136:         EventQueue.invokeLater(new Runnable() {
137:             public void run()
138:             {
139:                 String url = getParameter("url");
140:                 Process proc = new Process(url);
141:                 proc.isURL = true;
142:                 add(new JScrollPane(proc.area));
143:                 proc.run();
144:             }
145:         });
146:     }
147:     
148:     public static void main(String[] args)
149:     {
150:         String filename;
151: 
152:         if (args.length < 1) {
153:             filename = "logic1.net"; 
154:         }
155:         else filename = args[0];
156:         final Process proc = new Process(filename);
157: 
158:         EventQueue.invokeLater(new Runnable() {
159:             public void run()
160:             {
161:                 JFrame frame = new JFrame("Gates Version 1");
162:                 frame.add(new JScrollPane(proc.area));
163:                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
164:                 frame.pack();
165:                 //frame.setSize(640,200);
166:                 frame.setVisible(true);
167:                 proc.run();
168:             }
169:         });
170:     }
171: }


Circuit.java


001: import java.io.*;
002: import java.util.ArrayList;
003: 
004: public class Circuit
005: {
006:     String name;
007:     Node ref;
008:     ArrayList<Node> nodes;
009:     ArrayList<Device> devices;
010:     String [] inputs;
011:     String [] outputs;
012: 
013:     Circuit()
014:     {
015:         ref = new Node("0");
016:         devices = new ArrayList<Device>();
017:         nodes = new ArrayList<Node>();
018:     }
019: 
020:     public void read(BufferedReader inr, PrintStream out) {
021:         LineNumberReader in = new LineNumberReader(inr);
022:         boolean done = false;
023:         while (!done) {
024:             int n = in.getLineNumber();
025:             try {
026:                 String inp = in.readLine();
027:                 if (inp==null) break;
028:                 out.println("Line " + n + ":  " + inp);
029:                 String [] str = inp.split("%"); // terminate at comment character
030:                 String [] tokens = str[0].split("\\s+");
031:                 if (tokens.length>1) {
032:                     // This version just does gates
033:                     Device d = Gate.getNewDevice(tokens[0]);
034:                     if (d!=null) {
035:                         d.parse(tokens);
036:                         devices.add(d);
037:                     }
038:                     else if (tokens[0].equals("inputs")) inputs = saveTokens(tokens);
039:                     else if (tokens[0].equals("outputs")) outputs = saveTokens(tokens);
040:                     else out.println("Device not recognized: " + tokens[0] );
041:                 }
042:             }
043:             catch (IOException e) {
044:                 out.println(e);
045:             }
046:         }
047:         out.println();
048:     }
049: 
050:     String [] saveTokens(String tokens[])
051:     {
052:         int i, ntokens;
053:         ntokens = tokens.length;
054:         String [] list = new String[ntokens-1];
055:         for (i=1; i<ntokens; i++) list[i-1] = tokens[i];
056:         return list;
057:     }
058: 
059:     Node find_node(String str)
060:     {
061:         int ncount = nodes.size();
062:         for (int j=0; j<ncount; j++) {
063:             Node node = nodes.get(j);
064:             if (node.name.equals(str)) return node;
065:         }
066:         return null;
067:     }
068: 
069: 
070:     int add_node(String str, Device dev)
071:     {
072:         int i;
073:         Node node;
074:         int ncount = nodes.size();
075:         for (i=0; i<ncount; i++) {
076:             node = nodes.get(i);
077:             if (node.name.equals(str)) {
078:                 node.devices.add(dev);
079:                 return i;
080:             }
081:         }
082:         node = new Node(str);
083:         nodes.add(node);
084:         node.devices.add(dev);
085:         return ncount;
086:     }
087: 
088:     void build_node_list()
089:     {
090:         int i, j;
091:         Device dev;
092:         int ndevices = devices.size();
093:         for (i=0; i<ndevices; i++) {
094:             dev = devices.get(i);
095:             int nodecount = dev.nodes.length;
096:             for (j=0; j<nodecount; j++) dev.ndx[j] = add_node(dev.nodes[j],dev);
097:         }
098:     }
099: 
100:     void list_nodes(PrintStream out)
101:     {
102:         for (Node node: nodes) out.println(node);
103:         /*
104:         int i;
105:         int ncount = nodes.size();
106:         for (i=0; i<ncount; i++) {
107:             Node node =  nodes.get(i);
108:             out.printf("%d\t %s\n",i,node);
109:         }
110:         */
111:     }
112:         
113: 
114:     void list_devices(PrintStream out)
115:     {
116:         for (Device d: devices) out.println(d);
117:     }
118: 
119:     int eval(ArrayList<Node> changed_in, ArrayList<Node> changed_out)
120:     {
121:         ArrayList<Gate> devices = new ArrayList<Gate>(0);
122:         Gate gate;
123:         for (Node node: changed_in) {
124:             for (Device dev: node.devices) {
125:                 gate = (Gate) dev;
126:                 // we only evaluate gates
127:                 if (!dev.getClass().isInstance(gate)) continue;
128:                 if (!devices.contains(gate)) devices.add(gate);
129:             }
130:         }
131:         for (Gate dev: devices) dev.eval(nodes,changed_out);
132:         return changed_out.size();
133:     }
134: }


TextAreaPrintStream.java


01: /**
02:  * Class TextAreaPrintStream
03:  * extends PrintStream.
04:  * A custom made PrintStream which overrides methods println(String)
05:  * and print(String).
06:  * Thus, when the out stream is set as this PrintStream (with System.setOut
07:  * method), all calls to System.out.println(String) or System.out.print(String)
08:  * will result in an output stream of characters in the JTextArea given as an
09:  * argument of the constructor of the class.
10:  **/
11: 
12: import java.io.*;
13: import javax.swing.*;
14: 
15: public class TextAreaPrintStream extends PrintStream {
16: 
17:     //The JTextArea to wich the output stream will be redirected.
18:     private JTextArea textArea;
19: 
20: 
21:     /**
22:      * Method TextAreaPrintStream
23:      * The constructor of the class.
24:      * @param the JTextArea to wich the output stream will be redirected.
25:      * @param a standard output stream (needed by super method)
26:      **/
27:     public TextAreaPrintStream(JTextArea area, OutputStream out) {
28:         super(out);
29:         textArea = area;
30:     }
31: 
32:     /**
33:      * Method println
34:      * @param the String to be output in the JTextArea textArea (private
35:      * attribute of the class).
36:      * After having printed such a String, prints a new line.
37:      **/
38:     public void println(String string) {
39:         textArea.append(string+"\n");
40:     }
41: 
42:     public void println() {
43:         textArea.append("\n");
44:     }
45: 
46:     public void println(Object obj) {
47:         textArea.append(obj.toString()+"\n");
48:     }
49: 
50: 
51: 
52:     /**
53:      * Method print
54:      * @param the String to be output in the JTextArea textArea (private
55:      * attribute of the class).
56:      **/
57:     public void print(String string) {
58:         textArea.append(string);
59:     }
60: 
61:     public void print(Object obj) {
62:         textArea.append(obj.toString());
63:     }
64: }


Maintained by John Loomis, updated Wed Mar 26 11:16:28 2008