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.
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.
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