X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ships%2FCounter.ship;h=37aa4520b2b746e9869c4f6c17c84977d4073440;hb=daa7ab3d282553b18a61333a3d122813212939e2;hp=dbdb4a5b1e51432f7b5ec989c2959dd5754d7d7b;hpb=caa93dc7618f95e403b52ea834fa1f136d26e43d;p=fleet.git diff --git a/ships/Counter.ship b/ships/Counter.ship index dbdb4a5..37aa452 100644 --- a/ships/Counter.ship +++ b/ships/Counter.ship @@ -20,17 +20,96 @@ data in: inOp 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; @@ -38,39 +117,47 @@ public void service() { } 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 `cleanup if (`inOp_empty) full <= 0; - if (`out_draining) begin - if (op_count) temp <= temp - in2_d; + if (out_draining && `out_empty) begin + if (op_count) temp <= temp_minus_in2; else temp <= temp - 1; 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_full && `in2_full) begin - temp <= in1_d[`DATAWIDTH-1:0] - in2_d[`DATAWIDTH-1:0]; + temp <= in1_d[`WORDWIDTH-1:0] - in2_d[`WORDWIDTH-1:0]; `drain_in1 full <= 1; end else if (op_c1 && `in1_full) begin - temp <= in1_d[`DATAWIDTH-1:0]-1; + temp <= in1_d[`WORDWIDTH-1:0]-1; `drain_in1 full <= 1; end else if (op_c2 && `in2_full) begin - temp <= in2_d[`DATAWIDTH-1:0]-1; + 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; `drain_inOp if (op_count) begin @@ -83,12 +170,16 @@ public void service() { } end else if (`out_empty) begin if (op_count) begin `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 `fill_out + 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 `fill_out + else begin `fill_out out_draining <= 1; end + c_flag <= (temp==0); end end end @@ -103,16 +194,20 @@ public void service() { } #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=*; @@ -147,8 +242,12 @@ counter.inOp: 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 =========================================================