data_to_host_write_enable <= 0;
if (force_reset == 1) begin
force_reset <= 0;
- data_to_host_write_enable <= 1;
+ //data_to_host_write_enable <= 1;
credits = 0;
count_in <= 0;
count_out <= 0;
.SEL(sel),
.DRCK(drck));
- wire [9:0] din;
wire [9:0] dout;
reg [9:0] dout_r;
+ reg [9:0] din;
+ wire write_o;
+ wire read_o;
wire strobe_o;
- assign din = 10'h71;
wire ack_i;
assign ack_i = 1;
.res_i (rst),
.strobe_o (strobe_o),
- .read_o (),
+ .read_o (read_o),
.write_o (write_o),
.ack_i (ack_i),
.cs_o (),
.addr_o (),
- .din_i (dout_r),
+ .din_i (din),
.dout_o (dout)
);
- always @(posedge clk) begin
- if (strobe_o)
- dout_r <= dout;
- end
+ wire strobe_write;
+ assign strobe_write = strobe_o & write_o;
+ wire strobe_read;
+ assign strobe_read = strobe_o & read_o;
+
+ reg strobe_write_was_high;
+ initial strobe_write_was_high = 0;
wire break_i;
reg send_k;
reg data_to_fleet_read_enable;
reg [7:0] force_reset;
+ reg data_to_host_full_bit;
+
assign clk_out = clk_pin;
wire sio_ce;
count_out <= 0;
force_reset <= 0;
credits = 0;
+ data_to_host_full_bit <= 0;
`reset
end else begin
`cleanup
+ if (strobe_read) begin
+ din <= { 1'b0, data_to_host_full_bit, data_to_host };
+ data_to_host_full_bit <= 0;
+ end
+
// fpga -> host
data_to_host_write_enable <= 0;
if (force_reset == 1) begin
`reset
end else if (force_reset != 0) begin
force_reset <= force_reset-1;
- end else if (count_out==0 && `in_full) begin
+ end else if (count_out==0 && `in_full && data_to_host_full_bit==0) begin
`drain_in
data_to_host_full_word <= in_d;
count_out <= 8;
- end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0) begin
+ end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=0 && data_to_host_full_bit==0) begin
data_to_host <= { 2'b0, data_to_host_full_word[5:0] };
data_to_host_full_word <= (data_to_host_full_word >> 6);
- data_to_host_write_enable <= 1;
+ data_to_host_full_bit <= 1;
count_out <= count_out-1;
credits = credits - 1;
end
// host -> fpga
data_to_fleet_read_enable <= 0;
+
+ if (!strobe_write && strobe_write_was_high) begin
+ strobe_write_was_high <= 0;
+
+ end else if (strobe_write && !strobe_write_was_high && (force_reset == 0)) begin
+ strobe_write_was_high <= 1;
+ // command 0: data
+ if (dout[7:6] == 2'b00 && `out_empty) begin
+ out_d <= { out_d[43:0], dout[5:0] };
+ if (count_in==9) begin
+ count_in <= 0;
+ `fill_out
+ end else begin
+ count_in <= count_in+1;
+ end
+
+ // command 1: flow control credit
+ end else if (dout[7:6] == 2'b01) begin
+ credits = credits + dout[5:0];
+
+ // command 3: reset (and echo back reset code)
+ end else if (dout[7:6] == 2'b11) begin
+ data_to_host <= dout[7:0];
+ data_to_host_full_bit <= 1;
+ force_reset <= 255;
+
+ end
+
+ end else
if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
// Note: if the switch fabric refuses to accept a new item,
--- /dev/null
+package edu.berkeley.fleet.fpga;
+import edu.berkeley.fleet.fpga.*;
+import edu.berkeley.fleet.api.*;
+import java.io.*;
+import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.sbp.util.ANSI;
+import java.io.*;
+import java.net.*;
+import edu.berkeley.fleet.util.*;
+import java.util.*;
+import java.util.concurrent.*;
+import static edu.berkeley.fleet.two.FleetTwoFleet.*;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Predicate.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+import com.sun.electric.tool.io.ExecProcess;
+
+public abstract class JtagConnectedFpga extends Fpga {
+
+ protected JtagConnectedFpga() throws IOException {
+ }
+
+ public FleetProcess run(Instruction[] instructions) {
+ try {
+ return new JtagConnectedFpgaClient(this, "none", instructions);
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+
+ public static class JtagConnectedFpgaClient extends FleetProcess {
+
+ private Fpga fpga;
+ private BlockingQueue<BitVector> queue = new LinkedBlockingQueue<BitVector>();
+ public PrintWriter pwjtag;
+ private Semaphore semaphore = new Semaphore(0);
+ private Semaphore peekSemaphore = new Semaphore(0);
+
+ public Fleet getFleet() { return fpga; }
+ public Dock getDebugInputDock() { return fpga.getShip("Debug",0).getDock("in"); }
+ public BitVector recvWord() {
+ if (isTerminated()) throw new RuntimeException("this fleet has been terminated");
+ try {
+ return queue.take();
+ } catch (InterruptedException e) { throw new RuntimeException(e); }
+ }
+ protected void _terminate() {
+ try {
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.close();
+ pwjtag = null;
+ }
+ } catch (Exception e) { e.printStackTrace(); }
+ }
+
+ public void flush() {
+ try {
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.flush();
+ }
+ } catch (Exception e) { e.printStackTrace(); }
+ }
+
+ public void masterClear() {
+ try {
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.println("poke 0 "+((3<<6) | 27));
+ pw.flush();
+ }
+
+ // it's important to acquire the semaphore first, then clear the queue
+ semaphore.acquire();
+ queue.clear();
+ } catch (Exception e) { throw new RuntimeException(); }
+ }
+
+
+ public JtagConnectedFpgaClient(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
+ this.fpga = fpga;
+
+ ExecProcess jtag = new ExecProcess(new String[] { "ssh", "root@goliath.megacz.com", "cd ~/fleet; jtag" }, null);
+ jtag.redirectStderr(System.err);
+ jtag.start();
+
+ pwjtag = new PrintWriter(new OutputStreamWriter(jtag.getStdin()));
+ final BufferedReader pwjtagin = new BufferedReader(new InputStreamReader(jtag.getStdout()));
+ new Thread() {
+ public void run() {
+ try {
+ int i=0;
+ long result = 0;
+ while(true) {
+ String sin = pwjtagin.readLine();
+ if (sin==null) return;
+ if (sin.indexOf("URJ_BUS_READ(")==-1) {
+ if (sin.startsWith("Parsing "))
+ System.err.print("\r"+sin+ANSI.clreol());
+ else
+ System.err.println(sin);
+ continue;
+ }
+ sin = sin.substring(sin.indexOf("URJ_BUS_READ("));
+ sin = sin.substring(sin.indexOf(" = 0x"));
+ sin = sin.substring(" = 0x".length());
+ sin = sin.substring(0, sin.indexOf(' '));
+ int val = Integer.parseInt(sin, 16);
+ if (val < 256) continue;
+ val = val & 0xff;
+ //System.err.println("READ: 0x"+Integer.toString(val & 0xff, 16));
+ if ((val & (3<<6)) == 0) {
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.println("poke 0 "+((1<<6) | 1));
+ }
+ peekSemaphore.release(3);
+ result |= ((val & 0xffL) << (i * 6L));
+ i++;
+ if (i==8) {
+ BitVector bs = new BitVector(37);
+ for(int j=0; j<37; j++)
+ bs.set(j, ((result >> j) & 1L)!=0);
+ queue.put(bs);
+ i = 0;
+ result = 0;
+ }
+ } else {
+ i = 0;
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.println("poke 0 "+((1<<6) | 15));
+ pw.flush();
+ }
+ peekSemaphore.release(3);
+ semaphore.release();
+ }
+
+ }
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ }.start();
+
+ PrintWriter pw = pwjtag;
+ //pw.println("cable Signalyzer");
+ pw.println("cable gnICE+");
+ pw.println("frequency 15000000");
+
+ //pw.println("bsdl path misc/bsdl");
+ //pw.println("detect");
+ pw.println("addpart 10");
+ pw.println("addpart 8");
+ pw.println("addpart 8");
+ pw.println("addpart 16");
+ pw.println("addpart 16");
+ pw.println("part 1");
+ pw.println("instruction BYPASS");
+ pw.println("part 2");
+ pw.println("instruction BYPASS");
+ pw.println("part 3");
+ pw.println("instruction BYPASS");
+ pw.println("part 4");
+ pw.println("instruction BYPASS");
+
+ pw.println("part 0");
+ pw.println("svf /root/fleet/build/ml509.small/main.svf stop progress");
+ pw.flush();
+
+ //# fjmem commands
+ pw.println("register IR 10");
+ pw.println("initbus fjmem opcode=1111000010");
+ pw.flush();
+
+ System.err.println("done programming.");
+
+ // the thread that periodically sends a peek request
+ new Thread() {
+ public void run() {
+ try {
+ while(true) {
+ peekSemaphore.tryAcquire(100, TimeUnit.MILLISECONDS);
+ int avail = peekSemaphore.availablePermits();
+ PrintWriter pw = pwjtag;
+ if (pw==null) return;
+ synchronized(pw) {
+ pw.println("peek 0");
+ if (avail==0) pw.flush();
+ }
+ }
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ }.start();
+
+ masterClear();
+ if (instructions!=null) {
+ for(Instruction inst : instructions) sendInstruction(inst);
+ flush();
+ }
+ }
+
+ public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), null, true); }
+ public void sendWord(Destination d, BitVector word) { sendWord(d, word, null, false); }
+ public void sendWord(Destination d, BitVector word, BitVector signal) { sendWord(d, word, signal, false); }
+ private void sendWord(Destination d, BitVector word, BitVector signal, boolean token) {
+ try {
+ Dock dispatchFrom = fpga.debugShip.getDock("in");
+ long out = 0;
+ out = fpga.PACKET_DATA.setval(out, word);
+ out = fpga.PACKET_TOKEN.setval(out, token ? 1 : 0);
+ out = signal==null ? fpga.PACKET_SIGNAL.setval(out, 0) : fpga.PACKET_SIGNAL.setval(out, signal);
+ out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
+ synchronized(this) {
+ for(int i=9; i>=0; i--)
+ synchronized(pwjtag) {
+ pwjtag.println("poke 0 "+(BitManipulations.getIntField(i*6+5, i*6, out)&0xff));
+ //pwjtag.flush();
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ public void sendInstruction(Instruction inst) {
+ Dock dispatchFrom = fpga.debugShip.getDock("in");
+ sendWord(inst.dock.getInstructionDestination(),
+ new BitVector(fpga.getWordWidth()).set(fpga.writeInstruction(inst, dispatchFrom)));
+ }
+
+ private static Move discard(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, true, false, false, false, false); }
+ private static Move deliver(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, false, false, false, false, true, false); }
+ private static Move wait(Dock dock) { return new Move(dock, IgnoreFlagD, false, null, true, false, false, false, false, false); }
+ private static Move sendto(Dock dock, Path path) { return new Move(dock, IgnoreFlagD, false, path, false, false, false, false, true, false); }
+ }
+}
+