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
93 if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) {
94 a = box_in1.removeDataForShip();
95 b = box_in2.removeDataForShip();
96 box_out.addDataFromShip(a, false);
99 // fall through to MAX
101 a = box_in1.peekDataForShip();
102 b = box_in2.peekDataForShip();
103 box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX
104 if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
108 a = box_in1.peekDataForShip();
109 b = box_in2.peekDataForShip();
110 box_out.addDataFromShip(Math.min(a,b), a>b); // MIN
111 if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
114 a = box_in1.removeDataForShip();
115 b = box_in2.removeDataForShip();
116 box_out.addDataFromShip(0, a==b); // CMP
120 box_in1.removeDataForShip(); // DROP1
123 box_in2.removeDataForShip(); // DROP2
127 throw new RuntimeException("invalid opcode: " + op);
132 == FleetSim ==============================================================
134 == FPGA ==============================================================
136 wire [`WORDWIDTH:0] sum;
138 wire [(`WORDWIDTH-1):0] in2_inverted;
140 wire [(`WORDWIDTH-1):0] res;
145 wire [3:0] inOp_d_trunc;
146 assign inOp_d_trunc = inOp_d[3:0];
148 assign isplus = inOp_d_trunc[2:0]==2;
149 assign cin = isplus ? 0 : 1;
150 assign in2_inverted = isplus ? in2_d : ~in2_d;
151 assign sum = {in1_d,cin} + {in2_inverted,cin};
152 assign res = sum[`WORDWIDTH:1];
153 assign greater = !res[`WORDWIDTH-1];
154 assign both_negative = in1_d[`WORDWIDTH-1] && in2_d[`WORDWIDTH-1];
155 assign eq = in1_d == in2_d;
156 assign cout = sum[`WORDWIDTH];
160 assign out_d_[`WORDWIDTH] =
161 (inOp_d_trunc==0) ? 1'b0 :
162 (inOp_d_trunc==1) ? 1'b0 :
163 (inOp_d_trunc==2) ? cout :
164 (inOp_d_trunc==3) ? cout :
165 (inOp_d_trunc==4) ? ~greater :
166 (inOp_d_trunc==5) ? greater :
167 (inOp_d_trunc==6) ? eq :
168 (inOp_d_trunc==9) ? ~greater :
171 assign out_d_[(`WORDWIDTH-1):0] =
172 (inOp_d_trunc==0) ? (in1_d) :
173 (inOp_d_trunc==1) ? (in2_d) :
174 (inOp_d_trunc==2) ? (res) :
175 (inOp_d_trunc==3) ? (res) :
176 (inOp_d_trunc==4) ? (greater ? in1_d : in2_d) :
177 (inOp_d_trunc==5) ? (greater ? in2_d : in1_d) :
178 (inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq } :
179 (inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
182 always @(posedge clk) begin
188 if (out_draining && `out_empty) begin
191 if (inOp_d_trunc==0) `drain_in1
192 else if (inOp_d_trunc==1) `drain_in2
193 else if (inOp_d_trunc==9 && both_negative) begin `drain_in1 `drain_in2 end
194 else if (inOp_d_trunc==4 && greater) `drain_in1
195 else if (inOp_d_trunc==5 && greater) `drain_in2
196 else if (inOp_d_trunc==9 && greater) `drain_in1
197 else if (inOp_d_trunc==4 && !greater) `drain_in2
198 else if (inOp_d_trunc==5 && !greater) `drain_in1
199 else if (inOp_d_trunc==9 && !greater) `drain_in2
205 if (!out_draining && `out_empty && `in1_full && `in2_full && `inOp_full) begin
212 == Test ==============================================================================
214 // FIXME: need test for ADD carry-out c-flag
230 debug.in: set ilc=*; recv, deliver;
247 collect, send to debug.in;
249 set word= Alu.inOp[ADD]; deliver;
250 set word= Alu.inOp[SUB]; deliver;
251 set word= Alu.inOp[IN1]; deliver;
252 set word= Alu.inOp[IN2]; deliver;
253 set word= Alu.inOp[MIN]; deliver;
254 set word= Alu.inOp[MAX]; deliver;
255 set word= Alu.inOp[CMP]; deliver;
256 set word= Alu.inOp[CMP]; deliver;
259 collect, send to debug.in; // MIN
265 collect, send to debug.in; // MAX
283 == Contributors =========================================================
284 Adam Megacz <megacz@cs.berkeley.edu>