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;