From 8ef6f34f6a3eea2a8c2a60139e90fb07e3cf96de Mon Sep 17 00:00:00 2001 From: Adam Megacz Date: Sun, 20 Sep 2009 12:35:36 -0700 Subject: [PATCH] major overhaul of FPGA code to support both ML509 and Bee2 at the same time --- src/edu/berkeley/fleet/fpga/Bee2.java | 170 ++++++++++++---------- src/edu/berkeley/fleet/fpga/Client.java | 134 +++++++++++------ src/edu/berkeley/fleet/fpga/Fpga.java | 6 +- src/edu/berkeley/fleet/fpga/ML509.java | 2 + src/edu/berkeley/fleet/fpga/Server.java | 4 +- src/edu/berkeley/fleet/fpga/verilog/Verilog.java | 8 +- 6 files changed, 198 insertions(+), 126 deletions(-) diff --git a/src/edu/berkeley/fleet/fpga/Bee2.java b/src/edu/berkeley/fleet/fpga/Bee2.java index e0af6b6..5a223a1 100644 --- a/src/edu/berkeley/fleet/fpga/Bee2.java +++ b/src/edu/berkeley/fleet/fpga/Bee2.java @@ -10,15 +10,40 @@ import java.util.concurrent.Semaphore; public class Bee2 extends Fpga { + /* + Secondly, here is the EDK core: + + http://repository.eecs.berkeley.edu/viewvc/Projects/BEE/trunk/2/hardware/pcores/interchip_block_v1_00_a/ + + This core generates the links for both control-user and user-user using some crazy scripts possibly written by Yury. Some EDK system examples are here: + + http://repository.eecs.berkeley.edu/viewvc/Projects/BEE/trunk/2/applications/reference/MPI_demo/XPS_Ctrlfpga/ + http://repository.eecs.berkeley.edu/viewvc/Projects/BEE/trunk/2/applications/reference/MPI_demo/XPS_Userfpga/ + + You can either attempt to execute these scripts in order to generate output for your desired configuration or use already generated output for a 100 Mhz configuration as we did when we converted RAMP Blue to RDL: + + http://repository.eecs.berkeley.edu/viewvc/Projects/RAMP/tags/RAMPBlue_Final/Blue/UserFPGA/Infrastructure/Interchip/ + + You can see how we used the generated output here: + + http://repository.eecs.berkeley.edu/viewvc/Projects/RAMP/tags/RAMPBlue_Final/Blue/UserFPGA/ + + I may be able to assist you further if you run into difficulties, but my memory of how this is supposed to work is hazy at best--and I never understood the interchip core scripts anyway. + + Alex + + */ + protected String getDirName() { return "bee2"; } + public Bee2() throws IOException { for(int i=0; i<2; i++) createShip("Alu"); for(int i=0; i<1; i++) createShip("Memory"); for(int i=0; i<2; i++) createShip("Fifo"); - createShip("Random"); - createShip("Counter"); + //createShip("Random"); //createShip("CarrySaveAdder"); createShip("Rotator"); createShip("Lut3"); + createShip("Counter"); /* for(int i=0; i<2; i++) createShip("Memory"); for(int i=0; i<6; i++) createShip("Alu"); @@ -45,7 +70,7 @@ public class Bee2 extends Fpga { public void run() { try { for(String s = br.readLine(); s!=null; s=br.readLine()) - System.err.println(s); + System.err.println(" > " + s); } catch (Exception e) { throw new RuntimeException(e); } } } @@ -57,83 +82,78 @@ public class Bee2 extends Fpga { public static String pass_string = "password=security_is_for_wimps "; public static void main(String[] args) throws Exception { - int idx = Integer.parseInt(args[0]); + if (args.length != 2) { + System.err.println("usage: java " + Bee2.class.getName() + " {-client|-server} "); + System.exit(-1); + } + int idx = Integer.parseInt(args[1]); + String host = "bee2"; Process proc; - System.err.println("== unprogramming fpga " + idx); - proc = Runtime.getRuntime().exec("user_unprogram "+idx); - new Gobbler(proc.getInputStream()).start(); - proc.waitFor(); - System.err.println("== programming fpga " + idx); - proc = Runtime.getRuntime().exec("user_program "+idx+" main.bit"); - new Gobbler(proc.getInputStream()).start(); - int ret = proc.waitFor(); - if (ret!=0) System.exit(ret); - - raf = new RandomAccessFile(new File("/dev/selectmap"+idx), "rw"); - fos = new FileOutputStream(raf.getFD()); - fis = new BufferedInputStream(new FileInputStream(raf.getFD())); - ServerSocket ss = new ServerSocket(3133); - - while(true) { - System.out.println("listening..."); - Socket socket = ss.accept(); - try { - socket.setKeepAlive(true); - System.out.println("accept!"); - - //final InputStream is = new BufferedInputStream(socket.getInputStream()); - final InputStream is = socket.getInputStream(); - final OutputStream os = socket.getOutputStream(); //new BufferedOutputStream(socket.getOutputStream()); + int res; + + if (args[0].equals("-client")) { + + System.err.println("== rsyncing"); + proc = Runtime.getRuntime().exec("rsync -are ssh --progress --verbose fleet.jar build/bee2/main.bit misc/bicat.c "+host+":"); + new Gobbler(proc.getInputStream()).start(); + res = proc.waitFor(); + if (res != 0) throw new RuntimeException("nonzero exit code"); + + System.err.println("== (un)programming fpga " + idx); + proc = Runtime.getRuntime().exec("ssh "+host+" -- user_unprogram "+idx+"; user_program "+idx+" main.bit"); + new Gobbler(proc.getInputStream()).start(); + res = proc.waitFor(); + if (res != 0) throw new RuntimeException("nonzero exit code"); + + System.err.println("== launching java"); + proc = Runtime.getRuntime().exec("ssh "+host+" -- gcc -o bicat bicat.c && ./bicat /dev/selectmap"+idx); + //return proc.getInputStream(); + + } else if (args[0].equals("-server")) { + + raf = new RandomAccessFile(new File("/dev/selectmap"+idx), "rw"); + fos = new FileOutputStream(raf.getFD()); + fis = new BufferedInputStream(new FileInputStream(raf.getFD())); + + //socket.setKeepAlive(true); + //final InputStream is = new BufferedInputStream(socket.getInputStream()); + //final InputStream is = socket.getInputStream(); + //final OutputStream os = socket.getOutputStream(); //new BufferedOutputStream(socket.getOutputStream()); + + final InputStream is = System.in; + final OutputStream os = System.out; + PrintStream log = new PrintStream(new FileOutputStream("log")); - // read login string - byte[] buf = new byte[1024]; - StringBuffer sb = new StringBuffer(); - while(true) { - int i = is.read(); - if (i==-1) return; - if (((char)i)=='\n') break; - sb.append((char)i); + //socket.setSoTimeout(10); + while(true) { + boolean ok = false; + while (fis.available() > 0) { + ok = true; + int val = fis.read(); + if (val==-1) break; + log.println("fpga->host: 0x"+Integer.toString(val & 0xff, 16)); + if ((val & (3<<6)) == 0) + fos.write( (1<<6) | 1); + os.write((byte)val); + os.flush(); + } + while(is.available() > 0) { + int r = is.read(); + if (r == -1) break; + ok = true; + log.println("host->fpga: 0x"+Integer.toString(r & 0xff, 16)); + fos.write(r); } - System.err.println("login string: " + sb.toString()); - if (!sb.toString().startsWith(pass_string)) return; - - socket.setSoTimeout(10); - while(true) { - boolean ok = false; - while (fis.available() > 0) { - ok = true; - int val = fis.read(); - if (val==-1) break; - System.err.println("fpga->host: 0x"+Integer.toString(val & 0xff, 16)); - if ((val & (3<<6)) == 0) - fos.write( (1<<6) | 1); - os.write((byte)val); - os.flush(); - } - try { - int r = is.read(); - if (r == -1) break; - ok = true; - System.err.println("host->fpga: 0x"+Integer.toString(r & 0xff, 16)); - fos.write(r); - } catch (SocketTimeoutException _) { } - if (!ok) { - if (socket.isOutputShutdown() || socket.isInputShutdown() || socket.isClosed() || !socket.isConnected()) { - socket.close(); - break; - } - System.err.println("flushing os..."); - os.flush(); - System.err.println("flushing fos..."); - fos.flush(); - System.err.println("sleeping..."); - Thread.sleep(10); - } + if (!ok) { + log.println("flushing os..."); + os.flush(); + log.println("flushing fos..."); + fos.flush(); + log.println("sleeping..."); + Thread.sleep(10); } - } catch (IOException e) { - e.printStackTrace(); } } } -} +} \ No newline at end of file diff --git a/src/edu/berkeley/fleet/fpga/Client.java b/src/edu/berkeley/fleet/fpga/Client.java index 269181e..e84b7c4 100644 --- a/src/edu/berkeley/fleet/fpga/Client.java +++ b/src/edu/berkeley/fleet/fpga/Client.java @@ -17,6 +17,8 @@ public class Client extends FleetProcess { private Socket s; private BlockingQueue queue = new LinkedBlockingQueue(); + private Fpga fpga; + private OutputStream os = null; public Fleet getFleet() { return fpga; } public Dock getDebugInputDock() { @@ -32,13 +34,10 @@ public class Client extends FleetProcess { protected void _terminate() { try { - s.close(); + if (s!=null) s.close(); } catch (Exception e) { e.printStackTrace(); } } - private Fpga fpga; - private OutputStream os = null; - public void flush() { try { os.flush(); @@ -47,18 +46,24 @@ public class Client extends FleetProcess { } } - public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception { - this.fpga = fpga; + private static class Gobbler extends Thread { + private final BufferedReader br; + public Gobbler(InputStream is) { + this.br = new BufferedReader(new InputStreamReader(is)); + } + public void run() { + try { + for(String s = br.readLine(); s!=null; s=br.readLine()) + System.err.println(" > " + s); + } catch (Exception e) { throw new RuntimeException(e); } + } + } - s = fpga instanceof Bee2 - ? new Socket(InetAddress.getByName("megacz.com"), 3133) - : new Socket(InetAddress.getByName("goliath.megacz.com"), 3133); - this.os = new BufferedOutputStream(s.getOutputStream()); - final InputStream is = new BufferedInputStream(s.getInputStream()); - PrintWriter pw = new PrintWriter(new OutputStreamWriter(os)); - pw.print(Server.pass_string+" "+bitfile+"\n"); - pw.flush(); + private boolean needmc = false; + public void masterClear() { + queue.clear(); + needmc = true; // goofy reset sequence new Thread() { public void run() { @@ -69,42 +74,87 @@ public class Client extends FleetProcess { } catch (Exception e) { throw new RuntimeException(e); } } }.start(); - int k = 1; - while(k<60) { - int i = is.read(); - if ( (i & (3<<6)) != (3<<6) ) { k=1; continue; } - i = i & ~((-1)<<6); - if (i==k) k++; else k = 1; + try { + while(needmc) Thread.sleep(100); + } catch (Exception e) { throw new RuntimeException(e); } + } + + public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception { + this.fpga = fpga; + + final InputStream xis; + + if (fpga instanceof Bee2) { + int idx = 1; + String host = "bee2"; + Process proc; + int res; + + System.err.println("== rsyncing"); + proc = Runtime.getRuntime().exec("rsync -are ssh --progress --verbose build/bee2/main.bit misc/bicat.c "+host+":"); + new Gobbler(proc.getInputStream()).start(); + res = proc.waitFor(); + if (res != 0) throw new RuntimeException("nonzero exit code"); + + System.err.println("== (un)programming fpga " + idx); + proc = Runtime.getRuntime().exec("ssh -t "+host+" -- (user_unprogram "+idx+" && gcc -o bicat bicat.c && user_program "+idx+" main.bit &>/dev/null) && ./bicat /dev/selectmap"+idx); + this.os = proc.getOutputStream(); + xis = new BufferedInputStream(proc.getInputStream()); + } else { + s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133); + this.os = new BufferedOutputStream(s.getOutputStream()); + xis = new BufferedInputStream(s.getInputStream()); + PrintWriter pw = new PrintWriter(new OutputStreamWriter(os)); + pw.print(Server.pass_string+" "+bitfile+"\n"); + pw.flush(); } - - // initial flow-control credits - os.write( (1<<6) | 15); + final InputStream is = xis; + needmc = true; Thread t = new Thread() { - public void run() { - try { - OUTER: while(true) { - long result = 0; - for(int i=0; i<8; i++) { - int val = is.read(); - if (val==-1) break OUTER; - result |= ((val & 0xffL) << (i * 6L)); + public void run() { + try { + while(needmc) { + int k = 1; + while(k<60) { + int i = is.read(); + if ( (i & (3<<6)) != (3<<6) ) { k=1; continue; } + i = i & ~((-1)<<6); + if (i==k) k++; else k = 1; + } + + // initial flow-control credits + os.write( (1<<6) | 15); + os.flush(); + needmc = false; + OUTER: while(true) { + long result = 0; + if (needmc) break; + for(int i=0; i<8; i++) { + int val = is.read(); + if (needmc) break OUTER; + if (val==-1) break OUTER; + result |= ((val & 0xffL) << (i * 6L)); + } + BitVector bs = new BitVector(37); + for(int i=0; i<37; i++) + bs.set(i, ((result >> i) & 1L)!=0); + queue.put(bs); + } } - BitVector bs = new BitVector(37); - for(int i=0; i<37; i++) - bs.set(i, ((result >> i) & 1L)!=0); - queue.put(bs); - } - } catch (SocketException e) { - } catch (Exception e) { throw new RuntimeException(e); - } finally { terminate(); } - } + } catch (SocketException e) { + } catch (Exception e) { throw new RuntimeException(e); + } finally { terminate(); } + } }; t.setDaemon(true); t.start(); + masterClear(); - for(Instruction inst : instructions) sendInstruction(inst); - flush(); + if (instructions!=null) { + for(Instruction inst : instructions) sendInstruction(inst); + flush(); + } } public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); } diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index 26bbc8f..ec2ef1c 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -132,6 +132,8 @@ public abstract class Fpga extends FleetTwoFleet { // Expand ////////////////////////////////////////////////////////////////////////////// + protected abstract String getDirName(); + public void expand(ShipDescription sd) { try { if (sd.getSection("fpga")==null) return; @@ -139,7 +141,7 @@ public abstract class Fpga extends FleetTwoFleet { String filename = sd.getName().toLowerCase(); if (sd.getSection("ucf") != null) { - File outf = new File("build/fpga/"+filename+".ucf"); + File outf = new File("build/"+getDirName()+"/"+filename+".ucf"); FileOutputStream out = new FileOutputStream(outf); PrintWriter pw = new PrintWriter(out); pw.println(sd.getSection("ucf")); @@ -147,7 +149,7 @@ public abstract class Fpga extends FleetTwoFleet { pw.close(); } - File outf = new File("build/fpga/"+filename+".v"); + File outf = new File("build/"+getDirName()+"/"+filename+".v"); new File(outf.getParent()).mkdirs(); System.err.println("writing to " + outf); FileOutputStream out = new FileOutputStream(outf); diff --git a/src/edu/berkeley/fleet/fpga/ML509.java b/src/edu/berkeley/fleet/fpga/ML509.java index d4a59af..0c6fa5f 100644 --- a/src/edu/berkeley/fleet/fpga/ML509.java +++ b/src/edu/berkeley/fleet/fpga/ML509.java @@ -10,6 +10,7 @@ public abstract class ML509 extends Fpga { } public static class Large extends ML509 { + protected String getDirName() { return "ml509.large"; } public Large() throws IOException { for(int i=0; i<1; i++) createShip("Memory"); for(int i=0; i<6; i++) createShip("Alu"); @@ -25,6 +26,7 @@ public abstract class ML509 extends Fpga { } public static class Small extends ML509 { + protected String getDirName() { return "ml509.small"; } public Small() throws IOException { for(int i=0; i<2; i++) createShip("Alu"); for(int i=0; i<1; i++) createShip("Memory"); diff --git a/src/edu/berkeley/fleet/fpga/Server.java b/src/edu/berkeley/fleet/fpga/Server.java index d6b90e1..3122b32 100644 --- a/src/edu/berkeley/fleet/fpga/Server.java +++ b/src/edu/berkeley/fleet/fpga/Server.java @@ -23,8 +23,8 @@ public class Server { public static void main(String[] args) throws Exception { System.err.println("programming..."); Process proc = Runtime.getRuntime().exec(new String[] { - "./program.sh", - "./main.bit" + "./misc/program.sh", + "./build/ml509.small/main.bit" }); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); String str = null; diff --git a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java index 31d96ab..44d02e5 100644 --- a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java +++ b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java @@ -654,7 +654,7 @@ public class Verilog { if (!fix) throw new RuntimeException(); boolean isRoot = name.equals("main"); pw.print("module "+name); - pw.println(isRoot ? "(clk_pin, rst_pin " : "(clk, rst "); + pw.println(isRoot ? "(rst_pin " : "(clk, rst "); for(String name : portorder) pw.println(" , " + ports.get(name).getInterface()); for (InstantiatedModule im : this.instantiatedModules.values()) for(PercolatedPort pp : im.module.percolatedPorts) @@ -664,15 +664,11 @@ public class Verilog { pw.println(); if (isRoot) { - pw.println(" input clk_pin;"); pw.println(" input rst_pin;"); pw.println(" wire clk;"); pw.println(" wire clk_fb;"); pw.println(" wire clk_unbuffered;"); - pw.println(" assign clk_unbuffered = clk_pin;"); - //pw.println(" assign clk = clk_pin;"); - pw.println(" BUFG GBUF_FOR_MUX_CLOCK (.I(clk_unbuffered), .O(clk));"); /* pw.println(" DCM"); pw.println(" #("); @@ -712,6 +708,8 @@ public class Verilog { if (isRoot) { pw.println(" assign rst = rst_out;"); pw.println(" assign rst_in = !rst_pin;"); + pw.println(" BUFG GBUF_FOR_MUX_CLOCK (.I(clk_unbuffered), .O(clk));"); + pw.println(" assign clk_unbuffered = clk_out;"); } for(String name : ports.keySet()) pw.println(" " + ports.get(name).getDeclaration()); -- 1.7.10.4