updates to Client/server
[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 = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
54         //s = new Socket(InetAddress.getByName("localhost"), 3133);
55         this.os = new BufferedOutputStream(s.getOutputStream());
56         final InputStream is = new BufferedInputStream(s.getInputStream());
57         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
58         pw.print(Server.pass_string+" "+bitfile+"\n");
59         pw.flush();
60
61         // goofy reset sequence
62         new Thread() {
63             public void run() {
64                 try {
65                     for(int i=0; i<255; i++) os.write( (3<<6) | 0);
66                     for(int i=0; i<60; i++) os.write( (3<<6) | i);
67                     os.flush();
68                 } catch (Exception e) { throw new RuntimeException(e); }
69             }
70         }.start();
71         int k = 1;
72         while(k<60) {
73             int i = is.read();
74             System.out.println("readback " + i);
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()), true); }
111     public void sendWord(Destination d, BitVector word) { sendWord(d, word, false); }
112     private void sendWord(Destination d, BitVector word, boolean token) {
113         try {
114             Dock dispatchFrom = fpga.debugShip.getDock("in");
115             long out = 0;
116             out = fpga.PACKET_DATA.setval(out, word);
117             out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
118             out = fpga.PACKET_SIGNAL.setval(out, 0);
119             out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
120             synchronized(this) {
121                 for(int i=9; i>=0; i--)
122                     os.write(BitManipulations.getIntField(i*6+5, i*6, out));
123                 os.flush();
124             }
125         } catch (Exception e) {
126             throw new RuntimeException(e);
127         }
128     }
129     public void sendInstruction(Instruction inst) {
130         Dock dispatchFrom = fpga.debugShip.getDock("in");
131         sendWord(inst.dock.getInstructionDestination(),
132                  new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
133     }
134
135     private static Move discard(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
136     private static Move deliver(Dock dock)           { return new Move(dock, false, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
137     private static Move wait(Dock dock)              { return new Move(dock, false, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
138     private static Move sendto(Dock dock, Path path) { return new Move(dock, false, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
139 }