Bee2 branch landing: step 1
[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 edu.berkeley.fleet.api.*;
5 import java.io.*;
6 import java.net.*;
7 import edu.berkeley.fleet.util.*;
8 import java.util.*;
9 import java.util.concurrent.*;
10 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
11 import static edu.berkeley.fleet.api.Instruction.Set.*;
12 import static edu.berkeley.fleet.api.Predicate.*;
13 import static edu.berkeley.fleet.api.Instruction.*;
14
15
16 public class Client extends FleetProcess {
17
18     private Socket s;
19     private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
20
21     public Fleet getFleet() { return fpga; }
22     public Dock getDebugInputDock() {
23         return fpga.getShip("Debug",0).getDock("in");
24     }
25     public BitVector recvWord() {
26         if (isTerminated())
27             throw new RuntimeException("this fleet has been terminated");
28         try {
29             return queue.take();
30         } catch (InterruptedException e) { throw new RuntimeException(e); }
31     }
32
33     protected void _terminate() {
34         try {
35             s.close();
36         } catch (Exception e) { e.printStackTrace(); }
37     }
38
39     private Fpga fpga;
40     private OutputStream os = null;
41
42     public void flush() {
43         try {
44             os.flush();
45         } catch (Exception e) {
46             throw new RuntimeException(e);
47         }
48     }
49
50     public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
51         this.fpga = fpga;
52
53         s = fpga instanceof Bee2
54             ? new Socket(InetAddress.getByName("megacz.com"), 3133)
55             : new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
56         this.os = new BufferedOutputStream(s.getOutputStream());
57         final InputStream is = new BufferedInputStream(s.getInputStream());
58         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
59         pw.print(Server.pass_string+" "+bitfile+"\n");
60         pw.flush();
61
62         // goofy reset sequence
63         new Thread() {
64             public void run() {
65                 try {
66                     for(int i=0; i<255; i++) os.write( (3<<6) | 0);
67                     for(int i=0; i<60; i++) os.write( (3<<6) | i);
68                     os.flush();
69                 } catch (Exception e) { throw new RuntimeException(e); }
70             }
71         }.start();
72         int k = 1;
73         while(k<60) {
74             int i = is.read();
75             if ( (i & (3<<6)) != (3<<6) ) { k=1; continue; }
76             i = i & ~((-1)<<6);
77             if (i==k) k++; else k = 1;
78         }
79         
80         // initial flow-control credits
81         os.write( (1<<6) | 15);
82
83         Thread t = new Thread() {
84             public void run() {
85                 try {
86                     OUTER: while(true) {
87                         long result = 0;
88                         for(int i=0; i<8; i++) {
89                             int val = is.read();
90                             if (val==-1) break OUTER;
91                             result |= ((val & 0xffL) << (i * 6L));
92                         }
93                         BitVector bs = new BitVector(37);
94                         for(int i=0; i<37; i++)
95                             bs.set(i, ((result >> i) & 1L)!=0);
96                         queue.put(bs);
97                     }
98                 } catch (SocketException e) {
99                 } catch (Exception e) { throw new RuntimeException(e);
100                 } finally { terminate(); }
101             }
102             };
103         t.setDaemon(true);
104         t.start();
105
106         for(Instruction inst : instructions) sendInstruction(inst);
107         flush();
108     }
109
110     public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }
111     public void sendWord(Destination d, BitVector word) { sendWord(d, word, null, false); }
112     public void sendWord(Destination d, BitVector word, BitVector signal) { sendWord(d, word, signal, false); }
113     private void sendWord(Destination d, BitVector word, BitVector signal, boolean token) {
114         try {
115             Dock dispatchFrom = fpga.debugShip.getDock("in");
116             long out = 0;
117             out = fpga.PACKET_DATA.setval(out, word);
118             out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
119             if (signal==null)
120                 out = fpga.PACKET_SIGNAL.setval(out, 0);
121             else 
122                 out = fpga.PACKET_SIGNAL.setval(out, signal);
123             out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
124             synchronized(this) {
125                 for(int i=9; i>=0; i--)
126                     os.write(BitManipulations.getIntField(i*6+5, i*6, out));
127                 os.flush();
128             }
129         } catch (Exception e) {
130             throw new RuntimeException(e);
131         }
132     }
133     public void sendInstruction(Instruction inst) {
134         Dock dispatchFrom = fpga.debugShip.getDock("in");
135         sendWord(inst.dock.getInstructionDestination(),
136                  new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
137     }
138
139     private static Move discard(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
140     private static Move deliver(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
141     private static Move wait(Dock dock)              { return new Move(dock, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
142     private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
143 }