From: adam Date: Thu, 21 Aug 2008 10:33:34 +0000 (+0100) Subject: overhaul Alu2 fpga code, add new opcodes X-Git-Url: http://git.megacz.com/?p=fleet.git;a=commitdiff_plain;h=939a24ac79180eab3e8af14db8733d6f4e42ead2 overhaul Alu2 fpga code, add new opcodes --- diff --git a/ships/Alu2.ship b/ships/Alu2.ship index 10b3eeb..7f270b6 100644 --- a/ships/Alu2.ship +++ b/ships/Alu2.ship @@ -4,10 +4,13 @@ ship: Alu2 data in: in1 data in: in2 data in: inOp - constant ADD: 0 - constant SUB: 1 - constant MAX: 2 - constant MIN: 3 + constant IN1: 0 + constant IN2: 1 + constant ADD: 2 + constant SUB: 3 + constant MAX: 4 + constant MIN: 5 + constant CMP: 6 data out: out @@ -30,6 +33,18 @@ 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}. +\subsection*{C-Flag} + +\begin{verbatim} +IN1 - undefined +IN2 - undefined +ADD - carry-out +SUB - undefined +MAX - 0 if in1>in2, else 1 +MIN - 1 if in1>in2, else 0 +CMP - 0 if in1!=in2, else 1 +\end{verbatim} + \subsection*{To Do} The {\it link bit} and other features of \cite{ies31} are not yet @@ -49,13 +64,19 @@ public void service() { long b = box_in2.removeDataForShip(); long op = box_inOp.removeDataForShip(); switch((int)op) { - case 0: box_out.addDataFromShip(a+b); // ADD + case 0: box_out.addDataFromShip(a); // IN1 + break; + case 1: box_out.addDataFromShip(b); // IN2 break; - case 1: box_out.addDataFromShip(a-b); // SUB + case 2: box_out.addDataFromShip(a+b); // ADD break; - case 2: box_out.addDataFromShip(Math.max(a,b)); // MAX + case 3: box_out.addDataFromShip(a-b); // SUB break; - case 3: box_out.addDataFromShip(Math.min(a,b)); // MIN + case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX + box_out.flag_c = !(a>b); + break; + case 5: box_out.addDataFromShip(Math.min(a,b)); // MIN + box_out.flag_c = a>b; break; default: box_out.addDataFromShip(0); break; @@ -67,58 +88,137 @@ public void service() { == FPGA ============================================================== + wire [`DATAWIDTH:0] sum; + wire cin; + wire [(`DATAWIDTH-1):0] in2_inverted; + + wire [(`DATAWIDTH-1):0] res; + wire isplus; + wire eq; + wire cout; + + assign isplus = inOp_d[2:0]==2; + assign cin = isplus ? 0 : 1; + assign in2_inverted = isplus ? in2_d : ~in2_d; + assign sum = {in1_d,cin} + {in2_inverted,cin}; + assign res = sum[`DATAWIDTH:1]; + assign greater = !res[`DATAWIDTH-1]; + assign eq = in1_d == in2_d; + assign cout = sum[`DATAWIDTH]; + + assign out_d_[`DATAWIDTH] = + (inOp_d==0) ? 1'b0 : + (inOp_d==1) ? 1'b0 : + (inOp_d==2) ? cout : + (inOp_d==3) ? 1'b0 : + (inOp_d==4) ? ~greater : + (inOp_d==5) ? greater : + (inOp_d==6) ? eq : + 0; + + assign out_d_[(`DATAWIDTH-1):0] = + (inOp_d==0) ? (in1_d) : + (inOp_d==1) ? (in2_d) : + (inOp_d==2) ? (res) : + (inOp_d==3) ? (res) : + (inOp_d==4) ? (greater ? in1_d : in2_d) : + (inOp_d==5) ? (greater ? in2_d : in1_d) : + (inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq } : + 0; + always @(posedge clk) begin 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; + if (out_r && out_a) begin + out_r <= 0; 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 + if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin + out_r <= 1; end end end == Test ============================================================================== -// expected output + +// FIXME: need test for ADD carry-out c-flag + #ship debug : Debug #ship alu : Alu2 #expect 17 #expect 1 +#expect 9 +#expect 8 #expect 8 +#expect 1 #expect 9 +#expect 0 +#expect 0 +#expect 0 +#expect 1 +#expect 1 debug.in: [*] take, deliver; alu.in1: - literal 9; load repeat counter with 4; deliver; + literal 9; + load repeat counter with 7; + deliver; + literal 9; + deliver; alu.in2: - literal 8; load repeat counter with 4; deliver; - + literal 8; + load repeat counter with 7; + deliver; + literal 9; + deliver; + +alu.out: + load repeat counter with 4; + take, sendto debug.in; alu.inOp: literal Alu2.inOp[ADD]; deliver; literal Alu2.inOp[SUB]; deliver; + literal Alu2.inOp[IN1]; deliver; + literal Alu2.inOp[IN2]; deliver; + +alu.inOp: literal Alu2.inOp[MIN]; deliver; literal Alu2.inOp[MAX]; deliver; - -alu.in1: [*] take, deliver; -alu.in2: [*] take, deliver; -alu.out: [*] take, sendto debug.in; - - + literal Alu2.inOp[CMP]; deliver; + literal Alu2.inOp[CMP]; deliver; + +alu.out: + take, sendto debug.in; // MIN + setflags a=c, b=b; + [a] literal 1; + [!a] literal 0; + sendto debug.in; + + take, sendto debug.in; // MAX + setflags a=c, b=b; + [a] literal 1; + [!a] literal 0; + sendto debug.in; + + take, sendto debug.in; // CMP + setflags a=c, b=b; + [a] literal 1; + [!a] literal 0; + sendto debug.in; + + take, sendto debug.in; // CMP + setflags a=c, b=b; + [a] literal 1; + [!a] literal 0; + sendto debug.in; == Contributors ========================================================= Adam Megacz