== FPGA ==============================================================
wire break_i;
- reg break_last;
reg send_k;
initial send_k = 0;
wire [7:0] data_to_fleet;
reg data_to_host_write_enable;
reg data_to_fleet_read_enable;
+ reg [7:0] force_reset;
wire sio_ce;
wire sio_ce_x4;
wire break;
wire uart_cts;
assign uart_cts = 0;
- assign rst_out = rst_in || break;
+ assign rst_out = rst_in || (force_reset!=0);
// fst=3 means clock divider is 3+2=5 for a 50Mhz clock => 10Mhz
// using a 33Mhz clock,
break,
break_i);
- // break and break are _active high_
- always @(posedge clk) break_last <= break;
- assign break_i = break && !break_last;
- assign break_done = !break && break_last;
+ reg [16:0] credits;
// fpga -> host
always @(posedge clk) begin
- if (rst) begin
- count_in <= 0;
- count_out <= 0;
+ if (rst_in) begin
+ count_in <= 0;
+ count_out <= 0;
+ force_reset <= 0;
+ credits = 0;
`reset
end else begin
// fpga -> host
data_to_host_write_enable <= 0;
- if (break_i) begin
- end else if (break_done) begin
+ if (force_reset == 1) begin
+ force_reset <= 0;
data_to_host_write_enable <= 1;
- data_to_host <= 111;
- send_k <= 1;
- end else if (send_k) begin
- data_to_host_write_enable <= 1;
- data_to_host <= 107;
- send_k <= 0;
+ credits = 0;
+ count_in <= 0;
+ count_out <= 0;
+ `reset
+ end else if (force_reset != 0) begin
+ force_reset <= force_reset-1;
end else if (count_out==0 && `in_full) 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) begin
+ end else if (count_out!=0 && !data_to_host_full && !data_to_host_write_enable && credits!=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;
count_out <= count_out-1;
+ credits = credits - 1;
end
// host -> fpga
data_to_fleet_read_enable <= 0;
- if (!data_to_fleet_empty && `out_empty && !data_to_fleet_read_enable) begin
- out_d <= { out_d[43:0], data_to_fleet[5:0] };
- data_to_fleet_read_enable <= 1;
- if (count_in==9) begin
- count_in <= 0;
- `fill_out
- end else begin
- count_in <= count_in+1;
- end
+ if (!data_to_fleet_empty && !data_to_fleet_read_enable) begin
+
+ // command 0: data
+ if (data_to_fleet[7:6] == 2'b00 && `out_empty) begin
+ data_to_fleet_read_enable <= 1;
+ out_d <= { out_d[43:0], data_to_fleet[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 (data_to_fleet[7:6] == 2'b01) begin
+ data_to_fleet_read_enable <= 1;
+ credits = credits + data_to_fleet[5:0];
+
+/*
+ // uncommenting this requires changing data_to_host_write_enable
+ // to a blocking assignment, and seems to cause data loss whenever
+ // more than four items are in flight.
+ // command 2: echo
+ end else if (data_to_fleet[7:6] == 2'b10 && !data_to_host_full && !data_to_host_write_enable) begin
+ data_to_fleet_read_enable <= 1;
+ data_to_host <= data_to_fleet;
+ data_to_host_write_enable = 1;
+*/
+
+ // command 3: reset (and echo back reset code)
+ end else if (data_to_fleet[7:6] == 2'b11) begin
+ data_to_fleet_read_enable <= 1;
+ data_to_host <= data_to_fleet;
+ force_reset <= 255;
+
+ end
+
end
end
package edu.berkeley.fleet.fpga;
import static edu.berkeley.fleet.util.BitManipulations.*;
+import java.util.concurrent.Semaphore;
import edu.berkeley.fleet.api.*;
import java.io.*;
import java.net.*;
protected void _terminate() {
try {
+ closed = true;
s.close();
} catch (Exception e) { e.printStackTrace(); }
}
public void flush() {
try {
- dos.flush();
+ synchronized(this) {
+ dos.flush();
+ }
} catch (Exception e) {
throw new RuntimeException(e);
}
}
+ /** the 16550 has a 16-byte FIFO buffer */
+ private final Semaphore sem = new Semaphore(15);
+ private boolean closed = false;
+
public Client(Fpga fpga, String bitfile, Instruction[] instructions) throws Exception {
this.fpga = fpga;
pw.flush();
this.dos = new DataOutputStream(os);
- for(Instruction inst : instructions)
- sendInstruction(inst);
- flush();
- final InputStream is = new BufferedInputStream(s.getInputStream());
+ dos.write( (3<<6) | 9);
+ dos.flush();
+ Thread.sleep(1000);
+
+ final InputStream is0 = s.getInputStream();
+ while(is0.available() > 0) {
+ int i = is0.read();
+ //System.out.println("reset code: " + (i & ~(-1 << 6)));
+ }
+
+ final InputStream is = new BufferedInputStream(is0);
+
Thread t = new Thread() {
public void run() {
try {
while(true) {
+ int count = sem.availablePermits();
+ if (count >= (1<<6)) count = (1<<6)-1;
+ if (count < 1) count = 1;
+ sem.acquire(count);
+ if (closed) return;
+ synchronized(this) {
+ dos.write( (1<<6) | count );
+ if (sem.availablePermits()==0) dos.flush();
+ }
+ }
+ } catch (Exception e) { throw new RuntimeException(e); }
+ }
+ };
+ t.setDaemon(true);
+ t.start();
+
+ t = new Thread() {
+ public void run() {
+ try {
+ while(true) {
long result = 0;
int val = 0;
for(int i=0; i<8; i++) {
val = is.read();
if (val==-1) break;
+ sem.release();
long val2 = (val & 0xffL);
val2 = val2 << (i * 6);
result |= val2;
};
t.setDaemon(true);
t.start();
+
+ for(Instruction inst : instructions) sendInstruction(inst);
+ flush();
+
}
public void sendToken(Destination d) { sendWord(d, new BitVector(fpga.getWordWidth()), true); }
out = fpga.PACKET_DEST.setval(out, ((FpgaPath)dispatchFrom.getPath(d, null)).toLong());
synchronized(this) {
for(int i=9; i>=0; i--)
- dos.write(BitManipulations.getIntField(i*6+7, i*6, out));
+ dos.write(BitManipulations.getIntField(i*6+5, i*6, out));
+ dos.flush();
}
} catch (Exception e) {
throw new RuntimeException(e);
System.err.println("login string: " + sb.toString());
if (!sb.toString().startsWith(pass_string)) return;
final OutputStream os = new BufferedOutputStream(socket.getOutputStream());
- System.err.println("sending breaks...");
- sp.sendBreak(100);
final OutputStream fos = sp.getOutputStream();
final InputStream fis = new BufferedInputStream(sp.getInputStream());
- sign = false;
System.err.println("sending instructions...");
new Thread() {
int r = is.read();
if (r == -1) break;
fos.write(r);
- if (!sign) {
- fos.flush();
- Thread.sleep(100);
- sign = true;
- }
}
fos.flush();
} catch (Exception e) { throw new RuntimeException(e);
}
}.start();
-
System.err.println("reading back...");
while(true) {
long result = 0;
}
if (closed) { os.flush(); return; }
val = fis.read();
- if (!sign) {
- System.err.println("leader byte: 0x" + Integer.toString(val, 16) + " '"+((char)val)+"'");
- continue;
- }
if (val==-1) break;
System.err.println("byte: 0x"+Integer.toString(val & 0xff, 16));
os.write((byte)val);