added Choice ship
[fleet.git] / ships / Choice.ship
1 ship: Choice
2
3 == Ports ===========================================================
4 data  in:   in1
5 data  in:   in2
6
7 data  in:   in.swapIfZero
8 data  in:   in.swapIfNonZero
9 data  in:   in.swapIfNegative
10 data  in:   in.swapIfPositive
11 data  in:   in.swapIfNonNegative
12 data  in:   in.swapIfNonPositive
13
14 data  in:   in.muxIfZero
15 data  in:   in.muxIfNonZero
16 data  in:   in.muxIfNegative
17 data  in:   in.muxIfPositive
18 data  in:   in.muxIfNonNegative
19 data  in:   in.muxIfNonPositive
20
21 data  in:   in.deMuxIfZero
22 data  in:   in.deMuxIfNonZero
23 data  in:   in.deMuxIfNegative
24 data  in:   in.deMuxIfPositive
25 data  in:   in.deMuxIfNonNegative
26 data  in:   in.deMuxIfNonPositive
27
28 data  out:  out1
29 data  out:  out2
30
31 == Constants ========================================================
32
33 == TeX ==============================================================
34
35 With judicious programming of its BenkoBoxes, this ship can be used to
36 implement nearly all forms of selection and branching.
37
38 When data is available at the in port, it is examined.  Which
39 destination the datum has arrived on determines the *condition* the
40 datum should be tested for and the *action* which should be taken if
41 the condition holds true.
42
43 The latter portion of the name of the destination (IfZero,
44 If(Non)Positive, If(Non)Negative) determines the condition which the
45 datum on the in port is tested for.  The former portion (mux, demux,
46 swap) determines the *action* to be taken if the condition tests true.
47
48   action   condition    effect
49   ------   ---------    -------------------------------
50   swap     false        in1->out1   in2->out2
51   swap     true         in2->out1   in1->out2
52   mux      false        in1->out1
53   mux      true         in2->out1
54   demux    false        in1->out1
55   demux    true         in1->out2
56
57 In each case, the ship will wait for a datum to be available on all
58 input ports (and only those ports) mentioned in the appropriate row of
59 the "effect" column above, and will output them on the corresponding
60 output ports.
61
62
63 == Fleeterpreter ====================================================
64 private Packet selector;
65 public void service() {
66   if (!box_out1.readyForItemFromShip() || !box_out2.readyForItemFromShip()) return;
67   if (selector == null && !box_in.dataReadyForShip()) return;
68   if (selector == null) selector = box_in.removePacketForShip();
69   String port = selector.destination.getDestinationName();
70
71   if (port.startsWith("swap")  && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return;
72   if (port.startsWith("mux")   && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return;
73   if (port.startsWith("deMux") && (!box_in1.dataReadyForShip())) return;
74
75   long val = box_in.removeDataForShip();
76   boolean condition = false;
77   if (port.endsWith("IfZero"))        condition = val==0;
78   if (port.endsWith("IfNonZero"))     condition = val!=0;
79   if (port.endsWith("IfPositive"))    condition = val>0;
80   if (port.endsWith("IfNegative"))    condition = val<0;
81   if (port.endsWith("IfNonPositive")) condition = val<=0;
82   if (port.endsWith("IfNonNegative")) condition = val>=0;
83   if (port.startsWith("swap")) {
84     if (condition) {
85       box_out1.addDataFromShip(box_in2.removeDataForShip());
86       box_out2.addDataFromShip(box_in1.removeDataForShip());
87     } else {
88       box_out1.addDataFromShip(box_in1.removeDataForShip());
89       box_out2.addDataFromShip(box_in2.removeDataForShip());
90     }
91   } else if (port.startsWith("mux")) {
92     box_out1.addDataFromShip(condition ? box_in2.removeDataForShip() : box_in1.removeDataForShip());
93   } else if (port.startsWith("deMux")) {
94     (condition ? box_out2 : box_out1).addDataFromShip(box_in1.removeDataForShip());
95   }
96 }
97
98 == FleetSim ==============================================================
99
100 == FPGA ==============================================================
101
102   // FIXME
103   reg                    have_a;
104   reg [(`DATAWIDTH-1):0] reg_a;
105   reg                    have_b;
106   reg [(`DATAWIDTH-1):0] reg_b;
107   reg                    have_op;
108   reg [(`DATAWIDTH-1):0] reg_op;
109
110   always @(posedge clk) begin
111     if (!have_a) begin
112       `onread(in1_r, in1_a) have_a = 1; reg_a = in1_d; end
113       end
114     if (!have_b) begin
115       `onread(in2_r, in2_a) have_b = 1; reg_b = in2_d; end
116       end
117     if (!have_op) begin
118       `onread(inOp_r, inOp_a) have_op = 1; reg_op = inOp_d; end
119       end
120   
121     if (have_a && have_b && have_op) begin
122       case (reg_op)
123         0: out_d = reg_a + reg_b;
124         1: out_d = reg_a - reg_b;
125         default: out_d = 0;
126       endcase        
127       `onwrite(out_r, out_a)
128         have_a  = 0;
129         have_b  = 0;
130         have_op = 0;
131       end
132     end
133   end
134
135
136
137
138 == Contributors =========================================================
139 Adam Megacz <megacz@cs.berkeley.edu>