+++ /dev/null
-ship: Lut
-
-== Ports ===========================================================
-data in: in1
-data in: in2
-data in: in3
-data in: inLut
-
-data out: out
-
-== Constants ========================================================
-
-== TeX ==============================================================
-
-This ship implements a {\bf L}ook {\bf U}p {\bf T}able. The least
-significant eight bits of the {\tt inLut} value form a truth table
-with two inputs and one output (FIXME: specify the layout).
-
-When values are available at all three inputs they are consumed and a
-value is produced at {\tt out}. Each bit of {\tt out} is produced by
-looking up the corresponding bits of {\tt in1} and {\tt in2} in the
-{\tt inLut} truth table.
-
-== Fleeterpreter ====================================================
- public void service() {
- if (box_in1.dataReadyForShip() &&
- box_in2.dataReadyForShip() &&
- box_inLut.dataReadyForShip()) {
- int a = box_in1.removeDataForShip();
- int b = box_in2.removeDataForShip();
- int lut = box_inLut.removeDataForShip();
- int ret = 0;
- if ((lut & 1) != 0) ret |= (~a) & (~b);
- if ((lut & 2) != 0) ret |= (a) & (~b);
- if ((lut & 4) != 0) ret |= (~a) & (b);
- if ((lut & 8) != 0) ret |= a & b;
- box_out.addDataFromShip(ret);
- }
- }
-
-== FleetSim ==============================================================
-== FPGA ==============================================================
-// not implemented FIXME
-
-== Contributors =========================================================
-Adam Megacz <megacz@cs.berkeley.edu>
--- /dev/null
+ship: Lut3
+
+== Ports ===========================================================
+data in: in1
+data in: in2
+data in: in3
+data in: inLut
+
+data out: out
+
+== Constants ========================================================
+
+AND
+OR
+XOR
+NAND
+NOR
+
+== TeX ==============================================================
+
+This ship implements a 3-input {\bf L}ook {\bf U}p {\bf T}able. The
+least significant eight bits of the {\tt inLut} value form a truth
+table with three inputs and one output.
+
+When values are available at all four inputs they are consumed and a
+value is produced at {\tt out}. Each bit of {\tt out} is produced by
+looking up the corresponding bits of {\tt in1}, {\tt in2}, and {\tt
+in3} in the {\tt inLut} truth table.
+
+In particular, the bits {\tt in1}, {\tt in2}, {\tt in3} are
+concatenated to form a three-bit number, with {\tt in3} as the {\it
+most significant} bit and {\tt in1} as the {\it least significant
+bit}. This three-bit number, ranging from 0 to 7 (decimal), is used
+as a bit index into {\tt inLut}'s value (whose least significant bit
+is considered ``bit zero'').
+
+The ship-specific constants refer to commonly-used truth tables for
+{\it two-input} functions; these constant truth tables are invariant
+under input {\tt in3}.
+
+== Fleeterpreter ====================================================
+ public void service() {
+ if (box_in1.dataReadyForShip() &&
+ box_in2.dataReadyForShip() &&
+ box_in3.dataReadyForShip() &&
+ box_inLut.dataReadyForShip()) {
+ int a = box_in1.removeDataForShip();
+ int b = box_in2.removeDataForShip();
+ int c = box_in3.removeDataForShip();
+ int lut = box_inLut.removeDataForShip();
+ int ret = 0;
+ ret |= ((lut & (1<<0))==0) ? 0 : (~a) & (~b) & (~c);
+ ret |= ((lut & (1<<1))==0) ? 0 : ( a) & (~b) & (~c);
+ ret |= ((lut & (1<<2))==0) ? 0 : (~a) & ( b) & (~c);
+ ret |= ((lut & (1<<3))==0) ? 0 : ( a) & ( b) & (~c);
+ ret |= ((lut & (1<<4))==0) ? 0 : (~a) & (~b) & ( c);
+ ret |= ((lut & (1<<5))==0) ? 0 : ( a) & (~b) & ( c);
+ ret |= ((lut & (1<<6))==0) ? 0 : (~a) & ( b) & ( c);
+ ret |= ((lut & (1<<7))==0) ? 0 : ( a) & ( b) & ( c);
+ box_out.addDataFromShip(ret);
+ }
+ }
+
+== FleetSim ==============================================================
+== FPGA ==============================================================
+
+ reg have_in1;
+ reg [(`DATAWIDTH-1):0] reg_in1;
+ reg have_in2;
+ reg [(`DATAWIDTH-1):0] reg_in2;
+ reg have_in3;
+ reg [(`DATAWIDTH-1):0] reg_in3;
+ reg have_inLut;
+ reg [(`DATAWIDTH-1):0] reg_inLut;
+
+ wire [(`DATAWIDTH-1):0] out;
+ genvar i;
+ generate
+ for(i=0; i<`DATAWIDTH; i=i+1) begin : OUT
+ assign out[i] = inLut_d[{in3_d[i], in2_d[i], in1_d[i]}];
+ end
+ endgenerate
+
+ always @(posedge clk) begin
+ if (!have_in1) begin
+ `onread(in1_r, in1_a) have_in1 = 1; reg_in1 = in1_d; end
+ end
+ if (!have_in2) begin
+ `onread(in2_r, in2_a) have_in2 = 1; reg_in2 = in2_d; end
+ end
+ if (!have_in3) begin
+ `onread(in3_r, in3_a) have_in3 = 1; reg_in3 = in3_d; end
+ end
+ if (!have_inLut) begin
+ `onread(inLut_r, inLut_a) have_inLut = 1; reg_inLut = inLut_d; end
+ end
+
+ if (have_in1 && have_in2 && have_in3 && have_inLut) begin
+ out_d = out;
+ `onwrite(out_r, out_a)
+ have_in1 = 0;
+ have_in2 = 0;
+ have_in3 = 0;
+ have_inLut = 0;
+ end
+ end
+ end
+
+
+== Contributors =========================================================
+Adam Megacz <megacz@cs.berkeley.edu>