mrunfpga: fleet.jar build/main.bit
$(java) $(cp) $(interpreter_class) --dump-code
- rsync -zare ssh --progress --verbose build/fleet.bin build/main.bit src/edu/berkeley/fleet/slipway/test.c root@bee441.cs.berkeley.edu:
- ssh root@bee441.cs.berkeley.edu '$(remote_run)'
+ rsync -zare ssh --progress --verbose build/main.bit root@bee441.cs.berkeley.edu:/var/slipway/megacz.bit
+ $(java) $(cp) edu.berkeley.fleet.slipway.Client megacz.bit < build/fleet.bin
build/main.bit: contrib/demo.ships $(shell find src -name \*.v)
make fleet.jar
#include "contrib/demo.ships"
-debug.data: [*] take, deliver;
+// values and addresses to write
+1: sendto mem.write_addr;
+2: sendto mem.write_addr;
+3: sendto mem.write_addr;
+9: sendto mem.write_data;
+8: sendto mem.write_data;
+7: sendto mem.write_data;
-1: sendto alu2.a;
-1: sendto alu2.b;
-0: sendto alu2.op;
-0: sendto alu2.op;
-0: sendto alu2.op;
-0: sendto alu2.op;
+// memory write ports accept the values
+mem.write_addr: [*] take, deliver;
+mem.write_data: [*] take, deliver;
-alu2.out:
- take;
- [2] sendto alu2.a;
- [2] sendto alu2.b;
- take, sendto alu2.a;
- take, sendto alu2.b;
- take, sendto debug.data;
+// once all three are written, cue the fifo
+mem.write_done:
+ [3] take;
+ ack fifo.out;
-alu2.op: [*] take, deliver;
-alu2.a: [*] take, deliver;
-alu2.b: [*] take, deliver;
+// meanwhile, the fifo is sitting on a set of read addresses
+fifo.in: [*] take, deliver;
+1: sendto fifo.in;
+2: sendto fifo.in;
+3: sendto fifo.in;
+1: sendto fifo.in;
+1: sendto fifo.in;
+1: sendto fifo.in;
+// when it gets the ack, it issues them all to the memory read unit
+fifo.out:
+ wait;
+ [*] take, sendto mem.read_addr;
+
+// values read from memory go to debug (which accepts them)
+mem.read_addr: [*] take, deliver;
+mem.read_data: [*] take, sendto debug.data;
+debug.data: [*] take, deliver;
#ship debug : Debug
#ship execute : Execute
#ship fifo : Fifo
-
-#ship alu2_02 : Alu2
-#ship alu2_03 : Alu2
-#ship alu2_04 : Alu2
-#ship alu2_05 : Alu2
-#ship alu2_06 : Alu2
-#ship alu2_07 : Alu2
-#ship alu2_08 : Alu2
-#ship alu2_09 : Alu2
-#ship alu2_10 : Alu2
-#ship alu2_11 : Alu2
-#ship alu2_12 : Alu2
-#ship alu2_13 : Alu2
-#ship alu2_14 : Alu2
-#ship alu2_15 : Alu2
-#ship alu2_16 : Alu2
-
-#ship fifo_02 : Fifo
-#ship fifo_03 : Fifo
-#ship fifo_04 : Fifo
-#ship fifo_05 : Fifo
-#ship fifo_06 : Fifo
-#ship fifo_07 : Fifo
-#ship fifo_08 : Fifo
-#ship fifo_09 : Fifo
-#ship fifo_10 : Fifo
-#ship fifo_11 : Fifo
-#ship fifo_12 : Fifo
-#ship fifo_13 : Fifo
-#ship fifo_14 : Fifo
-#ship fifo_15 : Fifo
-#ship fifo_16 : Fifo
+#ship mem : Mem
// alu1
Log.println();
}
+ public int readMem(int addr) {
+ return addr >= mem.length ? 0 : mem[addr];
+ }
public void writeMem(int addr, int data) {
if (addr >= mem.length) {
int[] mem2 = new int[addr*2+1];
--- /dev/null
+package edu.berkeley.fleet.ships;
+import edu.berkeley.fleet.interpreter.*;
+import edu.berkeley.fleet.*;
+
+import java.util.*;
+import java.io.*;
+
+public class Mem extends InterpreterShip {
+
+ DataInbox read_addr = new DataInbox(this, "read_addr");
+ DataOutbox read_data = new DataOutbox(this, "read_data");
+ DataInbox write_addr = new DataInbox(this, "write_addr");
+ DataInbox write_data = new DataInbox(this, "write_data");
+ TokenOutbox write_done = new TokenOutbox(this, "write_done");
+
+ public Mem(Interpreter fleet, String name) { super(fleet, name); }
+
+ public String getBalsaName() { return "mem"; }
+
+ public void service() {
+ if (read_addr.dataReadyForShip() &&
+ read_data.readyForItemFromShip()) {
+ Interpreter f = (Interpreter)getFleet();
+ read_data.addDataFromShip(f.readMem(read_addr.removeDataForShip()));
+ }
+
+ if (write_addr.dataReadyForShip() &&
+ write_data.dataReadyForShip() &&
+ write_done.readyForItemFromShip()) {
+ Interpreter f = (Interpreter)getFleet();
+ f.writeMem(write_addr.removeDataForShip(),
+ write_data.removeDataForShip());
+ write_done.addTokenFromShip();
+ }
+
+ }
+
+}
Socket s = new Socket(InetAddress.getByName("bee441.cs.berkeley.edu"), 3133);
OutputStream os = s.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
- pw.print(Server.pass_string+" main.bit\n");
+ String bitfile = args.length==0 ? "main.bit" : args[0];
+ pw.print(Server.pass_string+" "+bitfile+"\n");
pw.flush();
byte[] buf = new byte[1024];
--- /dev/null
+module bram(clk, we, a, dpra, di, spo, dpo);
+ input clk;
+ input we;
+ input [(`BRAM_ADDR_WIDTH-1):0] a;
+ input [(`BRAM_ADDR_WIDTH-1):0] dpra;
+ input [(`BRAM_DATA_WIDTH-1):0] di;
+ output [(`BRAM_DATA_WIDTH-1):0] spo;
+ output [(`BRAM_DATA_WIDTH-1):0] dpo;
+ reg [(`BRAM_DATA_WIDTH-1):0] ram [((1<<(`BRAM_ADDR_WIDTH))-1):0];
+ reg [(`BRAM_ADDR_WIDTH-1):0] read_a;
+ reg [(`BRAM_ADDR_WIDTH-1):0] read_dpra;
+ always @(posedge clk) begin
+ if (we)
+ ram[a] <= di;
+ read_a <= a;
+ read_dpra <= dpra;
+ end
+ assign spo = ram[read_a];
+ assign dpo = ram[read_dpra];
+endmodule
--- /dev/null
+`include "macros.v"
+`define BRAM_ADDR_WIDTH 8
+`define BRAM_DATA_WIDTH 37
+`include "bram.inc"
+
+module mem (clk,
+ read_addr_r, read_addr_a_, read_addr_d,
+ read_data_r_, read_data_a, read_data_d_,
+ write_addr_r, write_addr_a_, write_addr_d,
+ write_data_r, write_data_a_, write_data_d,
+ write_done_r_, write_done_a, write_done_d_);
+
+ input clk;
+ `input(read_addr_r, read_addr_a, read_addr_a_, [(`DATAWIDTH-1):0], read_addr_d)
+ `output(read_data_r, read_data_r_, read_data_a, [(`DATAWIDTH-1):0], read_data_d_)
+ `defreg(read_data_d_, [(`DATAWIDTH-1):0], read_data_d)
+ `input(write_addr_r, write_addr_a, write_addr_a_, [(`DATAWIDTH-1):0], write_addr_d)
+ `input(write_data_r, write_data_a, write_data_a_, [(`DATAWIDTH-1):0], write_data_d)
+ `output(write_done_r, write_done_r_, write_done_a, [(`DATAWIDTH-1):0], write_done_d_)
+ `defreg(write_done_d_, [(`DATAWIDTH-1):0], write_done_d)
+
+ reg bram_we;
+ wire [(`BRAM_DATA_WIDTH-1):0] bram_read_data;
+ reg [(`BRAM_ADDR_WIDTH-1):0] bram_write_address;
+ reg [(`BRAM_DATA_WIDTH-1):0] bram_write_data;
+ bram mybram(clk,
+ bram_we, bram_write_address,
+ read_addr_d, bram_write_data,
+ not_connected, bram_read_data);
+
+ reg send_done;
+ reg have_read; initial have_read = 0;
+ reg read_pending; initial read_pending = 0;
+
+ always @(posedge clk) begin
+ bram_we = 0;
+ if (read_pending) begin
+ read_pending = 0;
+ have_read = 1;
+ read_data_d = bram_read_data;
+ end else if (have_read) begin
+ `onwrite(read_data_r, read_data_a)
+ have_read = 0;
+ end
+ end else begin
+ `onread(read_addr_r, read_addr_a)
+ // ======= Careful with the timing here! =====================
+ // We MUST capture bram_read_data on the very next clock since
+ // read_addr_d is free to change after the next clock
+ // ===========================================================
+ read_pending = 1;
+ end
+ end
+
+ if (send_done) begin
+ `onwrite(write_done_r, write_done_a)
+ send_done = 0;
+ end
+ end else begin
+ if (!write_addr_r && write_addr_a) write_addr_a = 0;
+ if (!write_data_r && write_data_a) write_data_a = 0;
+ if (write_addr_r && write_data_r) begin
+ write_addr_a = 1;
+ write_data_a = 1;
+ bram_we = 1;
+ send_done = 1;
+ bram_write_address = write_addr_d;
+ bram_write_data = write_data_d;
+ end
+ end
+ end
+
+endmodule