add FleetProcess.sendWord() that takes a signal
[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             if ( (i & (3<<6)) != (3<<6) ) { k=1; continue; }
75             i = i & ~((-1)<<6);
76             if (i==k) k++; else k = 1;
77         }
78         
79         // initial flow-control credits
80         os.write( (1<<6) | 15);
81
82         Thread t = new Thread() {
83             public void run() {
84                 try {
85                     OUTER: while(true) {
86                         long result = 0;
87                         for(int i=0; i<8; i++) {
88                             int val = is.read();
89                             if (val==-1) break OUTER;
90                             result |= ((val & 0xffL) << (i * 6L));
91                         }
92                         BitVector bs = new BitVector(37);
93                         for(int i=0; i<37; i++)
94                             bs.set(i, ((result >> i) & 1L)!=0);
95                         queue.put(bs);
96                     }
97                 } catch (SocketException e) {
98                 } catch (Exception e) { throw new RuntimeException(e);
99                 } finally { terminate(); }
100             }
101             };
102         t.setDaemon(true);
103         t.start();
104
105         for(Instruction inst : instructions) sendInstruction(inst);
106         flush();
107     }
108
109     public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }
110     public void sendWord(Destination d, BitVector word) { sendWord(d, word, null, false); }
111     public void sendWord(Destination d, BitVector word, BitVector signal) { sendWord(d, word, signal, false); }
112     private void sendWord(Destination d, BitVector word, BitVector signal, 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             if (signal==null)
119                 out = fpga.PACKET_SIGNAL.setval(out, 0);
120             else 
121                 out = fpga.PACKET_SIGNAL.setval(out, signal);
122             out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
123             synchronized(this) {
124                 for(int i=9; i>=0; i--)
125                     os.write(BitManipulations.getIntField(i*6+5, i*6, out));
126                 os.flush();
127             }
128         } catch (Exception e) {
129             throw new RuntimeException(e);
130         }
131     }
132     public void sendInstruction(Instruction inst) {
133         Dock dispatchFrom = fpga.debugShip.getDock("in");
134         sendWord(inst.dock.getInstructionDestination(),
135                  new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
136     }
137
138     private static Move discard(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, true,  false, false, false, false); }
139     private static Move deliver(Dock dock)           { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true,  false); }
140     private static Move wait(Dock dock)              { return new Move(dock, IgnoreFlagD, false, null, true,  false, false, false, false, false); }
141     private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true,  false); }
142 }