3 == Ports ===========================================================
21 == TeX ==============================================================
23 {\tt Alu} is a ``two-input'' arithmetic logic unit. It includes
24 logic for performing arithmetic operations on a pair of arguments.
25 Currently this includes
27 subtraction ({\sc sub}),
28 maximum ({\sc max}), and
31 \subsection*{Semantics}
33 When a value is present at each of {\tt in1}, {\tt in2} and {\tt
34 inOp}, these three values are consumed. Based on the value consumed
35 at {\tt inOp}, the requested operation is performed on the values
36 consumed from {\tt in1} and {\tt in2}. The result of this operation
37 is then made available at {\tt out}.
42 IN1 - undefined; drain in1 only
43 IN2 - undefined; drain in2 only
46 MAX - if in1>in2 cflag=0 and drain in1, else cflag=1 and drain in2
47 MIN - if in1>in2 cflag=1 and drain in2, else cflag=0 and drain in1
48 CMP - if in1==in2 cflag=1, else cflag=0
49 DROP1 - consume in1, produce no output
50 DROP2 - consume in2, produce no output
51 MAXMERGE - if (in1<0 && in2<0) consume both, emit either, cflag=undef else act as MAX
56 The {\it link bit} and other features of \cite{ies31} are not yet
59 The carry-in, carry-out, zero-test, negative-test, and overflow-test
60 flags typically present in a conventional processor ALU are also not
63 == Fleeterpreter ====================================================
64 public void service() {
65 if (box_inOp.dataReadyForShip() &&
66 box_in1.dataReadyForShip() &&
67 box_in2.dataReadyForShip() &&
68 box_out.readyForDataFromShip()) {
71 long op = box_inOp.removeDataForShip();
74 a = box_in1.removeDataForShip();
75 box_out.addDataFromShip(a); // IN1
78 b = box_in2.removeDataForShip();
79 box_out.addDataFromShip(b); // IN2
82 a = box_in1.removeDataForShip();
83 b = box_in2.removeDataForShip();
84 box_out.addDataFromShip(a+b); // ADD
87 a = box_in1.removeDataForShip();
88 b = box_in2.removeDataForShip();
89 box_out.addDataFromShip(a-b); // SUB
92 if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) {
93 a = box_in1.removeDataForShip();
94 b = box_in2.removeDataForShip();
95 box_out.addDataFromShip(a, false);
100 a = box_in1.peekDataForShip();
101 b = box_in2.peekDataForShip();
102 box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX
103 if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
106 a = box_in1.peekDataForShip();
107 b = box_in2.peekDataForShip();
108 box_out.addDataFromShip(Math.min(a,b), a>b); // MIN
109 if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
112 a = box_in1.removeDataForShip();
113 b = box_in2.removeDataForShip();
114 box_out.addDataFromShip(0, a==b); // CMP
118 box_in1.removeDataForShip(); // DROP1
121 box_in2.removeDataForShip(); // DROP2
125 throw new RuntimeException("invalid opcode: " + op);
130 == FleetSim ==============================================================
132 == FPGA ==============================================================
134 wire [`WORDWIDTH:0] sum;
136 wire [(`WORDWIDTH-1):0] in2_inverted;
138 wire [(`WORDWIDTH-1):0] res;
143 wire [3:0] inOp_d_trunc;
144 assign inOp_d_trunc = inOp_d[3:0];
146 assign isplus = inOp_d_trunc[2:0]==2;
147 assign cin = isplus ? 0 : 1;
148 assign in2_inverted = isplus ? in2_d : ~in2_d;
149 assign sum = {in1_d,cin} + {in2_inverted,cin};
150 assign res = sum[`WORDWIDTH:1];
151 assign greater = !res[`WORDWIDTH-1];
152 assign both_negative = in1_d[`WORDWIDTH-1] && in2_d[`WORDWIDTH-1];
153 assign eq = in1_d == in2_d;
154 assign cout = sum[`WORDWIDTH];
158 assign out_d_[`WORDWIDTH] =
159 (inOp_d_trunc==0) ? 1'b0 :
160 (inOp_d_trunc==1) ? 1'b0 :
161 (inOp_d_trunc==2) ? cout :
162 (inOp_d_trunc==3) ? cout :
163 (inOp_d_trunc==4) ? ~greater :
164 (inOp_d_trunc==5) ? greater :
165 (inOp_d_trunc==6) ? eq :
166 (inOp_d_trunc==9) ? ~greater :
169 assign out_d_[(`WORDWIDTH-1):0] =
170 (inOp_d_trunc==0) ? (in1_d) :
171 (inOp_d_trunc==1) ? (in2_d) :
172 (inOp_d_trunc==2) ? (res) :
173 (inOp_d_trunc==3) ? (res) :
174 (inOp_d_trunc==4) ? (greater ? in1_d : in2_d) :
175 (inOp_d_trunc==5) ? (greater ? in2_d : in1_d) :
176 (inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq } :
177 (inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
180 always @(posedge clk) begin
186 if (out_draining && `out_empty) begin
189 if (inOp_d_trunc==0) `drain_in1
190 else if (inOp_d_trunc==1) `drain_in2
191 else if (inOp_d_trunc==9 && both_negative) begin `drain_in1 `drain_in2 end
192 else if (inOp_d_trunc==4 && greater) `drain_in1
193 else if (inOp_d_trunc==5 && greater) `drain_in2
194 else if (inOp_d_trunc==9 && greater) `drain_in1
195 else if (inOp_d_trunc==4 && !greater) `drain_in2
196 else if (inOp_d_trunc==5 && !greater) `drain_in1
197 else if (inOp_d_trunc==9 && !greater) `drain_in2
203 if (!out_draining && `out_empty && `in1_full && `in2_full && `inOp_full) begin
210 == Test ==============================================================================
212 // FIXME: need test for ADD carry-out c-flag
228 debug.in: set ilc=*; recv, deliver;
245 collect, send to debug.in;
247 set word= Alu.inOp[ADD]; deliver;
248 set word= Alu.inOp[SUB]; deliver;
249 set word= Alu.inOp[IN1]; deliver;
250 set word= Alu.inOp[IN2]; deliver;
251 set word= Alu.inOp[MIN]; deliver;
252 set word= Alu.inOp[MAX]; deliver;
253 set word= Alu.inOp[CMP]; deliver;
254 set word= Alu.inOp[CMP]; deliver;
257 collect, send to debug.in; // MIN
263 collect, send to debug.in; // MAX
281 == Contributors =========================================================
282 Adam Megacz <megacz@cs.berkeley.edu>