constant DROP1: 7
constant DROP2: 8
constant MAXMERGE: 9
+ constant AND: 10
+ constant OR: 11
+ constant XOR: 12
data out: out
b = box_in2.removeDataForShip();
box_out.addDataFromShip(a-b); // SUB
break;
- case 9:
+
+ case 9: // MAXMERGE
if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) {
a = box_in1.removeDataForShip();
b = box_in2.removeDataForShip();
box_out.addDataFromShip(a, false);
break;
}
- // fall through
+ // fall through to MAX
case 4:
a = box_in1.peekDataForShip();
b = box_in2.peekDataForShip();
box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX
- if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
+ if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
break;
+
case 5:
a = box_in1.peekDataForShip();
b = box_in2.peekDataForShip();
box_out.addDataFromShip(Math.min(a,b), a>b); // MIN
- if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
+ if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
break;
case 6:
a = box_in1.removeDataForShip();
box_in2.removeDataForShip(); // DROP2
break;
*/
+ case 10:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(a & b); // CMP
+ break;
+ case 11:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(a | b); // CMP
+ break;
+ case 12:
+ a = box_in1.removeDataForShip();
+ b = box_in2.removeDataForShip();
+ box_out.addDataFromShip(a ^ b); // CMP
+ break;
default:
throw new RuntimeException("invalid opcode: " + op);
}
wire eq;
wire cout;
- wire [3:0] inOp_d_trunc;
- assign inOp_d_trunc = inOp_d[3:0];
+ wire [4:0] inOp_d_trunc;
+ assign inOp_d_trunc = inOp_d[4:0];
- assign isplus = inOp_d_trunc[2:0]==2;
+ assign isplus = inOp_d_trunc[4:0]==2;
assign cin = isplus ? 0 : 1;
assign in2_inverted = isplus ? in2_d : ~in2_d;
assign sum = {in1_d,cin} + {in2_inverted,cin};
(inOp_d_trunc==5) ? (greater ? in2_d : in1_d) :
(inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq } :
(inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
+ (inOp_d_trunc==10) ? (in1_d & in2_d) :
+ (inOp_d_trunc==11) ? (in1_d | in2_d) :
+ (inOp_d_trunc==12) ? (in1_d ^ in2_d) :
0;
+ wire firing_condition;
+ assign firing_condition =
+ (inOp_d_trunc==0) ? `in1_full :
+ (inOp_d_trunc==1) ? `in2_full :
+ (inOp_d_trunc==7) ? `in1_full :
+ (inOp_d_trunc==8) ? `in2_full :
+ ((`in1_full) && (`in2_full));
+
always @(posedge clk) begin
- if (!rst) begin
+ if (rst) begin
`reset
out_draining <= 0;
end else begin
- `flush
`cleanup
if (out_draining && `out_empty) begin
`drain_inOp
out_draining <= 0;
if (inOp_d_trunc==0) `drain_in1
else if (inOp_d_trunc==1) `drain_in2
+ else if (inOp_d_trunc==7) `drain_in1
+ else if (inOp_d_trunc==8) `drain_in2
else if (inOp_d_trunc==9 && both_negative) begin `drain_in1 `drain_in2 end
else if (inOp_d_trunc==4 && greater) `drain_in1
else if (inOp_d_trunc==5 && greater) `drain_in2
`drain_in2
end
end
- if (!out_draining && `out_empty && `in1_full && `in2_full && `inOp_full) begin
- `fill_out
+ if (!out_draining && `out_empty && firing_condition && `inOp_full) begin
+ if (inOp_d_trunc!=7 && inOp_d_trunc!=8) `fill_out
out_draining <= 1;
end
end