1 package edu.berkeley.fleet.fpga;
2 import edu.berkeley.fleet.fpga.*;
3 import edu.berkeley.fleet.api.*;
5 import static edu.berkeley.fleet.util.BitManipulations.*;
6 import edu.berkeley.fleet.api.*;
7 import edu.berkeley.sbp.util.ANSI;
10 import edu.berkeley.fleet.util.*;
12 import java.util.concurrent.*;
13 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
14 import static edu.berkeley.fleet.api.Instruction.Set.*;
15 import static edu.berkeley.fleet.api.Predicate.*;
16 import static edu.berkeley.fleet.api.Instruction.*;
17 import com.sun.electric.tool.io.ExecProcess;
19 public abstract class JtagConnectedFpga extends Fpga {
21 protected JtagConnectedFpga() throws IOException {
24 public FleetProcess run(Instruction[] instructions) {
26 return new JtagConnectedFpgaClient(this, "none", instructions);
27 } catch (Exception e) { throw new RuntimeException(e); }
30 public static class JtagConnectedFpgaClient extends FleetProcess {
33 private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
34 public PrintWriter pwjtag;
35 private Semaphore semaphore = new Semaphore(0);
36 private Semaphore peekSemaphore = new Semaphore(0);
38 public Fleet getFleet() { return fpga; }
39 public Dock getDebugInputDock() { return fpga.getShip("Debug",0).getDock("in"); }
40 public BitVector recvWord() {
41 if (isTerminated()) throw new RuntimeException("this fleet has been terminated");
44 } catch (InterruptedException e) { throw new RuntimeException(e); }
46 protected void _terminate() {
48 PrintWriter pw = pwjtag;
54 } catch (Exception e) { e.printStackTrace(); }
59 PrintWriter pw = pwjtag;
64 } catch (Exception e) { e.printStackTrace(); }
67 public void masterClear() {
69 PrintWriter pw = pwjtag;
72 pw.println("poke 0 "+((3<<6) | 27));
76 // it's important to acquire the semaphore first, then clear the queue
79 } catch (Exception e) { throw new RuntimeException(); }
83 public JtagConnectedFpgaClient(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
86 ExecProcess jtag = new ExecProcess(new String[] { "ssh", "root@goliath.megacz.com", "cd ~/fleet; jtag" }, null);
87 jtag.redirectStderr(System.err);
90 pwjtag = new PrintWriter(new OutputStreamWriter(jtag.getStdin()));
91 final BufferedReader pwjtagin = new BufferedReader(new InputStreamReader(jtag.getStdout()));
98 String sin = pwjtagin.readLine();
99 if (sin==null) return;
100 if (sin.indexOf("URJ_BUS_READ(")==-1) {
101 if (sin.startsWith("Parsing "))
102 System.err.print("\r"+sin+ANSI.clreol());
104 System.err.println(sin);
107 sin = sin.substring(sin.indexOf("URJ_BUS_READ("));
108 sin = sin.substring(sin.indexOf(" = 0x"));
109 sin = sin.substring(" = 0x".length());
110 sin = sin.substring(0, sin.indexOf(' '));
111 int val = Integer.parseInt(sin, 16);
112 if (val < 256) continue;
114 //System.err.println("READ: 0x"+Integer.toString(val & 0xff, 16));
115 if ((val & (3<<6)) == 0) {
116 PrintWriter pw = pwjtag;
117 if (pw==null) return;
119 pw.println("poke 0 "+((1<<6) | 1));
121 peekSemaphore.release(3);
122 result |= ((val & 0xffL) << (i * 6L));
125 BitVector bs = new BitVector(37);
126 for(int j=0; j<37; j++)
127 bs.set(j, ((result >> j) & 1L)!=0);
134 PrintWriter pw = pwjtag;
135 if (pw==null) return;
137 pw.println("poke 0 "+((1<<6) | 15));
140 peekSemaphore.release(3);
145 } catch (Exception e) { throw new RuntimeException(e); }
149 PrintWriter pw = pwjtag;
150 //pw.println("cable Signalyzer");
151 pw.println("cable gnICE+");
152 pw.println("frequency 15000000");
154 //pw.println("bsdl path misc/bsdl");
155 //pw.println("detect");
156 pw.println("addpart 10");
157 pw.println("addpart 8");
158 pw.println("addpart 8");
159 pw.println("addpart 16");
160 pw.println("addpart 16");
161 pw.println("part 1");
162 pw.println("instruction BYPASS");
163 pw.println("part 2");
164 pw.println("instruction BYPASS");
165 pw.println("part 3");
166 pw.println("instruction BYPASS");
167 pw.println("part 4");
168 pw.println("instruction BYPASS");
170 pw.println("part 0");
171 pw.println("svf /root/fleet/build/ml509.small/main.svf stop progress");
175 pw.println("register IR 10");
176 pw.println("initbus fjmem opcode=1111000010");
179 System.err.println("done programming.");
181 // the thread that periodically sends a peek request
186 peekSemaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
187 int avail = peekSemaphore.availablePermits();
188 PrintWriter pw = pwjtag;
189 if (pw==null) return;
191 pw.println("peek 0");
192 if (avail==0) pw.flush();
195 } catch (Exception e) { throw new RuntimeException(e); }
200 if (instructions!=null) {
201 for(Instruction inst : instructions) sendInstruction(inst);
206 public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }
207 public void sendWord(Destination d, BitVector word) { sendWord(d, word, null, false); }
208 public void sendWord(Destination d, BitVector word, BitVector signal) { sendWord(d, word, signal, false); }
209 private void sendWord(Destination d, BitVector word, BitVector signal, boolean token) {
211 Dock dispatchFrom = fpga.debugShip.getDock("in");
213 out = fpga.PACKET_DATA.setval(out, word);
214 out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
215 out = signal==null ? fpga.PACKET_SIGNAL.setval(out, 0) : fpga.PACKET_SIGNAL.setval(out, signal);
216 out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
218 for(int i=9; i>=0; i--)
219 synchronized(pwjtag) {
220 pwjtag.println("poke 0 "+(BitManipulations.getIntField(i*6+5, i*6, out)&0xff));
224 } catch (Exception e) {
225 throw new RuntimeException(e);
228 public void sendInstruction(Instruction inst) {
229 Dock dispatchFrom = fpga.debugShip.getDock("in");
230 sendWord(inst.dock.getInstructionDestination(),
231 new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
234 private static Move discard(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, true, false, false, false, false); }
235 private static Move deliver(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true, false); }
236 private static Move wait(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, true, false, false, false, false, false); }
237 private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true, false); }