From: adam Date: Thu, 22 Feb 2007 15:31:52 +0000 (+0100) Subject: added Choice ship X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=0b1d08ffb00e538631d2a5b606791c4a84639bd1;p=fleet.git added Choice ship --- diff --git a/ships/Choice.ship b/ships/Choice.ship new file mode 100644 index 0000000..20dfc4a --- /dev/null +++ b/ships/Choice.ship @@ -0,0 +1,139 @@ +ship: Choice + +== Ports =========================================================== +data in: in1 +data in: in2 + +data in: in.swapIfZero +data in: in.swapIfNonZero +data in: in.swapIfNegative +data in: in.swapIfPositive +data in: in.swapIfNonNegative +data in: in.swapIfNonPositive + +data in: in.muxIfZero +data in: in.muxIfNonZero +data in: in.muxIfNegative +data in: in.muxIfPositive +data in: in.muxIfNonNegative +data in: in.muxIfNonPositive + +data in: in.deMuxIfZero +data in: in.deMuxIfNonZero +data in: in.deMuxIfNegative +data in: in.deMuxIfPositive +data in: in.deMuxIfNonNegative +data in: in.deMuxIfNonPositive + +data out: out1 +data out: out2 + +== Constants ======================================================== + +== TeX ============================================================== + +With judicious programming of its BenkoBoxes, this ship can be used to +implement nearly all forms of selection and branching. + +When data is available at the in port, it is examined. Which +destination the datum has arrived on determines the *condition* the +datum should be tested for and the *action* which should be taken if +the condition holds true. + +The latter portion of the name of the destination (IfZero, +If(Non)Positive, If(Non)Negative) determines the condition which the +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. + + action condition effect + ------ --------- ------------------------------- + swap false in1->out1 in2->out2 + swap true in2->out1 in1->out2 + mux false in1->out1 + mux true in2->out1 + demux false in1->out1 + demux true in1->out2 + +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 +the "effect" column above, and will output them on the corresponding +output ports. + + +== Fleeterpreter ==================================================== +private Packet selector; +public void service() { + if (!box_out1.readyForItemFromShip() || !box_out2.readyForItemFromShip()) return; + if (selector == null && !box_in.dataReadyForShip()) return; + if (selector == null) selector = box_in.removePacketForShip(); + String port = selector.destination.getDestinationName(); + + if (port.startsWith("swap") && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return; + if (port.startsWith("mux") && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return; + if (port.startsWith("deMux") && (!box_in1.dataReadyForShip())) return; + + long val = box_in.removeDataForShip(); + boolean condition = false; + if (port.endsWith("IfZero")) condition = val==0; + if (port.endsWith("IfNonZero")) condition = val!=0; + if (port.endsWith("IfPositive")) condition = val>0; + if (port.endsWith("IfNegative")) condition = val<0; + if (port.endsWith("IfNonPositive")) condition = val<=0; + if (port.endsWith("IfNonNegative")) condition = val>=0; + if (port.startsWith("swap")) { + if (condition) { + box_out1.addDataFromShip(box_in2.removeDataForShip()); + box_out2.addDataFromShip(box_in1.removeDataForShip()); + } else { + box_out1.addDataFromShip(box_in1.removeDataForShip()); + box_out2.addDataFromShip(box_in2.removeDataForShip()); + } + } else if (port.startsWith("mux")) { + box_out1.addDataFromShip(condition ? box_in2.removeDataForShip() : box_in1.removeDataForShip()); + } else if (port.startsWith("deMux")) { + (condition ? box_out2 : box_out1).addDataFromShip(box_in1.removeDataForShip()); + } +} + +== FleetSim ============================================================== + +== FPGA ============================================================== + + // FIXME + reg have_a; + reg [(`DATAWIDTH-1):0] reg_a; + reg have_b; + reg [(`DATAWIDTH-1):0] reg_b; + reg have_op; + reg [(`DATAWIDTH-1):0] reg_op; + + always @(posedge clk) begin + if (!have_a) begin + `onread(in1_r, in1_a) have_a = 1; reg_a = in1_d; end + end + if (!have_b) begin + `onread(in2_r, in2_a) have_b = 1; reg_b = in2_d; end + end + if (!have_op) begin + `onread(inOp_r, inOp_a) have_op = 1; reg_op = inOp_d; end + end + + if (have_a && have_b && have_op) begin + case (reg_op) + 0: out_d = reg_a + reg_b; + 1: out_d = reg_a - reg_b; + default: out_d = 0; + endcase + `onwrite(out_r, out_a) + have_a = 0; + have_b = 0; + have_op = 0; + end + end + end + + + + +== Contributors ========================================================= +Adam Megacz diff --git a/tests/choice/demux-test.fleet b/tests/choice/demux-test.fleet new file mode 100644 index 0000000..553c159 --- /dev/null +++ b/tests/choice/demux-test.fleet @@ -0,0 +1,68 @@ +// expected output +#expect 2 +#expect 1 + +#expect 1 +#expect 2 + +#expect 1 +#expect 1 +#expect 2 + +#expect 2 +#expect 2 +#expect 1 + +#expect 2 +#expect 1 +#expect 1 + +#expect 1 +#expect 2 +#expect 2 + +// ships required in order to run this code +#ship debug : Debug +#ship fifo : Fifo +#ship fifo1 : Fifo +#ship fifo2 : Fifo +#ship choice : Choice + +// alternate values from choice1+choice2 +choice.out1: [*] take, notify fifo1.out; +choice.out2: [*] take, notify fifo2.out; +debug.in: [*] take, deliver, notify fifo.out; + +choice.in1: take; [*] deliver; +1: sendto choice.in1; + +// choice.in2 should never be used (FIXME: test this) + +choice.in: [*] take, deliver; + +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfZero; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfZero; +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonZero; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonZero; +-1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfPositive; +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfPositive; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfPositive; +-1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonPositive; +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonPositive; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonPositive; +-1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNegative; +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNegative; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNegative; +-1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonNegative; +0: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonNegative; +1: sendto fifo.in; fifo.out: wait, take, sendto choice.in.deMuxIfNonNegative; +0: sendto fifo.out; +fifo.in: [*] take, deliver; + +1: sendto fifo1.in; +fifo1.in: take, deliver; +fifo1.out: take; [*] wait, sendto debug.in; + +2: sendto fifo2.in; +fifo2.in: take, deliver; +fifo2.out: take; [*] wait, sendto debug.in; diff --git a/tests/choice/mux-test.fleet b/tests/choice/mux-test.fleet new file mode 100644 index 0000000..835df26 --- /dev/null +++ b/tests/choice/mux-test.fleet @@ -0,0 +1,60 @@ +// expected output +#expect 2 +#expect 1 + +#expect 1 +#expect 2 + +#expect 1 +#expect 1 +#expect 2 + +#expect 2 +#expect 2 +#expect 1 + +#expect 2 +#expect 1 +#expect 1 + +#expect 1 +#expect 2 +#expect 2 + + +// ships required in order to run this code +#ship debug : Debug +#ship choice : Choice + +choice.out1: [*] take, sendto debug.in; + +// this should never emit anything +choice.out2: take; [*] notify debug.in; + +debug.in: [*] take, deliver; + +choice.in1: take; [*] deliver; +choice.in2: take; [*] deliver; +1: sendto choice.in1; +2: sendto choice.in2; + +choice.in: [*] take, deliver; + +0: sendto choice.in.muxIfZero; +1: sendto choice.in.muxIfZero; +0: sendto choice.in.muxIfNonZero; +1: sendto choice.in.muxIfNonZero; +-1: sendto choice.in.muxIfPositive; +0: sendto choice.in.muxIfPositive; +1: sendto choice.in.muxIfPositive; +-1: sendto choice.in.muxIfNonPositive; +0: sendto choice.in.muxIfNonPositive; +1: sendto choice.in.muxIfNonPositive; +-1: sendto choice.in.muxIfNegative; +0: sendto choice.in.muxIfNegative; +1: sendto choice.in.muxIfNegative; +-1: sendto choice.in.muxIfNonNegative; +0: sendto choice.in.muxIfNonNegative; +1: sendto choice.in.muxIfNonNegative; + + diff --git a/tests/choice/swap-test.fleet b/tests/choice/swap-test.fleet new file mode 100644 index 0000000..85eb89d --- /dev/null +++ b/tests/choice/swap-test.fleet @@ -0,0 +1,79 @@ +// expected output +#expect 2 +#expect 1 +#expect 1 +#expect 2 + +#expect 1 +#expect 2 +#expect 2 +#expect 1 + +#expect 1 +#expect 2 +#expect 1 +#expect 2 +#expect 2 +#expect 1 + +#expect 2 +#expect 1 +#expect 2 +#expect 1 +#expect 1 +#expect 2 + +#expect 2 +#expect 1 +#expect 1 +#expect 2 +#expect 1 +#expect 2 + +#expect 1 +#expect 2 +#expect 2 +#expect 1 +#expect 2 +#expect 1 + +// ships required in order to run this code +#ship debug : Debug +#ship choice : Choice + +// alternate values from choice1+choice2 +choice.out1: [*] wait, take, sendto debug.in; +choice.out2: [*] wait, take, sendto debug.in; +debug.in: + [*] nop; + (*) notify choice.out1; + (*) take, deliver; + (*) notify choice.out2; + (*) take, deliver; + kill*; + +choice.in1: take; [*] deliver; +choice.in2: take; [*] deliver; +1: sendto choice.in1; +2: sendto choice.in2; + +choice.in: [*] take, deliver; + +0: sendto choice.in.swapIfZero; +1: sendto choice.in.swapIfZero; +0: sendto choice.in.swapIfNonZero; +1: sendto choice.in.swapIfNonZero; +-1: sendto choice.in.swapIfPositive; +0: sendto choice.in.swapIfPositive; +1: sendto choice.in.swapIfPositive; +-1: sendto choice.in.swapIfNonPositive; +0: sendto choice.in.swapIfNonPositive; +1: sendto choice.in.swapIfNonPositive; +-1: sendto choice.in.swapIfNegative; +0: sendto choice.in.swapIfNegative; +1: sendto choice.in.swapIfNegative; +-1: sendto choice.in.swapIfNonNegative; +0: sendto choice.in.swapIfNonNegative; +1: sendto choice.in.swapIfNonNegative; + +