datum on the in port is tested for. The former portion (mux, demux,
swap) determines the *action* to be taken if the condition tests true.
+\begin{verbatim}
action condition effect
------ --------- -------------------------------
swap false in1->out1 in2->out2
mux true in2->out1
demux false in1->out1
demux true in1->out2
+\end{verbatim}
In each case, the ship will wait for a datum to be available on all
input ports (and only those ports) mentioned in the appropriate row of
== Fleeterpreter ====================================================
private Packet selector;
public void service() {
- if (!box_out1.readyForItemFromShip() || !box_out2.readyForItemFromShip()) return;
+ if (!box_out1.readyForDataFromShip() || !box_out2.readyForDataFromShip()) return;
if (selector == null && !box_in.dataReadyForShip()) return;
if (selector == null) selector = box_in.removePacketForShip();
String port = selector.destination.getDestinationName();
if (port.startsWith("mux") && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return;
if (port.startsWith("deMux") && (!box_in1.dataReadyForShip())) return;
- long val = box_in.removeDataForShip();
+ long val = selector.value;
boolean condition = false;
if (port.endsWith("IfZero")) condition = val==0;
if (port.endsWith("IfNonZero")) condition = val!=0;
if (condition) {
box_out1.addDataFromShip(box_in2.removeDataForShip());
box_out2.addDataFromShip(box_in1.removeDataForShip());
+ selector = null;
} else {
box_out1.addDataFromShip(box_in1.removeDataForShip());
box_out2.addDataFromShip(box_in2.removeDataForShip());
+ selector = null;
}
} else if (port.startsWith("mux")) {
box_out1.addDataFromShip(condition ? box_in2.removeDataForShip() : box_in1.removeDataForShip());
+ selector = null;
} else if (port.startsWith("deMux")) {
(condition ? box_out2 : box_out1).addDataFromShip(box_in1.removeDataForShip());
+ selector = null;
}
}
reg have_out2;
reg fire;
+ reg zero;
+ reg pos;
+ reg neg;
+
always @(posedge clk) begin
+
if (!have_in1) begin
- `onread(in1_r, in1_a) have_in1 = 1; reg_in1 = in1_d; end
+ `onread(in1_r, in1_a) have_in1 <= 1; reg_in1 <= in1_d; end
end
if (!have_in2) begin
- `onread(in2_r, in2_a) have_in2 = 1; reg_in2 = in2_d; end
+ `onread(in2_r, in2_a) have_in2 <= 1; reg_in2 <= in2_d; end
end
if (!have_in) begin
- `onread(in_r, in_a) have_in = 1; reg_in = in_d; end
+ `onread(in_r, in_a) have_in <= 1; reg_in <= in_d; end
end
if (have_out1) begin
- `onwrite(out1_r, out1_d) have_out1 = 0; end
+ `onwrite(out1_r, out1_a) have_out1 <= 0; end
end
+
if (have_out2) begin
- `onwrite(out2_r, out2_d) have_out2 = 0; end
+ `onwrite(out2_r, out2_a) have_out2 <= 0; end
end
if (have_in && !have_out1 && !have_out2) begin
+ zero = reg_in[`DATAWIDTH-1:0] == 0;
+ neg = reg_in[`DATAWIDTH-1];
+ pos = !zero && !neg;
case (reg_in[`PACKET_WIDTH-1:`DATAWIDTH])
- 00: /* in.swapIfZero */ fire = reg_in[`DATAWIDTH-1:0] == 0;
- 06: /* in.muxIfZero */ fire = reg_in[`DATAWIDTH-1:0] == 0;
- 12: /* in.deMuxIfZero */ fire = reg_in[`DATAWIDTH-1:0] == 0;
- 01: /* in.swapIfNonZero */ fire = reg_in[`DATAWIDTH-1:0] != 0;
- 07: /* in.muxIfNonZero */ fire = reg_in[`DATAWIDTH-1:0] != 0;
- 13: /* in.deMuxIfNonZero */ fire = reg_in[`DATAWIDTH-1:0] != 0;
- 02: /* in.swapIfNegative */ fire = reg_in[`DATAWIDTH-1:0] < 0;
- 08: /* in.muxIfNegative */ fire = reg_in[`DATAWIDTH-1:0] < 0;
- 14: /* in.deMuxIfNegative */ fire = reg_in[`DATAWIDTH-1:0] < 0;
- 03: /* in.swapIfPositive */ fire = reg_in[`DATAWIDTH-1:0] > 0;
- 09: /* in.muxIfPositive */ fire = reg_in[`DATAWIDTH-1:0] > 0;
- 15: /* in.deMuxIfPositive */ fire = reg_in[`DATAWIDTH-1:0] > 0;
- 04: /* in.swapIfNonNegative */ fire = reg_in[`DATAWIDTH-1:0] >= 0;
- 16: /* in.deMuxIfNonNegative */ fire = reg_in[`DATAWIDTH-1:0] >= 0;
- 10: /* in.muxIfNonNegative */ fire = reg_in[`DATAWIDTH-1:0] >= 0;
- 05: /* in.swapIfNonPositive */ fire = reg_in[`DATAWIDTH-1:0] <= 0;
- 11: /* in.muxIfNonPositive */ fire = reg_in[`DATAWIDTH-1:0] <= 0;
- 17: /* in.deMuxIfNonPositive */ fire = reg_in[`DATAWIDTH-1:0] <= 0;
+ 00: fire = zero;
+ 06: fire = zero;
+ 12: fire = zero;
+ 01: fire = !zero;
+ 07: fire = !zero;
+ 13: fire = !zero;
+ 02: fire = neg;
+ 08: fire = neg;
+ 14: fire = neg;
+ 03: fire = pos;
+ 09: fire = pos;
+ 15: fire = pos;
+ 04: fire = !neg;
+ 16: fire = !neg;
+ 10: fire = !neg;
+ 05: fire = !pos;
+ 11: fire = !pos;
+ 17: fire = !pos;
endcase
if (reg_in[`PACKET_WIDTH-1:`DATAWIDTH] <= 5) begin
- if (have_in1 && have_in2) begin
- have_out1 = 1;
- have_out2 = 1;
- have_in1 = 0;
- have_in2 = 0;
- out1_d = fire ? reg_in2 : reg_in1;
- out2_d = fire ? reg_in1 : reg_in2;
+ if (have_in1 && have_in2 && !have_out1 && !have_out2) begin
+ have_out1 <= 1;
+ have_out2 <= 1;
+ have_in1 <= 0;
+ have_in2 <= 0;
+ have_in <= 0;
+ out1_d <= fire ? reg_in2 : reg_in1;
+ out2_d <= fire ? reg_in1 : reg_in2;
end
end else if (reg_in[`PACKET_WIDTH-1:`DATAWIDTH] <= 11) begin
if (fire && have_in2) begin
- have_out1 = 1;
- have_in2 = 0;
- out1_d = in2_d;
+ have_out1 <= 1;
+ have_in2 <= 0;
+ out1_d <= in2_d;
+ have_in <= 0;
end else if (!fire && have_in1) begin
- have_out1 = 1;
- have_in1 = 0;
- out1_d = in1_d;
+ have_out1 <= 1;
+ have_in1 <= 0;
+ out1_d <= in1_d;
+ have_in <= 0;
end
end else begin
if (have_in1) begin
if (fire) begin
- have_out2 = 1;
- out2_d = in1_d;
- have_in1 = 0;
+ have_out2 <= 1;
+ out2_d <= in1_d;
+ have_in1 <= 0;
+ have_in <= 0;
end else begin
- have_out1 = 1;
- out1_d = in1_d;
- have_in1 = 0;
+ have_out1 <= 1;
+ out1_d <= in1_d;
+ have_in1 <= 0;
+ have_in <= 0;
end
end
end
+
end
+
end
+== Test ==============================================================================
+#skip
+#ship debug : Debug
+#expect 0
+0: sendto debug.in;
+
== Contributors =========================================================
Adam Megacz <megacz@cs.berkeley.edu>