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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [8051/] [oc8051_alu.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// alu for 8051 Core                                            ////
4
////                                                              ////
5
//// This file is part of the 8051 cores project                  ////
6
//// http://www.opencores.org/cores/8051/                         ////
7
////                                                              ////
8
//// Description                                                  ////
9
//// Implementation of aritmetic unit  according to               ////
10
//// 8051 IP core specification document. Uses divide.v and       ////
11
//// multiply.v                                                   ////
12
////                                                              ////
13
//// To Do:                                                       ////
14
////  pc signed add                                               ////
15
////                                                              ////
16
//// Author(s):                                                   ////
17
//// - Simon Teran, simont@opencores.org                          ////
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2001 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE. See the GNU Lesser General Public License for more  ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
//
46
// CVS Revision History
47
//
48
// $Log: not supported by cvs2svn $
49
// Revision 1.18  2003/07/01 18:51:11  simont
50
// x replaced with 0.
51
//
52
// Revision 1.17  2003/06/09 16:51:16  simont
53
// fix bug in DA operation.
54
//
55
// Revision 1.16  2003/06/03 17:15:06  simont
56
// sub_result output added.
57
//
58
// Revision 1.15  2003/05/07 12:31:53  simont
59
// add wire sub_result, conect it to des_acc and des1.
60
//
61
// Revision 1.14  2003/05/05 15:46:36  simont
62
// add aditional alu destination to solve critical path.
63
//
64
// Revision 1.13  2003/04/29 08:35:12  simont
65
// fix bug in substraction.
66
//
67
// Revision 1.12  2003/04/25 17:15:51  simont
68
// change branch instruction execution (reduse needed clock periods).
69
//
70
// Revision 1.11  2003/04/14 14:29:42  simont
71
// fiz bug iv pcs operation.
72
//
73
// Revision 1.10  2003/01/13 14:14:40  simont
74
// replace some modules
75
//
76
// Revision 1.9  2002/09/30 17:33:59  simont
77
// prepared header
78
//
79
//
80
 
81
// synopsys translate_off
82
`include "oc8051_timescale.v"
83
// synopsys translate_on
84
 
85
`include "oc8051_defines.v"
86
 
87
 
88
 
89
module oc8051_alu (clk, rst, op_code, src1, src2, src3, srcCy, srcAc, bit_in,
90
                  des1, des2, des_acc, desCy, desAc, desOv, sub_result);
91
//
92
// op_code      (in)  operation code [oc8051_decoder.alu_op -r]
93
// src1         (in)  first operand [oc8051_alu_src1_sel.des]
94
// src2         (in)  second operand [oc8051_alu_src2_sel.des]
95
// src3         (in)  third operand [oc8051_alu_src3_sel.des]
96
// srcCy        (in)  carry input [oc8051_cy_select.data_out]
97
// srcAc        (in)  auxiliary carry input [oc8051_psw.data_out[6] ]
98
// bit_in       (in)  bit input, used for logic operatins on bits [oc8051_ram_sel.bit_out]
99
// des1         (out)
100
// des2         (out)
101
// desCy        (out) carry output [oc8051_ram_top.bit_data_in, oc8051_acc.bit_in, oc8051_b_register.bit_in, oc8051_psw.cy_in, oc8051_ports.bit_in]
102
// desAc        (out) auxiliary carry output [oc8051_psw.ac_in]
103
// desOv        (out) Overflow output [oc8051_psw.ov_in]
104
//
105
 
106
input        srcCy, srcAc, bit_in, clk, rst;
107
input  [3:0] op_code;
108
input  [7:0] src1, src2, src3;
109
output       desCy, desAc, desOv;
110
output [7:0] des1, des2, des_acc, sub_result;
111
 
112
reg desCy, desAc, desOv;
113
reg [7:0] des1, des2, des_acc;
114
 
115
 
116
//
117
//add
118
//
119
wire [4:0] add1, add2, add3, add4;
120
wire [3:0] add5, add6, add7, add8;
121
wire [1:0] add9, adda, addb, addc;
122
 
123
//
124
//sub
125
//
126
wire [4:0] sub1, sub2, sub3, sub4;
127
wire [3:0] sub5, sub6, sub7, sub8;
128
wire [1:0] sub9, suba, subb, subc;
129
wire [7:0] sub_result;
130
 
131
//
132
//mul
133
//
134
  wire [7:0] mulsrc1, mulsrc2;
135
  wire mulOv;
136
  reg enable_mul;
137
 
138
//
139
//div
140
//
141
wire [7:0] divsrc1,divsrc2;
142
wire divOv;
143
reg enable_div;
144
 
145
//
146
//da
147
//
148
reg da_tmp, da_tmp1;
149
//reg [8:0] da1;
150
 
151
//
152
// inc
153
//
154
wire [15:0] inc, dec;
155
 
156
oc8051_multiply oc8051_mul1(.clk(clk), .rst(rst), .enable(enable_mul), .src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
157
oc8051_divide oc8051_div1(.clk(clk), .rst(rst), .enable(enable_div), .src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));
158
 
159
/* Add */
160
assign add1 = {1'b0,src1[3:0]};
161
assign add2 = {1'b0,src2[3:0]};
162
assign add3 = {3'b000,srcCy};
163
assign add4 = add1+add2+add3;
164
 
165
assign add5 = {1'b0,src1[6:4]};
166
assign add6 = {1'b0,src2[6:4]};
167
assign add7 = {1'b0,1'b0,1'b0,add4[4]};
168
assign add8 = add5+add6+add7;
169
 
170
assign add9 = {1'b0,src1[7]};
171
assign adda = {1'b0,src2[7]};
172
assign addb = {1'b0,add8[3]};
173
assign addc = add9+adda+addb;
174
 
175
/* Sub */
176
assign sub1 = {1'b1,src1[3:0]};
177
assign sub2 = {1'b0,src2[3:0]};
178
assign sub3 = {1'b0,1'b0,1'b0,srcCy};
179
assign sub4 = sub1-sub2-sub3;
180
 
181
assign sub5 = {1'b1,src1[6:4]};
182
assign sub6 = {1'b0,src2[6:4]};
183
assign sub7 = {1'b0,1'b0,1'b0, !sub4[4]};
184
assign sub8 = sub5-sub6-sub7;
185
 
186
assign sub9 = {1'b1,src1[7]};
187
assign suba = {1'b0,src2[7]};
188
assign subb = {1'b0,!sub8[3]};
189
assign subc = sub9-suba-subb;
190
 
191
assign sub_result = {subc[0],sub8[2:0],sub4[3:0]};
192
 
193
/* inc */
194
assign inc = {src2, src1} + {15'h0, 1'b1};
195
assign dec = {src2, src1} - {15'h0, 1'b1};
196
 
197
always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3 or mulsrc1
198
      or mulsrc2 or mulOv or divsrc1 or divsrc2 or divOv or addc or add8 or add4
199
      or sub4 or sub8 or subc or da_tmp or inc or dec or sub_result)
200
begin
201
 
202
  case (op_code) /* synopsys full_case parallel_case */
203
//operation add
204
    `OC8051_ALU_ADD: begin
205
      des_acc = {addc[0],add8[2:0],add4[3:0]};
206
      des1 = src1;
207
      des2 = src3+ {7'b0, addc[1]};
208
      desCy = addc[1];
209
      desAc = add4[4];
210
      desOv = addc[1] ^ add8[3];
211
 
212
      enable_mul = 1'b0;
213
      enable_div = 1'b0;
214
    end
215
//operation subtract
216
    `OC8051_ALU_SUB: begin
217
      des_acc = sub_result;
218
//      des1 = sub_result;
219
      des1 = 8'h00;
220
      des2 = 8'h00;
221
      desCy = !subc[1];
222
      desAc = !sub4[4];
223
      desOv = !subc[1] ^ !sub8[3];
224
 
225
      enable_mul = 1'b0;
226
      enable_div = 1'b0;
227
    end
228
//operation multiply
229
    `OC8051_ALU_MUL: begin
230
      des_acc = mulsrc1;
231
      des1 = src1;
232
      des2 = mulsrc2;
233
      desOv = mulOv;
234
      desCy = 1'b0;
235
      desAc = 1'b0;
236
      enable_mul = 1'b1;
237
      enable_div = 1'b0;
238
    end
239
//operation divide
240
    `OC8051_ALU_DIV: begin
241
      des_acc = divsrc1;
242
      des1 = src1;
243
      des2 = divsrc2;
244
      desOv = divOv;
245
      desAc = 1'b0;
246
      desCy = 1'b0;
247
      enable_mul = 1'b0;
248
      enable_div = 1'b1;
249
    end
250
//operation decimal adjustment
251
    `OC8051_ALU_DA: begin
252
 
253
      if (srcAc==1'b1 | src1[3:0]>4'b1001) {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]}+ 5'b00110;
254
      else {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]};
255
 
256
      if (srcCy | da_tmp | src1[7:4]>4'b1001)
257
        {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]}+ 5'b00110 + {4'b0, da_tmp};
258
      else {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]} + {4'b0, da_tmp};
259
 
260
      desCy = da_tmp | da_tmp1;
261
      des1 = src1;
262
      des2 = 8'h00;
263
      desAc = 1'b0;
264
      desOv = 1'b0;
265
      enable_mul = 1'b0;
266
      enable_div = 1'b0;
267
    end
268
//operation not
269
// bit operation not
270
    `OC8051_ALU_NOT: begin
271
      des_acc = ~src1;
272
      des1 = ~src1;
273
      des2 = 8'h00;
274
      desCy = !srcCy;
275
      desAc = 1'b0;
276
      desOv = 1'b0;
277
      enable_mul = 1'b0;
278
      enable_div = 1'b0;
279
    end
280
//operation and
281
//bit operation and
282
    `OC8051_ALU_AND: begin
283
      des_acc = src1 & src2;
284
      des1 = src1 & src2;
285
      des2 = 8'h00;
286
      desCy = srcCy & bit_in;
287
      desAc = 1'b0;
288
      desOv = 1'b0;
289
      enable_mul = 1'b0;
290
      enable_div = 1'b0;
291
    end
292
//operation xor
293
// bit operation xor
294
    `OC8051_ALU_XOR: begin
295
      des_acc = src1 ^ src2;
296
      des1 = src1 ^ src2;
297
      des2 = 8'h00;
298
      desCy = srcCy ^ bit_in;
299
      desAc = 1'b0;
300
      desOv = 1'b0;
301
      enable_mul = 1'b0;
302
      enable_div = 1'b0;
303
    end
304
//operation or
305
// bit operation or
306
    `OC8051_ALU_OR: begin
307
      des_acc = src1 | src2;
308
      des1 = src1 | src2;
309
      des2 = 8'h00;
310
      desCy = srcCy | bit_in;
311
      desAc = 1'b0;
312
      desOv = 1'b0;
313
      enable_mul = 1'b0;
314
      enable_div = 1'b0;
315
    end
316
//operation rotate left
317
// bit operation cy= cy or (not ram)
318
    `OC8051_ALU_RL: begin
319
      des_acc = {src1[6:0], src1[7]};
320
      des1 = src1 ;
321
      des2 = 8'h00;
322
      desCy = srcCy | !bit_in;
323
      desAc = 1'b0;
324
      desOv = 1'b0;
325
      enable_mul = 1'b0;
326
      enable_div = 1'b0;
327
    end
328
//operation rotate left with carry and swap nibbles
329
    `OC8051_ALU_RLC: begin
330
      des_acc = {src1[6:0], srcCy};
331
      des1 = src1 ;
332
      des2 = {src1[3:0], src1[7:4]};
333
      desCy = src1[7];
334
      desAc = 1'b0;
335
      desOv = 1'b0;
336
      enable_mul = 1'b0;
337
      enable_div = 1'b0;
338
    end
339
//operation rotate right
340
    `OC8051_ALU_RR: begin
341
      des_acc = {src1[0], src1[7:1]};
342
      des1 = src1 ;
343
      des2 = 8'h00;
344
      desCy = srcCy & !bit_in;
345
      desAc = 1'b0;
346
      desOv = 1'b0;
347
      enable_mul = 1'b0;
348
      enable_div = 1'b0;
349
    end
350
//operation rotate right with carry
351
    `OC8051_ALU_RRC: begin
352
      des_acc = {srcCy, src1[7:1]};
353
      des1 = src1 ;
354
      des2 = 8'h00;
355
      desCy = src1[0];
356
      desAc = 1'b0;
357
      desOv = 1'b0;
358
      enable_mul = 1'b0;
359
      enable_div = 1'b0;
360
    end
361
//operation pcs Add
362
    `OC8051_ALU_INC: begin
363
      if (srcCy) begin
364
        des_acc = dec[7:0];
365
        des1 = dec[7:0];
366
        des2 = dec[15:8];
367
      end else begin
368
        des_acc = inc[7:0];
369
        des1 = inc[7:0];
370
        des2 = inc[15:8];
371
      end
372
      desCy = 1'b0;
373
      desAc = 1'b0;
374
      desOv = 1'b0;
375
      enable_mul = 1'b0;
376
      enable_div = 1'b0;
377
    end
378
//operation exchange
379
//if carry = 0 exchange low order digit
380
    `OC8051_ALU_XCH: begin
381
      if (srcCy)
382
      begin
383
        des_acc = src2;
384
        des1 = src2;
385
        des2 = src1;
386
      end else begin
387
        des_acc = {src1[7:4],src2[3:0]};
388
        des1 = {src1[7:4],src2[3:0]};
389
        des2 = {src2[7:4],src1[3:0]};
390
      end
391
      desCy = 1'b0;
392
      desAc = 1'b0;
393
      desOv = 1'b0;
394
      enable_mul = 1'b0;
395
      enable_div = 1'b0;
396
    end
397
    `OC8051_ALU_NOP: begin
398
      des_acc = src1;
399
      des1 = src1;
400
      des2 = src2;
401
      desCy = srcCy;
402
      desAc = srcAc;
403
      desOv = 1'b0;
404
      enable_mul = 1'b0;
405
      enable_div = 1'b0;
406
    end
407
  endcase
408
end
409
 
410
endmodule

powered by: WebSVN 2.1.0

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