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

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [8051/] [oc8051_alu.v] - Blame information for rev 25

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/oms8051mini/                 ////
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
////      - Dinesh Annayya, dinesha@opencores.org                 ////
19
////                                                              ////
20
//////////////////////////////////////////////////////////////////////
21 25 dinesha
////   v0.0 - Dinesh A, 5th Jan 2017
22
////        1. Active edge of reset changed from High to Low
23
//////////////////////////////////////////////////////////////////////
24 2 dinesha
////                                                              ////
25
//// Copyright (C) 2001 Authors and OPENCORES.ORG                 ////
26
////                                                              ////
27
//// This source file may be used and distributed without         ////
28
//// restriction provided that this copyright statement is not    ////
29
//// removed from the file and that any derivative work contains  ////
30
//// the original copyright notice and the associated disclaimer. ////
31
////                                                              ////
32
//// This source file is free software; you can redistribute it   ////
33
//// and/or modify it under the terms of the GNU Lesser General   ////
34
//// Public License as published by the Free Software Foundation; ////
35
//// either version 2.1 of the License, or (at your option) any   ////
36
//// later version.                                               ////
37
////                                                              ////
38
//// This source is distributed in the hope that it will be       ////
39
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
40
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
41
//// PURPOSE. See the GNU Lesser General Public License for more  ////
42
//// details.                                                     ////
43
////                                                              ////
44
//// You should have received a copy of the GNU Lesser General    ////
45
//// Public License along with this source; if not, download it   ////
46
//// from http://www.opencores.org/lgpl.shtml                     ////
47
////                                                              ////
48
//////////////////////////////////////////////////////////////////////
49
//
50
// CVS Revision History
51
//
52
// $Log: not supported by cvs2svn $
53
// Revision 1.18  2003/07/01 18:51:11  simont
54
// x replaced with 0.
55
//
56
// Revision 1.17  2003/06/09 16:51:16  simont
57
// fix bug in DA operation.
58
//
59
// Revision 1.16  2003/06/03 17:15:06  simont
60
// sub_result output added.
61
//
62
// Revision 1.15  2003/05/07 12:31:53  simont
63
// add wire sub_result, conect it to des_acc and des1.
64
//
65
// Revision 1.14  2003/05/05 15:46:36  simont
66
// add aditional alu destination to solve critical path.
67
//
68
// Revision 1.13  2003/04/29 08:35:12  simont
69
// fix bug in substraction.
70
//
71
// Revision 1.12  2003/04/25 17:15:51  simont
72
// change branch instruction execution (reduse needed clock periods).
73
//
74
// Revision 1.11  2003/04/14 14:29:42  simont
75
// fiz bug iv pcs operation.
76
//
77
// Revision 1.10  2003/01/13 14:14:40  simont
78
// replace some modules
79
//
80
// Revision 1.9  2002/09/30 17:33:59  simont
81
// prepared header
82
//
83
//
84
 
85
`include "top_defines.v"
86
 
87
 
88
 
89 25 dinesha
module oc8051_alu (clk, resetn, op_code, src1, src2, src3, srcCy, srcAc, bit_in,
90 2 dinesha
                  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 25 dinesha
input        srcCy, srcAc, bit_in, clk, resetn;
107 2 dinesha
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
 
157 25 dinesha
oc8051_multiply oc8051_mul1(.clk(clk), .resetn(resetn), .enable(enable_mul), .src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
158 2 dinesha
 
159
 
160
 
161
 
162
 
163
 
164
 
165 25 dinesha
oc8051_divide oc8051_div1(.clk(clk), .resetn(resetn), .enable(enable_div), .src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));
166 2 dinesha
 
167
/* Add */
168
assign add1 = {1'b0,src1[3:0]};
169
assign add2 = {1'b0,src2[3:0]};
170
assign add3 = {3'b000,srcCy};
171
assign add4 = add1+add2+add3;
172
 
173
assign add5 = {1'b0,src1[6:4]};
174
assign add6 = {1'b0,src2[6:4]};
175
assign add7 = {1'b0,1'b0,1'b0,add4[4]};
176
assign add8 = add5+add6+add7;
177
 
178
assign add9 = {1'b0,src1[7]};
179
assign adda = {1'b0,src2[7]};
180
assign addb = {1'b0,add8[3]};
181
assign addc = add9+adda+addb;
182
 
183
/* Sub */
184
assign sub1 = {1'b1,src1[3:0]};
185
assign sub2 = {1'b0,src2[3:0]};
186
assign sub3 = {1'b0,1'b0,1'b0,srcCy};
187
assign sub4 = sub1-sub2-sub3;
188
 
189
assign sub5 = {1'b1,src1[6:4]};
190
assign sub6 = {1'b0,src2[6:4]};
191
assign sub7 = {1'b0,1'b0,1'b0, !sub4[4]};
192
assign sub8 = sub5-sub6-sub7;
193
 
194
assign sub9 = {1'b1,src1[7]};
195
assign suba = {1'b0,src2[7]};
196
assign subb = {1'b0,!sub8[3]};
197
assign subc = sub9-suba-subb;
198
 
199
assign sub_result = {subc[0],sub8[2:0],sub4[3:0]};
200
 
201
/* inc */
202
assign inc = {src2, src1} + {15'h0, 1'b1};
203
assign dec = {src2, src1} - {15'h0, 1'b1};
204
 
205
always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3 or mulsrc1
206
      or mulsrc2 or mulOv or divsrc1 or divsrc2 or divOv or addc or add8 or add4
207
      or sub4 or sub8 or subc or da_tmp or inc or dec or sub_result)
208
begin
209
 
210
  case (op_code) /* synopsys full_case parallel_case */
211
//operation add
212
    `OC8051_ALU_ADD: begin
213
      des_acc = {addc[0],add8[2:0],add4[3:0]};
214
      des1 = src1;
215
      des2 = src3+ {7'b0, addc[1]};
216
      desCy = addc[1];
217
      desAc = add4[4];
218
      desOv = addc[1] ^ add8[3];
219
 
220
      enable_mul = 1'b0;
221
      enable_div = 1'b0;
222
    end
223
//operation subtract
224
    `OC8051_ALU_SUB: begin
225
      des_acc = sub_result;
226
//      des1 = sub_result;
227
      des1 = 8'h00;
228
      des2 = 8'h00;
229
      desCy = !subc[1];
230
      desAc = !sub4[4];
231
      desOv = !subc[1] ^ !sub8[3];
232
 
233
      enable_mul = 1'b0;
234
      enable_div = 1'b0;
235
    end
236
//operation multiply
237
    `OC8051_ALU_MUL: begin
238
      des_acc = mulsrc1;
239
      des1 = src1;
240
      des2 = mulsrc2;
241
      desOv = mulOv;
242
      desCy = 1'b0;
243
      desAc = 1'b0;
244
      enable_mul = 1'b1;
245
      enable_div = 1'b0;
246
    end
247
//operation divide
248
    `OC8051_ALU_DIV: begin
249
      des_acc = divsrc1;
250
      des1 = src1;
251
      des2 = divsrc2;
252
      desOv = divOv;
253
      desAc = 1'b0;
254
      desCy = 1'b0;
255
      enable_mul = 1'b0;
256
      enable_div = 1'b1;
257
    end
258
//operation decimal adjustment
259
    `OC8051_ALU_DA: begin
260
 
261
      if (srcAc==1'b1 | src1[3:0]>4'b1001) {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]}+ 5'b00110;
262
      else {da_tmp, des_acc[3:0]} = {1'b0, src1[3:0]};
263
 
264
      if (srcCy | da_tmp | src1[7:4]>4'b1001)
265
        {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]}+ 5'b00110 + {4'b0, da_tmp};
266
      else {da_tmp1, des_acc[7:4]} = {srcCy, src1[7:4]} + {4'b0, da_tmp};
267
 
268
      desCy = da_tmp | da_tmp1;
269
      des1 = src1;
270
      des2 = 8'h00;
271
      desAc = 1'b0;
272
      desOv = 1'b0;
273
      enable_mul = 1'b0;
274
      enable_div = 1'b0;
275
    end
276
//operation not
277
// bit operation not
278
    `OC8051_ALU_NOT: begin
279
      des_acc = ~src1;
280
      des1 = ~src1;
281
      des2 = 8'h00;
282
      desCy = !srcCy;
283
      desAc = 1'b0;
284
      desOv = 1'b0;
285
      enable_mul = 1'b0;
286
      enable_div = 1'b0;
287
    end
288
//operation and
289
//bit operation and
290
    `OC8051_ALU_AND: begin
291
      des_acc = src1 & src2;
292
      des1 = src1 & src2;
293
      des2 = 8'h00;
294
      desCy = srcCy & bit_in;
295
      desAc = 1'b0;
296
      desOv = 1'b0;
297
      enable_mul = 1'b0;
298
      enable_div = 1'b0;
299
    end
300
//operation xor
301
// bit operation xor
302
    `OC8051_ALU_XOR: begin
303
      des_acc = src1 ^ src2;
304
      des1 = src1 ^ src2;
305
      des2 = 8'h00;
306
      desCy = srcCy ^ bit_in;
307
      desAc = 1'b0;
308
      desOv = 1'b0;
309
      enable_mul = 1'b0;
310
      enable_div = 1'b0;
311
    end
312
//operation or
313
// bit operation or
314
    `OC8051_ALU_OR: begin
315
      des_acc = src1 | src2;
316
      des1 = src1 | src2;
317
      des2 = 8'h00;
318
      desCy = srcCy | bit_in;
319
      desAc = 1'b0;
320
      desOv = 1'b0;
321
      enable_mul = 1'b0;
322
      enable_div = 1'b0;
323
    end
324
//operation rotate left
325
// bit operation cy= cy or (not ram)
326
    `OC8051_ALU_RL: begin
327
      des_acc = {src1[6:0], src1[7]};
328
      des1 = src1 ;
329
      des2 = 8'h00;
330
      desCy = srcCy | !bit_in;
331
      desAc = 1'b0;
332
      desOv = 1'b0;
333
      enable_mul = 1'b0;
334
      enable_div = 1'b0;
335
    end
336
//operation rotate left with carry and swap nibbles
337
    `OC8051_ALU_RLC: begin
338
      des_acc = {src1[6:0], srcCy};
339
      des1 = src1 ;
340
      des2 = {src1[3:0], src1[7:4]};
341
      desCy = src1[7];
342
      desAc = 1'b0;
343
      desOv = 1'b0;
344
      enable_mul = 1'b0;
345
      enable_div = 1'b0;
346
    end
347
//operation rotate right
348
    `OC8051_ALU_RR: begin
349
      des_acc = {src1[0], src1[7:1]};
350
      des1 = src1 ;
351
      des2 = 8'h00;
352
      desCy = srcCy & !bit_in;
353
      desAc = 1'b0;
354
      desOv = 1'b0;
355
      enable_mul = 1'b0;
356
      enable_div = 1'b0;
357
    end
358
//operation rotate right with carry
359
    `OC8051_ALU_RRC: begin
360
      des_acc = {srcCy, src1[7:1]};
361
      des1 = src1 ;
362
      des2 = 8'h00;
363
      desCy = src1[0];
364
      desAc = 1'b0;
365
      desOv = 1'b0;
366
      enable_mul = 1'b0;
367
      enable_div = 1'b0;
368
    end
369
//operation pcs Add
370
    `OC8051_ALU_INC: begin
371
      if (srcCy) begin
372
        des_acc = dec[7:0];
373
        des1 = dec[7:0];
374
        des2 = dec[15:8];
375
      end else begin
376
        des_acc = inc[7:0];
377
        des1 = inc[7:0];
378
        des2 = inc[15:8];
379
      end
380
      desCy = 1'b0;
381
      desAc = 1'b0;
382
      desOv = 1'b0;
383
      enable_mul = 1'b0;
384
      enable_div = 1'b0;
385
    end
386
//operation exchange
387
//if carry = 0 exchange low order digit
388
    `OC8051_ALU_XCH: begin
389
      if (srcCy)
390
      begin
391
        des_acc = src2;
392
        des1 = src2;
393
        des2 = src1;
394
      end else begin
395
        des_acc = {src1[7:4],src2[3:0]};
396
        des1 = {src1[7:4],src2[3:0]};
397
        des2 = {src2[7:4],src1[3:0]};
398
      end
399
      desCy = 1'b0;
400
      desAc = 1'b0;
401
      desOv = 1'b0;
402
      enable_mul = 1'b0;
403
      enable_div = 1'b0;
404
    end
405
    `OC8051_ALU_NOP: begin
406
      des_acc = src1;
407
      des1 = src1;
408
      des2 = src2;
409
      desCy = srcCy;
410
      desAc = srcAc;
411
      desOv = 1'b0;
412
      enable_mul = 1'b0;
413
      enable_div = 1'b0;
414
    end
415
  endcase
416
end
417
 
418
endmodule

powered by: WebSVN 2.1.0

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