update ships for overhaul
[fleet.git] / ships / Lut3.ship
1 ship: Lut3
2
3 == Ports ===========================================================
4 data  in:   in1
5 data  in:   in2
6 data  in:   in3
7 data  in:   inLut
8
9 data  out:  out
10
11 == Constants ========================================================
12
13 AND
14 OR
15 XOR
16 NAND
17 NOR
18
19 == TeX ==============================================================
20
21 This ship implements a 3-input {\bf L}ook {\bf U}p {\bf T}able.  The
22 least significant eight bits of the {\tt inLut} value form a truth
23 table with three inputs and one output.
24
25 When values are available at all four inputs they are consumed and a
26 value is produced at {\tt out}.  Each bit of {\tt out} is produced by
27 looking up the corresponding bits of {\tt in1}, {\tt in2}, and {\tt
28 in3} in the {\tt inLut} truth table.
29
30 In particular, the bits {\tt in1}, {\tt in2}, {\tt in3} are
31 concatenated to form a three-bit number, with {\tt in3} as the {\it
32 most significant} bit and {\tt in1} as the {\it least significant
33 bit}.  This three-bit number, ranging from 0 to 7 (decimal), is used
34 as a bit index into {\tt inLut}'s value (whose least significant bit
35 is considered ``bit zero'').
36
37 The ship-specific constants refer to commonly-used truth tables for
38 {\it two-input} functions; these constant truth tables are invariant
39 under input {\tt in3}.
40
41 == Fleeterpreter ====================================================
42   public void service() {
43       if (box_in1.dataReadyForShip() &&
44           box_in2.dataReadyForShip() &&
45           box_in3.dataReadyForShip() &&
46           box_inLut.dataReadyForShip()) {
47           long a      = box_in1.removeDataForShip();
48           long b      = box_in2.removeDataForShip();
49           long c      = box_in3.removeDataForShip();
50           long lut    = box_inLut.removeDataForShip();
51           long ret = 0;
52           ret |= ((lut & (1<<0))==0) ? 0 : (~a) & (~b) & (~c);
53           ret |= ((lut & (1<<1))==0) ? 0 : ( a) & (~b) & (~c);
54           ret |= ((lut & (1<<2))==0) ? 0 : (~a) & ( b) & (~c);
55           ret |= ((lut & (1<<3))==0) ? 0 : ( a) & ( b) & (~c);
56           ret |= ((lut & (1<<4))==0) ? 0 : (~a) & (~b) & ( c);
57           ret |= ((lut & (1<<5))==0) ? 0 : ( a) & (~b) & ( c);
58           ret |= ((lut & (1<<6))==0) ? 0 : (~a) & ( b) & ( c);
59           ret |= ((lut & (1<<7))==0) ? 0 : ( a) & ( b) & ( c);
60           box_out.addDataFromShip(ret);
61       }
62   }
63
64 == FleetSim ==============================================================
65 == FPGA ==============================================================
66
67   reg                    have_in1;
68   reg [(`DATAWIDTH-1):0] reg_in1;
69   reg                    have_in2;
70   reg [(`DATAWIDTH-1):0] reg_in2;
71   reg                    have_in3;
72   reg [(`DATAWIDTH-1):0] reg_in3;
73   reg                    have_inLut;
74   reg [(`DATAWIDTH-1):0] reg_inLut;
75
76   wire [(`DATAWIDTH-1):0] out;
77   genvar i;
78   generate
79     for(i=0; i<`DATAWIDTH; i=i+1) begin : OUT
80       assign out[i] = inLut_d[{in3_d[i], in2_d[i], in1_d[i]}];
81     end
82   endgenerate
83
84   always @(posedge clk) begin
85     if (!have_in1) begin
86       `onread(in1_r, in1_a) have_in1 = 1; reg_in1 = in1_d; end
87       end
88     if (!have_in2) begin
89       `onread(in2_r, in2_a) have_in2 = 1; reg_in2 = in2_d; end
90       end
91     if (!have_in3) begin
92       `onread(in3_r, in3_a) have_in3 = 1; reg_in3 = in3_d; end
93       end
94     if (!have_inLut) begin
95       `onread(inLut_r, inLut_a) have_inLut = 1; reg_inLut = inLut_d; end
96       end
97   
98     if (have_in1 && have_in2 && have_in3 && have_inLut) begin
99       out_d = out;
100       `onwrite(out_r, out_a)
101         have_in1  = 0;
102         have_in2  = 0;
103         have_in3  = 0;
104         have_inLut = 0;
105       end
106     end
107   end
108
109
110 == Contributors =========================================================
111 Adam Megacz <megacz@cs.berkeley.edu>