X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ships%2FAlu.ship;h=67effe4388a294bc59d9c3df5265048747f36e1d;hb=fad55ce5384e931f47a61605b5d8fcb04256515b;hp=9cc5e7739b6768e3f7eeb3482e976fa1261e852a;hpb=19888c123ae1dfd675ef02c5c62f7c3f28a490a8;p=fleet.git diff --git a/ships/Alu.ship b/ships/Alu.ship index 9cc5e77..67effe4 100644 --- a/ships/Alu.ship +++ b/ships/Alu.ship @@ -11,6 +11,12 @@ data in: inOp constant MAX: 4 constant MIN: 5 constant CMP: 6 + constant DROP1: 7 + constant DROP2: 8 + constant MAXMERGE: 9 + constant AND: 10 + constant OR: 11 + constant XOR: 12 data out: out @@ -36,13 +42,16 @@ 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 +IN1 - undefined; drain in1 only +IN2 - undefined; drain in2 only +ADD - carry-out +SUB - undefined +MAX - if in1>in2 cflag=0 and drain in1, else cflag=1 and drain in2 +MIN - if in1>in2 cflag=1 and drain in2, else cflag=0 and drain in1 +CMP - if in1==in2 cflag=1, else cflag=0 +DROP1 - consume in1, produce no output +DROP2 - consume in2, produce no output +MAXMERGE - if (in1<0 && in2<0) consume both, emit either, cflag=undef else act as MAX \end{verbatim} \subsection*{To Do} @@ -56,30 +65,84 @@ yet implemented. == Fleeterpreter ==================================================== public void service() { - if (box_in1.dataReadyForShip() && + if (box_inOp.dataReadyForShip() && + box_in1.dataReadyForShip() && box_in2.dataReadyForShip() && - box_inOp.dataReadyForShip() && box_out.readyForDataFromShip()) { - long a = box_in1.removeDataForShip(); - long b = box_in2.removeDataForShip(); + long a; + long b; long op = box_inOp.removeDataForShip(); switch((int)op) { - case 0: box_out.addDataFromShip(a); // IN1 + case 0: + a = box_in1.removeDataForShip(); + box_out.addDataFromShip(a); // IN1 break; - case 1: box_out.addDataFromShip(b); // IN2 + case 1: + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(b); // IN2 break; - case 2: box_out.addDataFromShip(a+b); // ADD + case 2: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a+b); // ADD break; - case 3: box_out.addDataFromShip(a-b); // SUB + case 3: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a-b); // SUB break; - case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX - box_out.flag_c = !(a>b); + + case 9: // MAXMERGE + if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) { + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a, false); + break; + } + // fall through to MAX + case 4: + a = box_in1.peekDataForShip(); + b = box_in2.peekDataForShip(); + box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX + if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip(); + break; + + case 5: + a = box_in1.peekDataForShip(); + b = box_in2.peekDataForShip(); + box_out.addDataFromShip(Math.min(a,b), a>b); // MIN + if (ab; +*/ + case 10: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a & b); // CMP break; - default: box_out.addDataFromShip(0); + case 11: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a | b); // CMP break; + case 12: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a ^ b); // CMP + break; + default: + throw new RuntimeException("invalid opcode: " + op); } } } @@ -88,59 +151,91 @@ public void service() { == FPGA ============================================================== - wire [`DATAWIDTH:0] sum; + wire [`WORDWIDTH:0] sum; wire cin; - wire [(`DATAWIDTH-1):0] in2_inverted; + wire [(`WORDWIDTH-1):0] in2_inverted; - wire [(`DATAWIDTH-1):0] res; + wire [(`WORDWIDTH-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 : + wire [4:0] inOp_d_trunc; + assign inOp_d_trunc = inOp_d[4:0]; + + assign isplus = inOp_d_trunc[4: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[`WORDWIDTH:1]; + assign greater = !res[`WORDWIDTH-1]; + assign both_negative = in1_d[`WORDWIDTH-1] && in2_d[`WORDWIDTH-1]; + assign eq = in1_d == in2_d; + assign cout = sum[`WORDWIDTH]; + + reg out_draining; + + assign out_d_[`WORDWIDTH] = + (inOp_d_trunc==0) ? 1'b0 : + (inOp_d_trunc==1) ? 1'b0 : + (inOp_d_trunc==2) ? cout : + (inOp_d_trunc==3) ? cout : + (inOp_d_trunc==4) ? ~greater : + (inOp_d_trunc==5) ? greater : + (inOp_d_trunc==6) ? eq : + (inOp_d_trunc==9) ? ~greater : 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 } : + assign out_d_[(`WORDWIDTH-1):0] = + (inOp_d_trunc==0) ? (in1_d) : + (inOp_d_trunc==1) ? (in2_d) : + (inOp_d_trunc==2) ? (res) : + (inOp_d_trunc==3) ? (res) : + (inOp_d_trunc==4) ? (greater ? in1_d : in2_d) : + (inOp_d_trunc==5) ? (greater ? in2_d : in1_d) : + (inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq } : + (inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) : + (inOp_d_trunc==10) ? (in1_d & in2_d) : + (inOp_d_trunc==11) ? (in1_d | in2_d) : + (inOp_d_trunc==12) ? (in1_d ^ in2_d) : 0; + wire firing_condition; + assign firing_condition = + (inOp_d_trunc==0) ? `in1_full : + (inOp_d_trunc==1) ? `in2_full : + (inOp_d_trunc==7) ? `in1_full : + (inOp_d_trunc==8) ? `in2_full : + ((`in1_full) && (`in2_full)); + always @(posedge clk) begin - if (!rst) begin + if (rst) begin `reset + out_draining <= 0; end else begin - 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) begin - out_r <= 0; - in1_a <= 1; - in2_a <= 1; - inOp_a <= 1; + `cleanup + if (out_draining && `out_empty) begin + `drain_inOp + out_draining <= 0; + if (inOp_d_trunc==0) `drain_in1 + else if (inOp_d_trunc==1) `drain_in2 + else if (inOp_d_trunc==7) `drain_in1 + else if (inOp_d_trunc==8) `drain_in2 + else if (inOp_d_trunc==9 && both_negative) begin `drain_in1 `drain_in2 end + else if (inOp_d_trunc==4 && greater) `drain_in1 + else if (inOp_d_trunc==5 && greater) `drain_in2 + else if (inOp_d_trunc==9 && greater) `drain_in1 + else if (inOp_d_trunc==4 && !greater) `drain_in2 + else if (inOp_d_trunc==5 && !greater) `drain_in1 + else if (inOp_d_trunc==9 && !greater) `drain_in2 + else begin + `drain_in1 + `drain_in2 + end end - if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin - out_r <= 1; + if (!out_draining && `out_empty && firing_condition && `inOp_full) begin + if (inOp_d_trunc!=7 && inOp_d_trunc!=8) `fill_out + out_draining <= 1; end end end @@ -161,21 +256,19 @@ public void service() { #expect 9 #expect 0 #expect 0 -#expect 0 -#expect 1 #expect 1 debug.in: set ilc=*; recv, deliver; alu.in1: set word= 9; - set ilc=7; + set ilc=5; deliver; set word= 9; deliver; alu.in2: set word= 8; - set ilc=7; + set ilc=5; deliver; set word= 9; deliver; @@ -188,8 +281,6 @@ alu.inOp: set word= Alu.inOp[SUB]; deliver; set word= Alu.inOp[IN1]; deliver; set word= Alu.inOp[IN2]; deliver; - -alu.inOp: set word= Alu.inOp[MIN]; deliver; set word= Alu.inOp[MAX]; deliver; set word= Alu.inOp[CMP]; deliver; @@ -208,13 +299,13 @@ alu.out: [!a] set word= 0; send to debug.in; - collect, send to debug.in; // CMP + collect; // CMP set flags a=c, b=b; [a] set word= 1; [!a] set word= 0; send to debug.in; - collect, send to debug.in; // CMP + collect; // CMP set flags a=c, b=b; [a] set word= 1; [!a] set word= 0;