data in: in1
data in: in2
data in: inOp
- constant ADD: 0
- constant SUB: 1
- constant MAX: 2
- constant MIN: 3
+ constant IN1: 0
+ constant IN2: 1
+ constant ADD: 2
+ constant SUB: 3
+ constant MAX: 4
+ constant MIN: 5
+ constant CMP: 6
data out: out
consumed from {\tt in1} and {\tt in2}. The result of this operation
is then made available at {\tt 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
+\end{verbatim}
+
\subsection*{To Do}
The {\it link bit} and other features of \cite{ies31} are not yet
yet implemented.
== Fleeterpreter ====================================================
-public long resolveLiteral(String literal) {
- if (literal.equals("ADD")) return 0;
- if (literal.equals("SUB")) return 1;
- if (literal.equals("MAX")) return 2;
- if (literal.equals("MIN")) return 3;
- return super.resolveLiteral(literal);
-}
public void service() {
if (box_in1.dataReadyForShip() &&
box_in2.dataReadyForShip() &&
long b = box_in2.removeDataForShip();
long op = box_inOp.removeDataForShip();
switch((int)op) {
- case 0: box_out.addDataFromShip(a+b); // ADD
+ case 0: box_out.addDataFromShip(a); // IN1
break;
- case 1: box_out.addDataFromShip(a-b); // SUB
+ case 1: box_out.addDataFromShip(b); // IN2
break;
- case 2: box_out.addDataFromShip(Math.max(a,b)); // MAX
+ case 2: box_out.addDataFromShip(a+b); // ADD
break;
- case 3: box_out.addDataFromShip(Math.min(a,b)); // MIN
+ case 3: box_out.addDataFromShip(a-b); // SUB
+ break;
+ case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX
+ box_out.flag_c = !(a>b);
+ break;
+ case 5: box_out.addDataFromShip(Math.min(a,b)); // MIN
+ box_out.flag_c = a>b;
break;
default: box_out.addDataFromShip(0);
break;
== FPGA ==============================================================
+ wire [`DATAWIDTH:0] sum;
+ wire cin;
+ wire [(`DATAWIDTH-1):0] in2_inverted;
+
+ wire [(`DATAWIDTH-1):0] res;
+ wire isplus;
+ 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 out_d_[`DATAWIDTH] =
+ (inOp_d==0) ? 1'b0 :
+ (inOp_d==1) ? 1'b0 :
+ (inOp_d==2) ? cout :
+ (inOp_d==3) ? 1'b0 :
+ (inOp_d==4) ? ~greater :
+ (inOp_d==5) ? greater :
+ (inOp_d==6) ? eq :
+ 0;
+
+ assign out_d_[(`DATAWIDTH-1):0] =
+ (inOp_d==0) ? (in1_d) :
+ (inOp_d==1) ? (in2_d) :
+ (inOp_d==2) ? (res) :
+ (inOp_d==3) ? (res) :
+ (inOp_d==4) ? (greater ? in1_d : in2_d) :
+ (inOp_d==5) ? (greater ? in2_d : in1_d) :
+ (inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq } :
+ 0;
+
always @(posedge clk) begin
if (!rst) begin
`reset
end else begin
- if (out_r && out_a) out_r <= 0;
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 && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
- out_r <= 1;
+ if (out_r && out_a) begin
+ out_r <= 0;
in1_a <= 1;
in2_a <= 1;
inOp_a <= 1;
- case (inOp_d)
- 0: out_d <= in1_d + in2_d;
- 1: out_d <= in1_d - in2_d;
- 2: out_d <= in1_d > in2_d ? in1_d : in2_d;
- 3: out_d <= in1_d > in2_d ? in2_d : in1_d;
- default: out_d <= 0;
- endcase
+ end
+ if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin
+ out_r <= 1;
end
end
end
== Test ==============================================================================
-// expected output
+
+// FIXME: need test for ADD carry-out c-flag
+
#ship debug : Debug
#ship alu : Alu2
#expect 17
#expect 1
+#expect 9
#expect 8
+#expect 8
+#expect 1
#expect 9
+#expect 0
+#expect 0
+#expect 0
+#expect 1
+#expect 1
-debug.in: [*] take, deliver;
+debug.in: set ilc=*; recv, deliver;
alu.in1:
- literal 9; load repeat counter with 4; deliver;
+ set word= 9;
+ set ilc=7;
+ deliver;
+ set word= 9;
+ deliver;
alu.in2:
- literal 8; load repeat counter with 4; deliver;
-
-alu.in1: [*] take, deliver;
-alu.in2: [*] take, deliver;
-alu.out: [*] take, sendto debug.in;
-
+ set word= 8;
+ set ilc=7;
+ deliver;
+ set word= 9;
+ deliver;
+
+alu.out:
+ set ilc=4;
+ collect, send to debug.in;
alu.inOp:
- literal Alu2.inOp[ADD]; deliver;
- literal Alu2.inOp[SUB]; deliver;
- literal Alu2.inOp[MIN]; deliver;
- literal Alu2.inOp[MAX]; deliver;
-
+ set word= Alu2.inOp[ADD]; deliver;
+ set word= Alu2.inOp[SUB]; deliver;
+ set word= Alu2.inOp[IN1]; deliver;
+ set word= Alu2.inOp[IN2]; deliver;
+alu.inOp:
+ set word= Alu2.inOp[MIN]; deliver;
+ set word= Alu2.inOp[MAX]; deliver;
+ set word= Alu2.inOp[CMP]; deliver;
+ set word= Alu2.inOp[CMP]; deliver;
+
+alu.out:
+ collect, send to debug.in; // MIN
+ set flags a=c, b=b;
+ [a] set word= 1;
+ [!a] set word= 0;
+ send to debug.in;
+
+ collect, send to debug.in; // MAX
+ set flags a=c, b=b;
+ [a] set word= 1;
+ [!a] set word= 0;
+ send to debug.in;
+
+ collect, send to debug.in; // 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
+ set flags a=c, b=b;
+ [a] set word= 1;
+ [!a] set word= 0;
+ send to debug.in;
== Contributors =========================================================
Adam Megacz <megacz@cs.berkeley.edu>