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 a = box_in1.peekDataForShip();
93 b = box_in2.peekDataForShip();
94 box_out.addDataFromShip(Math.max(a,b)); // MAX
95 box_out.flag_c = !(a>b);
96 if (a<b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
99 a = box_in1.peekDataForShip();
100 b = box_in2.peekDataForShip();
101 box_out.addDataFromShip(Math.min(a,b)); // MIN
102 box_out.flag_c = a>b;
103 if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip();
106 a = box_in1.removeDataForShip();
107 b = box_in2.removeDataForShip();
108 box_out.addDataFromShip(0); // CMP
109 box_out.flag_c = a==b;
112 a = box_in1.removeDataForShip();
113 b = box_in2.removeDataForShip();
114 box_out.addDataFromShip(0);
120 == FleetSim ==============================================================
122 == FPGA ==============================================================
124 wire [`WORDWIDTH:0] sum;
126 wire [(`WORDWIDTH-1):0] in2_inverted;
128 wire [(`WORDWIDTH-1):0] res;
133 wire [3:0] inOp_d_trunc;
134 assign inOp_d_trunc = inOp_d[3:0];
136 assign isplus = inOp_d_trunc[2:0]==2;
137 assign cin = isplus ? 0 : 1;
138 assign in2_inverted = isplus ? in2_d : ~in2_d;
139 assign sum = {in1_d,cin} + {in2_inverted,cin};
140 assign res = sum[`WORDWIDTH:1];
141 assign greater = !res[`WORDWIDTH-1];
142 assign both_negative = in1_d[`WORDWIDTH-1] && in2_d[`WORDWIDTH-1];
143 assign eq = in1_d == in2_d;
144 assign cout = sum[`WORDWIDTH];
148 assign out_d_[`WORDWIDTH] =
149 (inOp_d_trunc==0) ? 1'b0 :
150 (inOp_d_trunc==1) ? 1'b0 :
151 (inOp_d_trunc==2) ? cout :
152 (inOp_d_trunc==3) ? cout :
153 (inOp_d_trunc==4) ? ~greater :
154 (inOp_d_trunc==5) ? greater :
155 (inOp_d_trunc==6) ? eq :
156 (inOp_d_trunc==9) ? ~greater :
159 assign out_d_[(`WORDWIDTH-1):0] =
160 (inOp_d_trunc==0) ? (in1_d) :
161 (inOp_d_trunc==1) ? (in2_d) :
162 (inOp_d_trunc==2) ? (res) :
163 (inOp_d_trunc==3) ? (res) :
164 (inOp_d_trunc==4) ? (greater ? in1_d : in2_d) :
165 (inOp_d_trunc==5) ? (greater ? in2_d : in1_d) :
166 (inOp_d_trunc==6) ? {{ (`WORDWIDTH-1) {1'b0 }}, eq } :
167 (inOp_d_trunc==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) :
170 always @(posedge clk) begin
177 if (out_draining && `out_empty) begin
180 if (inOp_d_trunc==0) `drain_in1
181 else if (inOp_d_trunc==1) `drain_in2
182 else if (inOp_d_trunc==9 && both_negative) begin `drain_in1 `drain_in2 end
183 else if (inOp_d_trunc==4 && greater) `drain_in1
184 else if (inOp_d_trunc==5 && greater) `drain_in2
185 else if (inOp_d_trunc==9 && greater) `drain_in1
186 else if (inOp_d_trunc==4 && !greater) `drain_in2
187 else if (inOp_d_trunc==5 && !greater) `drain_in1
188 else if (inOp_d_trunc==9 && !greater) `drain_in2
194 if (!out_draining && `out_empty && `in1_full && `in2_full && `inOp_full) begin
201 == Test ==============================================================================
203 // FIXME: need test for ADD carry-out c-flag
219 debug.in: set ilc=*; recv, deliver;
236 collect, send to debug.in;
238 set word= Alu.inOp[ADD]; deliver;
239 set word= Alu.inOp[SUB]; deliver;
240 set word= Alu.inOp[IN1]; deliver;
241 set word= Alu.inOp[IN2]; deliver;
242 set word= Alu.inOp[MIN]; deliver;
243 set word= Alu.inOp[MAX]; deliver;
244 set word= Alu.inOp[CMP]; deliver;
245 set word= Alu.inOp[CMP]; deliver;
248 collect, send to debug.in; // MIN
254 collect, send to debug.in; // MAX
272 == Contributors =========================================================
273 Adam Megacz <megacz@cs.berkeley.edu>