OpenCores
URL https://opencores.org/ocsvn/zet86/zet86/trunk

Subversion Repositories zet86

[/] [zet86/] [trunk/] [cores/] [zet/] [rtl/] [alu.v] - Blame information for rev 55

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 zeus
/*
2
 *  Copyright (c) 2008  Zeus Gomez Marmolejo <zeus@opencores.org>
3
 *
4
 *  This file is part of the Zet processor. This processor is free
5
 *  hardware; you can redistribute it and/or modify it under the terms of
6
 *  the GNU General Public License as published by the Free Software
7
 *  Foundation; either version 3, or (at your option) any later version.
8
 *
9 18 zeus
 *  Zet is distrubuted in the hope that it will be useful, but WITHOUT
10
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12
 *  License for more details.
13 17 zeus
 *
14
 *  You should have received a copy of the GNU General Public License
15 18 zeus
 *  along with Zet; see the file COPYING. If not, see
16 17 zeus
 *  <http://www.gnu.org/licenses/>.
17
 */
18
 
19 2 zeus
`timescale 1ns/10ps
20
 
21 30 zeus
module alu (
22
    input  [31:0] x,
23
    input  [15:0] y,
24
    output [31:0] out,
25
    input  [ 2:0] t,
26
    input  [ 2:0] func,
27
    input  [15:0] iflags,
28
    output [ 8:0] oflags,
29
    input         word_op,
30
    input  [15:0] seg,
31
    input  [15:0] off,
32
    input         clk,
33
    output        div_exc
34
  );
35 2 zeus
 
36
  // Net declarations
37 27 zeus
  wire [15:0] add, log, shi, rot;
38 2 zeus
  wire  [8:0] othflags;
39
  wire [19:0] oth;
40 15 zeus
  wire [31:0] cnv, mul;
41 26 zeus
  wire af_add, af_cnv;
42
  wire cf_cnv, cf_add, cf_mul, cf_log, cf_shi, cf_rot;
43
  wire of_cnv, of_add, of_mul, of_log, of_shi, of_rot;
44 15 zeus
  wire ofi, sfi, zfi, afi, pfi, cfi;
45
  wire ofo, sfo, zfo, afo, pfo, cfo;
46 2 zeus
  wire flags_unchanged;
47 30 zeus
  wire dexc;
48 2 zeus
 
49
  // Module instances
50 26 zeus
  addsub add1 (x[15:0], y, add, func, word_op, cfi, cf_add, af_add, of_add);
51 29 zeus
 
52 26 zeus
  conv cnv2 (
53
    .x      (x[15:0]),
54
    .func   (func),
55
    .out    (cnv),
56 37 zeus
    .iflags ({afi, cfi}),
57 26 zeus
    .oflags ({af_cnv, of_cnv, cf_cnv})
58
  );
59 2 zeus
 
60 29 zeus
  muldiv mul3 (
61
    .x       (x),
62
    .y       (y),
63
    .o       (mul),
64 31 zeus
    .f       (func),
65 29 zeus
    .word_op (word_op),
66
    .cfo     (cf_mul),
67
    .ofo     (of_mul),
68 30 zeus
    .clk     (clk),
69
    .exc     (dexc)
70 29 zeus
  );
71
 
72 28 zeus
  bitlog log4 (x[15:0], y, log, func, cf_log, of_log);
73 32 zeus
  shifts shi5 (x[15:0], y[4:0], shi, func[1:0], word_op, cfi, ofi, cf_shi, of_shi);
74 28 zeus
  rotate rot6 (x[15:0], y[4:0], func[1:0], cfi, word_op, rot, cf_rot, ofi, of_rot);
75 26 zeus
  othop  oth7 (x[15:0], y, seg, off, iflags, func, word_op, oth, othflags);
76
 
77
  mux8_16 m0(t, {8'd0, y[7:0]}, add, cnv[15:0],
78 15 zeus
             mul[15:0], log, shi, rot, oth[15:0], out[15:0]);
79
  mux8_16 m1(t, 16'd0, 16'd0, cnv[31:16], mul[31:16],
80 2 zeus
             16'd0, 16'd0, 16'd0, {12'b0,oth[19:16]}, out[31:16]);
81 29 zeus
  mux8_1  a1(t, 1'b0, cf_add, cf_cnv, cf_mul, cf_log, cf_shi, cf_rot, 1'b0, cfo);
82
  mux8_1  a2(t, 1'b0, af_add, af_cnv, 1'b0, 1'b0, 1'b0, afi, 1'b0, afo);
83
  mux8_1  a3(t, 1'b0, of_add, of_cnv, of_mul, of_log, of_shi, of_rot, 1'b0, ofo);
84 2 zeus
 
85
  // Flags
86
  assign pfo = flags_unchanged ? pfi : ^~ out[7:0];
87 26 zeus
  assign zfo = flags_unchanged ? zfi
88
             : ((word_op && (t!=3'd2)) ? ~|out[15:0] : ~|out[7:0]);
89
  assign sfo = flags_unchanged ? sfi
90
             : ((word_op && (t!=3'd2)) ? out[15] : out[7]);
91 2 zeus
 
92
  assign oflags = (t == 3'd7) ? othflags
93 15 zeus
                 : { ofo, iflags[10:8], sfo, zfo, afo, pfo, cfo };
94 2 zeus
 
95 15 zeus
  assign ofi = iflags[11];
96 2 zeus
  assign sfi = iflags[7];
97
  assign zfi = iflags[6];
98 15 zeus
  assign afi = iflags[4];
99 2 zeus
  assign pfi = iflags[2];
100
  assign cfi = iflags[0];
101
 
102 32 zeus
  assign flags_unchanged = (t == 3'd4 && func == 3'd2
103 27 zeus
                         || t == 3'd5 && y[4:0] == 5'h0
104 32 zeus
                         || t == 3'd6);
105 30 zeus
 
106
  assign div_exc = func[1] && (t==3'd3) && dexc;
107
 
108 2 zeus
endmodule
109
 
110 27 zeus
module addsub (
111
    input  [15:0] x,
112
    input  [15:0] y,
113
    output [15:0] out,
114
    input  [ 2:0] f,
115
    input         word_op,
116
    input         cfi,
117
    output        cfo,
118
    output        afo,
119
    output        ofo
120
  );
121 2 zeus
 
122
  // Net declarations
123 27 zeus
  wire [15:0] op2;
124 2 zeus
 
125 27 zeus
  wire ci;
126
  wire cfoadd;
127
  wire xs, ys, os;
128
 
129 2 zeus
  // Module instances
130 27 zeus
  fulladd16 fa0 ( // We instantiate only one adder
131
    .x  (x),      //  to have less hardware
132
    .y  (op2),
133
    .ci (ci),
134
    .co (cfoadd),
135
    .z  (out),
136
    .s  (f[2])
137
  );
138 2 zeus
 
139
  // Assignments
140 27 zeus
  assign op2 = f[2] ? ~y
141
             : ((f[1:0]==2'b11) ? { 8'b0, y[7:0] } : y);
142
  assign ci  = f[2] & f[1] | f[2] & ~f[0] & ~cfi
143
             | f[2] & f[0] | (f==3'b0) & cfi;
144
  assign afo = f[1] ? (f[2] ? &out[3:0] : ~|out[3:0] )
145
                    : (x[4] ^ y[4] ^ out[4]);
146
  assign cfo = f[1] ? cfi /* inc, dec */
147
             : (word_op ? cfoadd : (x[8]^y[8]^out[8]));
148 15 zeus
 
149 27 zeus
  assign xs  = word_op ? x[15] : x[7];
150
  assign ys  = word_op ? y[15] : y[7];
151
  assign os  = word_op ? out[15] : out[7];
152
  assign ofo = f[2] ? (~xs & ys & os | xs & ~ys & ~os)
153
                    : (~xs & ~ys & os | xs & ys & ~os);
154 2 zeus
endmodule
155
 
156 26 zeus
module conv (
157
    input  [15:0] x,
158
    input  [ 2:0] func,
159
    output [31:0] out,
160 37 zeus
    input  [ 1:0] iflags, // afi, cfi
161 26 zeus
    output [ 2:0] oflags  // afo, ofo, cfo
162
  );
163 25 zeus
 
164 2 zeus
  // Net declarations
165 26 zeus
  wire        afi, cfi;
166
  wire        ofo, afo, cfo;
167
  wire [15:0] aaa, aas;
168
  wire [ 7:0] daa, tmpdaa, das, tmpdas;
169
  wire [15:0] cbw, cwd;
170 2 zeus
 
171 26 zeus
  wire        acond, dcond;
172
  wire        tmpcf;
173
 
174 2 zeus
  // Module instances
175 26 zeus
  mux8_16 m0(func, cbw, aaa, aas, 16'd0,
176
                   cwd, {x[15:8], daa}, {x[15:8], das}, 16'd0, out[15:0]);
177 15 zeus
 
178 2 zeus
  // Assignments
179 26 zeus
  assign aaa = (acond ? (x + 16'h0106) : x) & 16'hff0f;
180
  assign aas = (acond ? (x - 16'h0106) : x) & 16'hff0f;
181 2 zeus
 
182 26 zeus
  assign tmpdaa = acond ? (x[7:0] + 8'h06) : x[7:0];
183
  assign daa    = dcond ? (tmpdaa + 8'h60) : tmpdaa;
184
  assign tmpdas = acond ? (x[7:0] - 8'h06) : x[7:0];
185
  assign das    = dcond ? (tmpdas - 8'h60) : tmpdas;
186 2 zeus
 
187 26 zeus
  assign               cbw   = { { 8{x[ 7]}}, x[7:0] };
188
  assign { out[31:16], cwd } = { {16{x[15]}}, x      };
189 2 zeus
 
190 26 zeus
  assign acond = ((x[7:0] & 8'h0f) > 8'h09) | afi;
191
  assign dcond = (x[7:0] > 8'h99) | cfi;
192 15 zeus
 
193 37 zeus
  assign afi = iflags[1];
194 26 zeus
  assign cfi = iflags[0];
195 2 zeus
 
196 26 zeus
  assign afo = acond;
197
  assign ofo = 1'b0;
198
  assign tmpcf = (x[7:0] < 8'h06) | cfi;
199
  assign cfo = func[2] ? (dcond ? 1'b1 : (acond & tmpcf))
200
             : acond;
201
 
202
  assign oflags = { afo, ofo, cfo };
203 2 zeus
endmodule
204 26 zeus
 
205 2 zeus
 
206 29 zeus
module muldiv (
207
    input  [31:0] x,  // 16 MSb for division
208
    input  [15:0] y,
209
    output [31:0] o,
210 31 zeus
    input  [ 2:0] f,
211 29 zeus
    input         word_op,
212
    output        cfo,
213
    output        ofo,
214 30 zeus
    input         clk,
215
    output        exc
216 29 zeus
  );
217
 
218 2 zeus
  // Net declarations
219 29 zeus
  wire as, bs, cfs, cfu;
220
  wire [16:0] a, b;
221
  wire [33:0] p;
222 30 zeus
  wire div0, over, ovf, mint;
223 2 zeus
 
224 30 zeus
  wire [33:0] zi;
225
  wire [16:0] di;
226
  wire [17:0] q;
227
  wire [17:0] s;
228
 
229 2 zeus
  // Module instantiations
230 29 zeus
  mult signmul17 (
231
    .clk (clk),
232
    .a   (a),
233
    .b   (b),
234
    .p   (p)
235
  );
236 2 zeus
 
237 30 zeus
  div_su #(34) dut (
238
    .clk  (clk),
239
    .ena  (1'b1),
240
    .z    (zi),
241
    .d    (di),
242
    .q    (q),
243
    .s    (s),
244
    .ovf  (ovf),
245
    .div0 (div0)
246
  );
247
 
248 29 zeus
  // Sign ext. for imul
249
  assign as  = f[0] & (word_op ? x[15] : x[7]);
250
  assign bs  = f[0] & (word_op ? y[15] : y[7]);
251
  assign a   = word_op ? { as, x[15:0] }
252
                       : { {9{as}}, x[7:0] };
253
  assign b   = word_op ? { bs, y } : { {9{bs}}, y[7:0] };
254 2 zeus
 
255 31 zeus
  assign zi  = f[2] ? { 26'h0, x[7:0] }
256
               : (word_op ? (f[0] ? { {2{x[31]}}, x }
257 30 zeus
                               : { 2'b0, x })
258
                       : (f[0] ? { {18{x[15]}}, x[15:0] }
259 31 zeus
                               : { 18'b0, x[15:0] }));
260 30 zeus
 
261
  assign di  = word_op ? (f[0] ? { y[15], y } : { 1'b0, y })
262
                       : (f[0] ? { {9{y[7]}}, y[7:0] }
263
                               : { 9'h000, y[7:0] });
264
 
265 31 zeus
  assign o   = f[2] ? { 16'h0, q[7:0], s[7:0] }
266
               : (f[1] ? ( word_op ? {s[15:0], q[15:0]}
267 30 zeus
                                : {16'h0, s[7:0], q[7:0]})
268 31 zeus
                    : p[31:0]);
269 30 zeus
 
270 31 zeus
  assign ofo = f[1] ? 1'b0 : cfo;
271
  assign cfo = f[1] ? 1'b0 : !(f[0] ? cfs : cfu);
272 29 zeus
  assign cfu = word_op ? (o[31:16] == 16'h0)
273
                       : (o[15:8] == 8'h0);
274
  assign cfs = word_op ? (o[31:16] == {16{o[15]}})
275
                       : (o[15:8] == {8{o[7]}});
276 30 zeus
 
277
  // Exceptions
278 31 zeus
  assign over = f[2] ? 1'b0
279
              : (word_op ? (f[0] ? (q[17:16]!={2{q[15]}})
280 30 zeus
                                : (q[17:16]!=2'b0) )
281
                        : (f[0] ? (q[17:8]!={10{q[7]}})
282 31 zeus
                                : (q[17:8]!=10'h000)));
283 30 zeus
  assign mint = f[0] & (word_op ? (x==32'h80000000)
284
                                : (x==16'h8000));
285 31 zeus
  assign exc  = div0 | (!f[2] & ovf) | over | mint;
286 2 zeus
endmodule
287 29 zeus
 
288 2 zeus
module bitlog(x, y, out, func, cfo, ofo);
289
  // IO ports
290
  input  [15:0] x, y;
291
  input  [2:0]  func;
292
  output [15:0] out;
293
  output        cfo, ofo;
294
 
295
  // Net declarations
296 19 zeus
  wire [15:0] and_n, or_n, not_n, xor_n;
297 15 zeus
 
298 2 zeus
  // Module instantiations
299 19 zeus
  mux8_16 m0(func, and_n, or_n, not_n, xor_n, 16'd0, 16'd0, 16'd0, 16'd0, out);
300 2 zeus
 
301
  // Assignments
302
  assign and_n  = x & y;
303
  assign or_n   = x | y;
304
  assign not_n  = ~x;
305
  assign xor_n  = x ^ y;
306
 
307
  assign cfo = 1'b0;
308
  assign ofo = 1'b0;
309
endmodule
310 21 zeus
 
311 17 zeus
//
312
// This module implements the instructions shl/sal, sar, shr
313
//
314 22 zeus
 
315 32 zeus
module shifts(x, y, out, func, word_op, cfi, ofi, cfo, ofo);
316 2 zeus
  // IO ports
317 27 zeus
  input  [15:0] x;
318
  input  [ 4:0] y;
319 2 zeus
  input   [1:0] func;
320
  input         word_op;
321
  output [15:0] out;
322
  output        cfo, ofo;
323 32 zeus
  input         cfi, ofi;
324 2 zeus
 
325
  // Net declarations
326 27 zeus
  wire [15:0] sal, sar, shr, sal16, sar16, shr16;
327
  wire [7:0]  sal8, sar8, shr8;
328
  wire ofo_shl, ofo_sar, ofo_shr;
329 22 zeus
  wire cfo_sal8, cfo_sal16, cfo_sar8, cfo_sar16, cfo_shr8, cfo_shr16;
330
  wire cfo16, cfo8;
331 32 zeus
  wire unchanged;
332 2 zeus
 
333
  // Module instantiations
334 27 zeus
  mux4_16 m0(func, sal, sar, shr, 16'd0, out);
335 2 zeus
 
336
  // Assignments
337 27 zeus
  assign { cfo_sal16, sal16 } = x << y;
338
  assign { sar16, cfo_sar16 } = (y > 5'd16) ? 17'h1ffff
339
    : (({x,1'b0} >> y) | (x[15] ? (17'h1ffff << (17 - y))
340
                                     : 17'h0));
341
  assign { shr16, cfo_shr16 } = ({x,1'b0} >> y);
342 2 zeus
 
343 27 zeus
  assign { cfo_sal8, sal8 } = x[7:0] << y;
344
  assign { sar8, cfo_sar8 } = (y > 5'd8) ? 9'h1ff
345
    : (({x[7:0],1'b0} >> y) | (x[7] ? (9'h1ff << (9 - y))
346
                                         : 9'h0));
347
  assign { shr8, cfo_shr8 } = ({x[7:0],1'b0} >> y);
348 22 zeus
 
349 27 zeus
  assign sal     = word_op ? sal16 : { 8'd0, sal8 };
350
  assign shr     = word_op ? shr16 : { 8'd0, shr8 };
351
  assign sar     = word_op ? sar16 : { {8{sar8[7]}}, sar8 };
352
 
353 32 zeus
  assign ofo = unchanged ? ofi
354
             : (func[1] ? ofo_shr : (func[0] ? ofo_sar : ofo_shl));
355 27 zeus
  assign cfo16 = func[1] ? cfo_shr16
356
               : (func[0] ? cfo_sar16 : cfo_sal16);
357
  assign cfo8  = func[1] ? cfo_shr8
358
               : (func[0] ? cfo_sar8 : cfo_sal8);
359 32 zeus
  assign cfo = unchanged ? cfi : (word_op ? cfo16 : cfo8);
360 2 zeus
  assign ofo_shl = word_op ? (out[15] != cfo) : (out[7] != cfo);
361
  assign ofo_sar = 1'b0;
362
  assign ofo_shr = word_op ? x[15] : x[7];
363 32 zeus
 
364
  assign unchanged = word_op ? (y==5'b0) : (y[3:0]==4'b0);
365 2 zeus
endmodule
366
 
367
module othop (x, y, seg, off, iflags, func, word_op, out, oflags);
368
  // IO ports
369
  input [15:0] x, y, off, seg, iflags;
370
  input [2:0] func;
371
  input word_op;
372
  output [19:0] out;
373
  output [8:0] oflags;
374
 
375
  // Net declarations
376
  wire [15:0] deff, deff2, outf, clcm, setf, intf, strf;
377
  wire [19:0] dcmp, dcmp2;
378
  wire dfi;
379
 
380
  // Module instantiations
381
  mux8_16 m0(func, dcmp[15:0], dcmp2[15:0], deff, outf, clcm, setf,
382
                   intf, strf, out[15:0]);
383
  assign out[19:16] = func ? dcmp2[19:16] : dcmp[19:16];
384
 
385
  // Assignments
386
  assign dcmp  = (seg << 4) + deff;
387
  assign dcmp2 = (seg << 4) + deff2;
388
  assign deff  = x + y + off;
389
  assign deff2 = x + y + off + 16'd2;
390
  assign outf  = y;
391
  assign clcm  = y[2] ? (y[1] ? /* -1: clc */ {iflags[15:1], 1'b0}
392
                         : /* 4: cld */ {iflags[15:11], 1'b0, iflags[9:0]})
393
                     : (y[1] ? /* 2: cli */ {iflags[15:10], 1'b0, iflags[8:0]}
394
                       : /* 0: cmc */ {iflags[15:1], ~iflags[0]});
395
  assign setf  = y[2] ? (y[1] ? /* -1: stc */ {iflags[15:1], 1'b1}
396
                         : /* 4: std */ {iflags[15:11], 1'b1, iflags[9:0]})
397
                     : (y[1] ? /* 2: sti */ {iflags[15:10], 1'b1, iflags[8:0]}
398
                       : /* 0: outf */ iflags);
399
 
400
  assign intf = {iflags[15:10], 2'b0, iflags[7:0]};
401
  assign dfi  = iflags[10];
402
  assign strf = dfi ? (x - y) : (x + y);
403
 
404
  assign oflags = word_op ? { out[11:6], out[4], out[2], out[0] }
405
                           : { iflags[11:8], out[7:6], out[4], out[2], out[0] };
406
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.