data out: out
== Fleeterpreter ====================================================
-public void service() { }
+
+boolean full = false;
+boolean op_count = false;
+boolean op_repeat = false;
+boolean op_pass = false;
+boolean op_drop = false;
+boolean op_c1 = false;
+boolean op_c2 = false;
+boolean op_v1 = false;
+boolean op_v2 = false;
+long temp = 0;
+boolean out_draining;
+
+public void reset() {
+ super.reset();
+ full = false;
+ temp = 0;
+ out_draining = false;
+}
+public void service() {
+
+ if (!box_inOp.dataReadyForShip()) full = false;
+
+ if (out_draining && box_out.readyForDataFromShip()) {
+ if (op_count) temp = temp - box_in2.peekDataForShip();
+ else temp--;
+ if (op_pass && op_v1) box_in1.removeDataForShip();
+ if (op_pass && op_v2) box_in2.removeDataForShip();
+ out_draining = false;
+
+ } else if (box_inOp.dataReadyForShip()) {
+ long op = box_inOp.peekDataForShip();
+ op_count = (op & 15)==12;
+ op_repeat = ((op>>2) & 3)==0;
+ op_pass = ((op>>2) & 3)==1;
+ op_drop = ((op>>2) & 3)==2;
+ op_c1 = (op_repeat || op_pass || op_drop) && !(((op>>1)&1)!=0);
+ op_c2 = (op_repeat || op_pass || op_drop) && (((op>>1)&1)!=0);
+ op_v1 = (op_repeat || op_pass || op_drop) && !(((op>>0)&1)!=0);
+ op_v2 = (op_repeat || op_pass || op_drop) && (((op>>0)&1)!=0);
+ if (!full) {
+ if (op_count && box_in1.dataReadyForShip() && box_in2.dataReadyForShip()) {
+ temp = box_in1.peekDataForShip() - box_in2.peekDataForShip();
+ box_in1.removeDataForShip();
+ full = true;
+ } else if (op_c1 && box_in1.dataReadyForShip()) {
+ temp = box_in1.peekDataForShip() - 1;
+ box_in1.removeDataForShip();
+ full = true;
+ } else if (op_c2 && box_in2.dataReadyForShip()) {
+ temp = box_in2.peekDataForShip() - 1;
+ box_in2.removeDataForShip();
+ full = true;
+ }
+ } else if (temp < 0) {
+ full = false;
+ box_inOp.removeDataForShip();
+ if (op_count) box_in2.removeDataForShip();
+ else if (op_repeat && op_v1) box_in1.removeDataForShip();
+ else if (op_repeat && op_v2) box_in2.removeDataForShip();
+
+ } else if (box_out.readyForDataFromShip()) {
+ if (op_count) {
+ out_draining = true;
+ box_out.addDataFromShip(temp, (temp - box_in2.peekDataForShip()) < 0);
+ } else if (op_v1 && box_in1.dataReadyForShip()) {
+ if (op_drop) { box_in1.removeDataForShip(); temp--; }
+ else { box_out.addDataFromShip(box_in1.peekDataForShip(), temp<=0); out_draining = true; }
+ } else if (op_v2 && box_in2.dataReadyForShip()) {
+ if (op_drop) { box_in2.removeDataForShip(); temp--; }
+ else { box_out.addDataFromShip(box_in2.peekDataForShip(), temp<=0); out_draining = true; }
+ }
+ }
+ }
+}
== FleetSim ==============================================================
== FPGA ==============================================================
- reg [`DATAWIDTH-1:0] temp;
- initial temp = {`DATAWIDTH{1'b1}};
+ wire [3:0] inOp_d_trunc;
+ assign inOp_d_trunc = inOp_d[3:0];
+
+ reg [`WORDWIDTH-1:0] temp;
+ initial temp = {`WORDWIDTH{1'b1}};
+ reg out_draining;
reg full;
initial full = 0;
- wire op_count; assign op_count = inOp_d==12;
+ reg c_flag;
+ wire op_count; assign op_count = inOp_d_trunc==12;
wire op_repeat; assign op_repeat = inOp_d[3:2]==0;
wire op_pass; assign op_pass = inOp_d[3:2]==1;
wire op_drop; assign op_drop = inOp_d[3:2]==2;
wire op_c2; assign op_c2 = (op_repeat || op_pass || op_drop) && inOp_d[1];
wire op_v1; assign op_v1 = (op_repeat || op_pass || op_drop) && !inOp_d[0];
wire op_v2; assign op_v2 = (op_repeat || op_pass || op_drop) && inOp_d[0];
- assign out_d_ = op_v1 ? in1_d : op_v2 ? in2_d : temp;
+
+ wire [`WORDWIDTH-1:0] pre_out;
+ assign pre_out = op_v1 ? in1_d : op_v2 ? in2_d : temp;
+ assign out_d_ = { c_flag, pre_out };
// FIXME: REPEAT with a count of zero will not work properly
+ wire [`WORDWIDTH-1:0] temp_minus_in2;
+ assign temp_minus_in2 = (temp - in2_d);
+
always @(posedge clk) begin
- if (!rst) begin
+ if (rst) begin
`reset
full <= 0;
+ out_draining <= 0;
+ c_flag <= 0;
end else begin
- `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 (!inOp_r && !inOp_a) full <= 0;
- if (out_r && out_a) begin
- out_r <= 0;
- if (op_count) temp <= temp - in2_d;
+ `cleanup
+ if (`inOp_empty) full <= 0;
+ if (out_draining && `out_empty) begin
+ if (op_count) temp <= temp_minus_in2;
else temp <= temp - 1;
- if (op_pass && op_v1) in1_a <= 1;
- if (op_pass && op_v2) in2_a <= 1;
- end else if (inOp_r && !inOp_a) begin
+ if (op_pass && op_v1) `drain_in1
+ if (op_pass && op_v2) `drain_in2
+ out_draining <= 0;
+ end else if (`inOp_full) begin
if (!full) begin
- if (op_count && in1_r && !in1_a && in2_r && !in2_a) begin
- temp <= in1_d[`DATAWIDTH-1:0] - in2_d[`DATAWIDTH-1:0];
- in1_a <= 1;
+ if (op_count && `in1_full && `in2_full) begin
+ temp <= in1_d[`WORDWIDTH-1:0] - in2_d[`WORDWIDTH-1:0];
+ `drain_in1
full <= 1;
- end else if (op_c1 && in1_r && !in1_a) begin
- temp <= in1_d[`DATAWIDTH-1:0]-1;
- in1_a <= 1;
+ end else if (op_c1 && `in1_full) begin
+ temp <= in1_d[`WORDWIDTH-1:0]-1;
+ `drain_in1
full <= 1;
- end else if (op_c2 && in2_r && !in2_a) begin
- temp <= in2_d[`DATAWIDTH-1:0]-1;
- in2_a <= 1;
+ end else if (op_c2 && `in2_full) begin
+ temp <= in2_d[`WORDWIDTH-1:0]-1;
+ `drain_in2
full <= 1;
end
- end else if (temp[`DATAWIDTH-1]) begin
+ end else if (temp[`WORDWIDTH-1]) begin
full <= 0;
- inOp_a <= 1;
+ `drain_inOp
if (op_count) begin
- in2_a <= 1;
+ `drain_in2
end else if (op_repeat && op_v1) begin
- in1_a <= 1;
+ `drain_in1
end else if (op_repeat && op_v2) begin
- in2_a <= 1;
+ `drain_in2
end
- end else if (!out_r && !out_a) begin
+ end else if (`out_empty) begin
if (op_count) begin
- out_r <= 1;
- end else if (op_v1 && in1_r && !in1_a) begin
- if (op_drop) begin in1_a <= 1; temp <= temp-1; end
- else out_r <= 1;
- end else if (op_v2 && in2_r && !in2_a) begin
- if (op_drop) begin in2_a <= 1; temp <= temp-1; end
- else out_r <= 1;
+ `fill_out
+ out_draining <= 1;
+ c_flag <= temp_minus_in2[`WORDWIDTH-1];
+ end else if (op_v1 && `in1_full) begin
+ if (op_drop) begin `drain_in1 temp <= temp-1; end
+ else begin `fill_out out_draining <= 1; end
+ c_flag <= (temp==0);
+ end else if (op_v2 && `in2_full) begin
+ if (op_drop) begin `drain_in2 temp <= temp-1; end
+ else begin `fill_out out_draining <= 1; end
+ c_flag <= (temp==0);
end
end
end
#expect 6
#expect 3
#expect 0
+#expect -1
#expect 2
#expect 1
#expect 0
+#expect -1
#expect 2
#expect 2
#expect 2
#expect 2
+#expect -1
#expect 9
#expect 9
#expect 9
+#expect -1
debug.in:
set ilc=*;
deliver;
counter.out:
- set ilc=*;
+ head;
collect, send to debug.in;
+ set flags a=c, b=b;
+ set word=-1;
+ [a] send to debug.in;
+ tail;
== Contributors =========================================================