X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ships%2FAlu2.ship;h=10b3eeb3d162b49e2e56add87b0d1020c9afdb0e;hb=e6db8cb5901129ea6f3f840b769e55292f17fd53;hp=ab4044e010710c899cfbaff1d026e09b480f8276;hpb=c5d2257819614aab486cea7ecf27cd5567756f0a;p=fleet.git diff --git a/ships/Alu2.ship b/ships/Alu2.ship index ab4044e..10b3eeb 100644 --- a/ships/Alu2.ship +++ b/ships/Alu2.ship @@ -4,52 +4,58 @@ ship: Alu2 data in: in1 data in: in2 data in: inOp + constant ADD: 0 + constant SUB: 1 + constant MAX: 2 + constant MIN: 3 data out: out -== Constants ======================================================== -ADD: add the two arguments; treat link as carry -SUB: subtract the two arguments; treat link as carry -MUL: -DIV: -MOD: -REM: -MAX: -MIN: -SORT: output min(in1,in2) followed by max(in1,in2) (FIXME: redundant?) == TeX ============================================================== -This ship is a two-input arithmetic unit. It features several -opcodes, such as {\tt ADD} and {\tt SUB}. In my opinion, it is -niftycool. -FIXME: implement all the link bit stuff +{\tt Alu2} is a ``two-input'' arithmetic logic unit. It includes +logic for performing arithmetic operations on a pair of arguments. +Currently this includes +addition ({\sc add}), +subtraction ({\sc sub}), +maximum ({\sc max}), and +minimum ({\sc min}). -Use carry-in bit to create a selector? Perhaps a waste of an ALU. +\subsection*{Semantics} -Carry-save / carry completion stuff. +When a value is present at each of {\tt in1}, {\tt in2} and {\tt +inOp}, these three values are consumed. Based on the value consumed +at {\tt inOp}, the requested operation is performed on the values +consumed from {\tt in1} and {\tt in2}. The result of this operation +is then made available at {\tt out}. -Flags: zero, negative, overflow, ? +\subsection*{To Do} + +The {\it link bit} and other features of \cite{ies31} are not yet +implemented. + +The carry-in, carry-out, zero-test, negative-test, and overflow-test +flags typically present in a conventional processor ALU are also not +yet implemented. == Fleeterpreter ==================================================== public void service() { if (box_in1.dataReadyForShip() && box_in2.dataReadyForShip() && box_inOp.dataReadyForShip() && - box_out.readyForItemFromShip()) { - int a = box_in1.removeDataForShip(); - int b = box_in2.removeDataForShip(); - int op = box_inOp.removeDataForShip(); - switch(op) { + box_out.readyForDataFromShip()) { + long a = box_in1.removeDataForShip(); + long b = box_in2.removeDataForShip(); + long op = box_inOp.removeDataForShip(); + switch((int)op) { case 0: box_out.addDataFromShip(a+b); // ADD break; case 1: box_out.addDataFromShip(a-b); // SUB break; - case 2: box_out.addDataFromShip(a*b); // MUL + case 2: box_out.addDataFromShip(Math.max(a,b)); // MAX break; - case 3: box_out.addDataFromShip(a/b); // DIV - break; - case 4: box_out.addDataFromShip(a%b); // REM + case 3: box_out.addDataFromShip(Math.min(a,b)); // MIN break; default: box_out.addDataFromShip(0); break; @@ -61,50 +67,56 @@ public void service() { == FPGA ============================================================== - input clk; - `input(in1_r, in1_a, in1_a_, [(`DATAWIDTH-1):0], in1_d) - `input(in2_r, in2_a, in2_a_, [(`DATAWIDTH-1):0], in2_d) - `input(inOp_r, inOp_a, inOp_a_, [(`DATAWIDTH-1):0], inOp_d) - `output(out_r, out_r_, out_a, [(`DATAWIDTH-1):0], out_d_) - - `defreg(out_d_, [(`DATAWIDTH-1):0], out_d) - - reg have_a; - reg [(`DATAWIDTH-1):0] reg_a; - reg have_b; - reg [(`DATAWIDTH-1):0] reg_b; - reg have_op; - reg [(`DATAWIDTH-1):0] reg_op; - always @(posedge clk) begin - if (!have_a) begin - `onread(in1_r, in1_a) have_a = 1; reg_a = in1_d; end - end - if (!have_b) begin - `onread(in2_r, in2_a) have_b = 1; reg_b = in2_d; end - end - if (!have_op) begin - `onread(inOp_r, inOp_a) have_op = 1; reg_op = inOp_d; end - end - - if (have_a && have_b && have_op) begin - case (reg_op) - 0: out_d = reg_a + reg_b; - 1: out_d = reg_a - reg_b; - //2: out_d = reg_a * reg_b; // will not synthesize --AM - //3: out_d = reg_a / reg_b; // will not synthesize --AM - //4: out_d = reg_a % reg_b; // will not synthesize --AM - default: out_d = 0; - endcase - `onwrite(out_r, out_a) - have_a = 0; - have_b = 0; - have_op = 0; + if (!rst) begin + `reset + end else begin + if (out_r && out_a) out_r <= 0; + if (!in1_r && in1_a) in1_a <= 0; + if (!in2_r && in2_a) in2_a <= 0; + if (!inOp_r && inOp_a) inOp_a <= 0; + if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin + out_r <= 1; + in1_a <= 1; + in2_a <= 1; + inOp_a <= 1; + case (inOp_d) + 0: out_d <= in1_d + in2_d; + 1: out_d <= in1_d - in2_d; + 2: out_d <= in1_d > in2_d ? in1_d : in2_d; + 3: out_d <= in1_d > in2_d ? in2_d : in1_d; + default: out_d <= 0; + endcase end end end -endmodule +== Test ============================================================================== +// expected output +#ship debug : Debug +#ship alu : Alu2 + +#expect 17 +#expect 1 +#expect 8 +#expect 9 + +debug.in: [*] take, deliver; +alu.in1: + literal 9; load repeat counter with 4; deliver; + +alu.in2: + literal 8; load repeat counter with 4; deliver; + +alu.inOp: + literal Alu2.inOp[ADD]; deliver; + literal Alu2.inOp[SUB]; deliver; + literal Alu2.inOp[MIN]; deliver; + literal Alu2.inOp[MAX]; deliver; + +alu.in1: [*] take, deliver; +alu.in2: [*] take, deliver; +alu.out: [*] take, sendto debug.in;