switch from using RS-232 BREAKs and no flow control to new command mode reset and...
[fleet.git] / src / edu / berkeley / fleet / fpga / Client.java
1 package edu.berkeley.fleet.fpga;
2
3 import static edu.berkeley.fleet.util.BitManipulations.*;
4 import java.util.concurrent.Semaphore;
5 import edu.berkeley.fleet.api.*;
6 import java.io.*;
7 import java.net.*;
8 import edu.berkeley.fleet.util.*;
9 import java.util.*;
10 import java.util.concurrent.*;
11 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
12 import static edu.berkeley.fleet.api.Instruction.Set.*;
13 import static edu.berkeley.fleet.api.Predicate.*;
14 import static edu.berkeley.fleet.api.Instruction.*;
15
16
17 public class Client extends FleetProcess {
18
19     private Socket s;
20     private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
21
22     public static long signExtend(long val) {
23         if ((val & (1L << 36)) != 0)
24             val = val | (0xffffffffffffffffL << 36);
25         return val;
26     }
27                                     
28     public Fleet getFleet() { return fpga; }
29     public Dock getDebugInputDock() {
30         return fpga.getShip("Debug",0).getDock("in");
31     }
32     public BitVector recvWord() {
33         if (isTerminated())
34             throw new RuntimeException("this fleet has been terminated");
35         try {
36             return queue.take();
37         } catch (InterruptedException e) { throw new RuntimeException(e); }
38     }
39
40     protected void _terminate() {
41         try {
42             closed = true;
43             s.close();
44         } catch (Exception e) { e.printStackTrace(); }
45     }
46
47     private Fpga fpga;
48     private DataOutputStream dos = null;
49
50     public void flush() {
51         try {
52             synchronized(this) {
53                 dos.flush();
54             }
55         } catch (Exception e) {
56             throw new RuntimeException(e);
57         }
58     }
59
60     /** the 16550 has a 16-byte FIFO buffer */
61     private final Semaphore sem = new Semaphore(15);
62     private boolean closed = false;
63
64     public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
65         this.fpga = fpga;
66
67         s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
68         //s = new Socket(InetAddress.getByName("localhost"), 3133);
69         OutputStream os = new BufferedOutputStream(s.getOutputStream());
70         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
71         pw.print(Server.pass_string+" "+bitfile+"\n");
72         pw.flush();
73
74         this.dos = new DataOutputStream(os);
75
76         dos.write( (3<<6) | 9);
77         dos.flush();
78         Thread.sleep(1000);
79
80         final InputStream is0 = s.getInputStream();
81         while(is0.available() > 0) {
82             int i = is0.read();
83             //System.out.println("reset code: " + (i & ~(-1 << 6)));
84         }
85
86         final InputStream is = new BufferedInputStream(is0);
87
88         Thread t = new Thread() {
89             public void run() {
90                 try {
91                     while(true) {
92                         int count = sem.availablePermits();
93                         if (count >= (1<<6)) count = (1<<6)-1; 
94                         if (count < 1) count = 1;
95                         sem.acquire(count);
96                         if (closed) return;
97                         synchronized(this) {
98                             dos.write( (1<<6) | count );
99                             if (sem.availablePermits()==0) dos.flush();
100                         }
101                     }
102                 } catch (Exception e) { throw new RuntimeException(e); }
103             }
104             };
105         t.setDaemon(true);
106         t.start();
107
108         t = new Thread() {
109             public void run() {
110                 try {
111                     while(true) {
112                         long result = 0;
113                         int val = 0;
114                         for(int i=0; i<8; i++) {
115                             val = is.read();
116                             if (val==-1) break;
117                             sem.release();
118                             long val2 = (val & 0xffL);
119                             val2 = val2 << (i * 6);
120                             result |= val2;
121                         }
122                         if (val==-1) break;
123                         BitVector bs = new BitVector(37);
124                         for(int i=0; i<37; i++)
125                             bs.set(i, ((result >> i) & 1L)!=0);
126                         queue.put(bs);
127                     }
128                 } catch (SocketException e) {
129                 } catch (Exception e) { throw new RuntimeException(e);
130                 } finally { terminate(); }
131             }
132             };
133         t.setDaemon(true);
134         t.start();
135
136         for(Instruction inst : instructions) sendInstruction(inst);
137         flush();
138
139     }
140
141     public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), true); }
142     public void sendWord(Destination d, BitVector word) { sendWord(d, word, false); }
143     private void sendWord(Destination d, BitVector word, boolean token) {
144         try {
145             Dock dispatchFrom = fpga.debugShip.getDock("in");
146             long out = 0;
147             out = fpga.PACKET_DATA.setval(out, word);
148             out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
149             out = fpga.PACKET_SIGNAL.setval(out, 0);
150             out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
151             synchronized(this) {
152                 for(int i=9; i>=0; i--)
153                     dos.write(BitManipulations.getIntField(i*6+5, i*6, out));
154                 dos.flush();
155             }
156         } catch (Exception e) {
157             throw new RuntimeException(e);
158         }
159     }
160     public void sendInstruction(Instruction inst) {
161         Dock dispatchFrom = fpga.debugShip.getDock("in");
162         sendWord(inst.dock.getInstructionDestination(),
163                  new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
164     }
165
166     private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
167     private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
168     private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
169     private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
170 }