constant MAX: 4
constant MIN: 5
constant CMP: 6
+ constant DROP1: 7
+ constant DROP2: 8
+ constant MAXMERGE: 9
data out: out
\subsection*{C-Flag}
\begin{verbatim}
-IN1 - undefined
-IN2 - undefined
-ADD - carry-out
-SUB - undefined
-MAX - 0 if in1>in2, else 1
-MIN - 1 if in1>in2, else 0
-CMP - 0 if in1!=in2, else 1
+IN1 - undefined; drain in1 only
+IN2 - undefined; drain in2 only
+ADD - carry-out
+SUB - undefined
+MAX - if in1>in2 cflag=0 and drain in1, else cflag=1 and drain in2
+MIN - if in1>in2 cflag=1 and drain in2, else cflag=0 and drain in1
+CMP - if in1==in2 cflag=1, else cflag=0
+DROP1 - consume in1, produce no output
+DROP2 - consume in2, produce no output
+MAXMERGE - if (in1<0 && in2<0) consume both, emit either, cflag=undef else act as MAX
\end{verbatim}
\subsection*{To Do}
== Fleeterpreter ====================================================
public void service() {
- if (box_in1.dataReadyForShip() &&
+ if (box_inOp.dataReadyForShip() &&
+ box_in1.dataReadyForShip() &&
box_in2.dataReadyForShip() &&
- box_inOp.dataReadyForShip() &&
box_out.readyForDataFromShip()) {
- long a = box_in1.removeDataForShip();
- long b = box_in2.removeDataForShip();
+ long a;
+ long b;
long op = box_inOp.removeDataForShip();
switch((int)op) {
- case 0: box_out.addDataFromShip(a); // IN1
+ case 0:
+ a = box_in1.removeDataForShip();
+ box_out.addDataFromShip(a); // IN1
break;
- case 1: box_out.addDataFromShip(b); // IN2
+ case 1:
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(b); // IN2
break;
- case 2: box_out.addDataFromShip(a+b); // ADD
+ case 2:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(a+b); // ADD
break;
- case 3: box_out.addDataFromShip(a-b); // SUB
+ case 3:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(a-b); // SUB
break;
- case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX
+ case 4:
+ a = box_in1.peekDataForShip();
+ b = box_in2.peekDataForShip();
+ box_out.addDataFromShip(Math.max(a,b)); // MAX
box_out.flag_c = !(a>b);
+ if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
break;
- case 5: box_out.addDataFromShip(Math.min(a,b)); // MIN
+ case 5:
+ a = box_in1.peekDataForShip();
+ b = box_in2.peekDataForShip();
+ box_out.addDataFromShip(Math.min(a,b)); // MIN
box_out.flag_c = a>b;
+ if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
break;
- default: box_out.addDataFromShip(0);
+ case 6:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(0); // CMP
+ box_out.flag_c = a==b;
+ break;
+ default:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(0);
break;
}
}
wire eq;
wire cout;
- assign isplus = inOp_d[2:0]==2;
- assign cin = isplus ? 0 : 1;
- assign in2_inverted = isplus ? in2_d : ~in2_d;
- assign sum = {in1_d,cin} + {in2_inverted,cin};
- assign res = sum[`DATAWIDTH:1];
- assign greater = !res[`DATAWIDTH-1];
- assign eq = in1_d == in2_d;
- assign cout = sum[`DATAWIDTH];
+ assign isplus = inOp_d[2:0]==2;
+ assign cin = isplus ? 0 : 1;
+ assign in2_inverted = isplus ? in2_d : ~in2_d;
+ assign sum = {in1_d,cin} + {in2_inverted,cin};
+ assign res = sum[`DATAWIDTH:1];
+ assign greater = !res[`DATAWIDTH-1];
+ assign both_negative = in1_d[`DATAWIDTH-1] && in2_d[`DATAWIDTH-1];
+ assign eq = in1_d == in2_d;
+ assign cout = sum[`DATAWIDTH];
assign out_d_[`DATAWIDTH] =
(inOp_d==0) ? 1'b0 :
(inOp_d==1) ? 1'b0 :
(inOp_d==2) ? cout :
- (inOp_d==3) ? 1'b0 :
+ (inOp_d==3) ? cout :
(inOp_d==4) ? ~greater :
(inOp_d==5) ? greater :
(inOp_d==6) ? eq :
+ (inOp_d==9) ? ~greater :
0;
assign out_d_[(`DATAWIDTH-1):0] =
(inOp_d==4) ? (greater ? in1_d : in2_d) :
(inOp_d==5) ? (greater ? in2_d : in1_d) :
(inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq } :
+ (inOp_d==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
0;
always @(posedge clk) begin
if (!rst) begin
`reset
end else begin
- if (!in1_r && in1_a) in1_a <= 0;
- if (!in2_r && in2_a) in2_a <= 0;
- if (!inOp_r && inOp_a) inOp_a <= 0;
+ `flush
+ if (!in1_r_ && in1_a) in1_a <= 0;
+ if (!in2_r_ && in2_a) in2_a <= 0;
+ if (!inOp_r_ && inOp_a) inOp_a <= 0;
if (out_r && out_a) begin
- out_r <= 0;
- in1_a <= 1;
- in2_a <= 1;
+ out_r <= 0;
inOp_a <= 1;
+
+ if (inOp_d==0) in1_a <= 1;
+ else if (inOp_d==1) in2_a <= 1;
+ else if (inOp_d==9 && both_negative) begin in1_a <= 1; in2_a <= 1; end
+ else if (inOp_d==4 && greater) in1_a <= 1;
+ else if (inOp_d==5 && greater) in2_a <= 1;
+ else if (inOp_d==9 && greater) in1_a <= 1;
+ else if (inOp_d==4 && !greater) in2_a <= 1;
+ else if (inOp_d==5 && !greater) in1_a <= 1;
+ else if (inOp_d==9 && !greater) in2_a <= 1;
+ else begin
+ in1_a <= 1;
+ in2_a <= 1;
+ end
end
if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
out_r <= 1;
#expect 9
#expect 0
#expect 0
-#expect 0
-#expect 1
#expect 1
debug.in: set ilc=*; recv, deliver;
alu.in1:
set word= 9;
- set ilc=7;
+ set ilc=5;
deliver;
set word= 9;
deliver;
alu.in2:
set word= 8;
- set ilc=7;
+ set ilc=5;
deliver;
set word= 9;
deliver;
set word= Alu.inOp[SUB]; deliver;
set word= Alu.inOp[IN1]; deliver;
set word= Alu.inOp[IN2]; deliver;
-
-alu.inOp:
set word= Alu.inOp[MIN]; deliver;
set word= Alu.inOp[MAX]; deliver;
set word= Alu.inOp[CMP]; deliver;
[!a] set word= 0;
send to debug.in;
- collect, send to debug.in; // CMP
+ collect; // CMP
set flags a=c, b=b;
[a] set word= 1;
[!a] set word= 0;
send to debug.in;
- collect, send to debug.in; // CMP
+ collect; // CMP
set flags a=c, b=b;
[a] set word= 1;
[!a] set word= 0;
`reset
state <= 0;
end else begin
- if (!in_r && in_a) in_a <= 0;
+ `flush
+ if (!in_r_ && in_a) in_a <= 0;
if (out_r && out_a) out_r <= 0;
if (!out_r && !out_a && state==3) begin
out_d <= { 1'b0, temp };
end
== Test ==============================================================
-
// expected output
#expect 0x3c4bc6
#expect 0x1796d2
--- /dev/null
+ship: DDR2
+
+== Ports ===========================================================
+data in: inAddrRead
+data in: inAddrWrite
+data in: inDataWrite
+
+data out: out
+
+== TeX ==============================================================
+
+== Fleeterpreter ====================================================
+ public void service() { }
+== FleetSim ==============================================================
+
+== FPGA ==============================================================
+
+ reg ddr2_addr_r;
+ reg ddr2_isread;
+ reg ddr2_write_data_push;
+ reg ddr2_read_data_pop;
+ reg [`DATAWIDTH:0] out_d;
+
+ assign ddr2_addr_r_ = ddr2_addr_r;
+ assign ddr2_isread_ = ddr2_isread;
+ assign ddr2_addr_ = !ddr2_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+ assign ddr2_write_data_push_ = ddr2_write_data_push;
+ assign ddr2_read_data_pop_ = ddr2_read_data_pop;
+ assign ddr2_write_data_ = { inDataWrite_d[31:5], inDataWrite_d[4], inDataWrite_d[35:0] };
+// assign ddr2_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0];
+ assign out_d_ = out_d;
+
+ always @(posedge clk) begin
+
+ if (!rst) begin
+ `reset
+ ddr2_isread <= 0;
+ ddr2_addr_r <= 0;
+ ddr2_read_data_pop <= 0;
+
+ end else begin
+ `flush
+
+ if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0;
+ if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+ if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+ if ( out_r && out_a) out_r <= 0;
+
+ if (ddr2_addr_r && !ddr2_addr_a) begin
+ // busy
+ end else if (ddr2_addr_r && ddr2_addr_a && !ddr2_isread) begin
+ ddr2_addr_r <= 0;
+ inAddrWrite_a <= 1;
+ inDataWrite_a <= 1;
+ out_d <= { 1'b1, 37'b0 };
+ out_r <= 1;
+ end else if (ddr2_addr_r && ddr2_addr_a && ddr2_isread) begin
+ ddr2_addr_r <= 0;
+ inAddrRead_a <= 1;
+ out_d <= { 1'b0, ddr2_read_data[36:0] };
+ out_r <= 1;
+ end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !ddr2_addr_r && !ddr2_addr_a) begin
+ ddr2_addr_r <= 1;
+ ddr2_isread <= 0;
+ end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !ddr2_addr_r && !ddr2_addr_a) begin
+ ddr2_addr_r <= 1;
+ ddr2_isread <= 1;
+ end
+ end
+ end
+
+
+== Test ========================================================
+#skip
+
+== Constants ========================================================
+
+== Contributors =========================================================
+Adam Megacz <megacz@cs.berkeley.edu>
== FPGA ==============================================================
- // FIXME: use the other chip (64-bit data bus)
-
reg dram_addr_r;
reg dram_isread;
reg dram_write_data_push;
reg dram_read_data_pop;
- reg [`DATAWIDTH-1:0] out_d;
+ reg [`DATAWIDTH:0] out_d;
+ wire [31:0] dram_addr__;
assign dram_addr_r_ = dram_addr_r;
assign dram_isread_ = dram_isread;
- assign dram_addr_ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+ assign dram_addr__ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0];
+ assign dram_addr_ = { dram_addr__[30:6], 1'b0, dram_addr__[5:0] };
assign dram_write_data_push_ = dram_write_data_push;
assign dram_read_data_pop_ = dram_read_data_pop;
- assign dram_write_data_ = inDataWrite_d[31:0];
+ assign dram_write_data_ = inDataWrite_d;
+// assign dram_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0];
assign out_d_ = out_d;
always @(posedge clk) begin
dram_read_data_pop <= 0;
end else begin
+ `flush
- if (!inAddrRead_r && inAddrRead_a) inAddrRead_a <= 0;
- if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0;
- if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0;
- if ( out_r && out_a) out_r <= 0;
+ if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0;
+ if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+ if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+ if ( out_r && out_a) out_r <= 0;
if (dram_addr_r && !dram_addr_a) begin
// busy
dram_addr_r <= 0;
inAddrWrite_a <= 1;
inDataWrite_a <= 1;
+ out_d <= { 1'b1, 37'b0 };
+ out_r <= 1;
end else if (dram_addr_r && dram_addr_a && dram_isread) begin
dram_addr_r <= 0;
inAddrRead_a <= 1;
- out_d <= dram_read_data;
+ out_d <= { 1'b0, dram_read_data[36:0] };
out_r <= 1;
- end else if (inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin
+ end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin
dram_addr_r <= 1;
dram_isread <= 0;
- end else if (inAddrRead_r && !inAddrRead_a && !out_r && !out_a && !dram_addr_r && !dram_addr_a) begin
+ end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !dram_addr_r && !dram_addr_a) begin
dram_addr_r <= 1;
dram_isread <= 1;
end
== FPGA ==============================================================
-module debug (clk, rst,
- data_debug_data_r, data_debug_data_a, data_debug_data,
- data_debug_out_r, data_debug_out_a, data_debug_out );
- input clk;
- input rst;
-
- input data_debug_data_r;
- output data_debug_data_a;
- input [`DATAWIDTH:0] data_debug_data;
-
- output data_debug_out_r;
- input data_debug_out_a;
- output [`DATAWIDTH:0] data_debug_out;
-
- assign data_debug_out_r = data_debug_data_r;
- assign data_debug_data_a = data_debug_out_a;
- assign data_debug_out = data_debug_data;
-
-endmodule
+ assign out_d_ = in_d;
+ assign out_r_ = in_r;
+
+ always @(posedge clk) begin
+ if (!rst) begin
+ `reset
+ end else begin
+ `flush
+ in_a <= out_a;
+ end
+ end
== Test ================================================================
#expect 25
== FPGA ==============================================================
- input [(`DATAWIDTH-1):0] in_d;
- output [(`DATAWIDTH-1):0] out_d_;
- input in_r;
- output in_a_;
- output out_r_;
- input out_a;
+ wire in_a__;
+ wire out_r__;
fifo8x37 fifo8x37(clk, rst,
- in_r, in_a_, in_d,
- out_r_, out_a, out_d_);
+ in_r, in_a__, in_d,
+ out_r__, out_a, out_d_);
+
+ always @(posedge clk) begin
+ if (!rst) begin
+ `reset
+ end else begin
+ `flush
+ out_r <= out_r__;
+ in_a <= in_a__;
+ end
+ end
== Test =================================================================
if (!rst) begin
`reset
end else begin
- if (!in1_r && in1_a) in1_a <= 0;
- if (!in2_r && in2_a) in2_a <= 0;
- if (!in3_r && in3_a) in3_a <= 0;
- if (!inLut_r && inLut_a) inLut_a <= 0;
+ `flush
+ if (!in1_r_ && in1_a) in1_a <= 0;
+ if (!in2_r_ && in2_a) in2_a <= 0;
+ if (!in3_r_ && in3_a) in3_a <= 0;
+ if (!inLut_r_ && inLut_a) inLut_a <= 0;
if (out_r && out_a) begin
in1_a <= 1;
in2_a <= 1;
The {\tt Memory} ship represents an interface to a storage space,
which can be used to read from it or write to it. This storage space
-might be a fast on-chip cache, off chip DRAM, or perhaps even a disk drive.
+might be a fast on-chip cache, off chip DRAM, or perhaps even a disk
+drive.
+
+Generally, distinct {\tt Memory} ships do not access the same backing
+storage, although this is not strictly prohibited.
+
+Each {\tt Memory} ship may have multiple {\it interfaces}, numbered
+starting with {\tt 0}. Each interface may have any subset of the
+following docks: {\tt inCBD}, {\tt inAddrRead}, {\tt inAddrWrite},
+{\tt inDataWrite}, and {\tt out}. If {\tt inCBD} or {\tt inAddrRead}
+is present on an interface, then {\tt out} must be present as well.
+If {\tt inAddrWrite} is present then {\tt inDataWrite} must be present
+as well.
+
+Each interface serializes the operations presented to it; this means
+that an interface with both read and write capabilities will not be
+able to read and write concurrently. Instead, a {\tt Memory} ship
+with the ability to read and write concurrently should have two
+interfaces, one which is read-only and one which is write-only.
There may be multiple {\tt Memory} ships which interface to the same
physical storage space. An implementation of Fleet must provide
\subsection*{Reading}
When a word is delivered to {\tt inAddrRead}, the word residing in
-memory at that address is provided at {\tt out}.
+memory at that address is provided at {\tt out}. The {\tt c-flag} at
+the {\tt out} port is set to zero.
\subsection*{Writing}
the word at {\tt inDataWrite} is written to the address specified by
{\tt inAddrWrite}. Once the word is successfully committed to memory,
the value {\tt inAddr+inStride} is provided at {\tt out} (that is, the
-address of the next word to be written).
+address of the next word to be written). The {\tt c-flag} at
+the {\tt out} port is set to one.
\subsection*{To Do}
write_flag <= 0;
dispatching_cbd <= 0;
end else begin
+ `flush
write_flag <= 0;
- if (!inAddrRead_r && inAddrRead_a) inAddrRead_a <= 0;
- if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0;
- if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0;
- if (!inCBD_r && inCBD_a) inCBD_a <= 0;
+ if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0;
+ if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0;
+ if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0;
+ if (!inCBD_r_ && inCBD_a) inCBD_a <= 0;
// assumes we never want a zero-length codebag
if ( inCBD_r && !inCBD_a && !out_r && !out_a) begin
== Test ==============================================================
+// FIXME: test c-flag at out dock
+// FIXME: rename to inCBD0, inAddrWrite0, etc
+
// expected output
#expect 12
#expect 13
if (!rst) begin
`reset
end else begin
- if (!in_r && in_a && !inAmount_r) in_a <= 0;
- if (!inAmount_r && inAmount_a) inAmount_a <= 0;
+ `flush
+ if (!in_r_ && in_a && !inAmount_r) in_a <= 0;
+ if (!inAmount_r_ && inAmount_a) inAmount_a <= 0;
if (out_r && out_a) out_r <= 0;
if (in_r && !in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin
in_a <= 1;
if (!rst) begin
`reset
end else begin
-
+ `flush
vga_pixel_a <= vga_pixel_r;
- if (!inData_r && inData_a) inData_a <= 0;
- if (!inX_r && inX_a) inX_a <= 0;
- if (!inY_r && inY_a) inY_a <= 0;
+ if (!inData_r_ && inData_a) inData_a <= 0;
+ if (!inX_r_ && inX_a) inX_a <= 0;
+ if (!inY_r_ && inY_a) inY_a <= 0;
if (inX_r && !inX_a && inY_r && !inY_a && inData_r && !inData_a) begin
we <= 1;
inX_a <= 1;