add support for shortcuts in FleetDoc
[fleet.git] / ships / Alu3.ship
1 ship: Alu3
2
3 == Ports ===========================================================
4 data  in:   in1
5 data  in:   in2
6 data  in:   in3
7
8 data  out:  out1
9   shortcut to: in1
10 data  out:  out2
11   shortcut to: in2
12 data  out:  out3
13   shortcut to: in3
14
15 == Constants ========================================================
16 == TeX ==============================================================
17
18 This ship performs addition of three inputs, producing two output
19 values in carry-save form.  To complete the addition, send the two
20 output values to an Alu2 with opcode ADD.  For summing a set of four
21 or more numbers, Alu3 followed by Alu2 is often faster than repeated
22 use of Alu2.
23
24 == Fleeterpreter ====================================================
25 public void service() {
26   if (box_in1.dataReadyForShip() &&
27       box_in2.dataReadyForShip() &&
28       box_in3.dataReadyForShip() &&
29       box_out1.readyForDataFromShip() &&
30       box_out2.readyForDataFromShip()) {
31       long v1     = box_in1.removeDataForShip();
32       long v2     = box_in2.removeDataForShip();
33       long v3     = box_in3.removeDataForShip();
34       long o1     = ((v1 & v2) | (v2 & v3) | (v1 & v3)) << 1;
35       long o2     = v1 ^ v2 ^ v3;
36       box_out1.addDataFromShip(o1);
37       box_out2.addDataFromShip(o2);
38   }
39 }
40
41 == FleetSim ==============================================================
42
43 == FPGA ==============================================================
44
45   reg                    have_a;
46   reg [(`DATAWIDTH-1):0] a;
47   reg                    have_b;
48   reg [(`DATAWIDTH-1):0] b;
49   reg                    have_c;
50   reg [(`DATAWIDTH-1):0] c;
51   reg                    have_out1;
52   reg                    have_out2;
53
54   always @(posedge clk) begin
55     if (have_out1) begin
56       `onwrite(out1_r, out1_a) have_out1 <= 0; end
57
58     end else if (have_out2) begin
59       `onwrite(out2_r, out2_a) have_out2 <= 0; end
60
61     end else if (!have_out1 && !have_out2) begin
62       if (!have_a) begin
63         `onread(in1_r, in1_a) have_a <= 1; a <= in1_d; end
64         end
65       if (!have_b) begin
66         `onread(in2_r, in2_a) have_b <= 1; b <= in2_d; end
67         end
68       if (!have_c) begin
69         `onread(in3_r, in3_a) have_c <= 1; c <= in3_d; end
70         end
71   
72       if (have_a && have_b && have_c) begin
73         out1_d    <= { { ((a & b) | (b & c) | (a & c)) } , 1'b0 };
74         out2_d    <= a ^ b ^ c;
75         have_a    <= 0;
76         have_b    <= 0;
77         have_c    <= 0;
78         have_out1 <= 1;
79         have_out2 <= 1;
80       end
81     end
82   end
83
84
85
86
87 == Contributors =========================================================
88 Adam Megacz <megacz@cs.berkeley.edu>