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