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

Subversion Repositories 8051

[/] [8051/] [trunk/] [rtl/] [verilog/] [oc8051_alu.v] - Blame information for rev 133

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

Line No. Rev Author Line
1 82 simont
//////////////////////////////////////////////////////////////////////
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 133 simont
// Revision 1.12  2003/04/25 17:15:51  simont
50
// change branch instruction execution (reduse needed clock periods).
51
//
52 132 simont
// Revision 1.11  2003/04/14 14:29:42  simont
53
// fiz bug iv pcs operation.
54
//
55 123 simont
// Revision 1.10  2003/01/13 14:14:40  simont
56
// replace some modules
57
//
58 82 simont
// Revision 1.9  2002/09/30 17:33:59  simont
59
// prepared header
60
//
61
//
62
 
63
// synopsys translate_off
64
`include "oc8051_timescale.v"
65
// synopsys translate_on
66
 
67
`include "oc8051_defines.v"
68
 
69
 
70
 
71 132 simont
module oc8051_alu (clk, rst, op_code, src1, src2, src3, srcCy, srcAc, bit_in, des1, des2, desCy,
72 82 simont
                   desAc, desOv);
73
//
74
// op_code      (in)  operation code [oc8051_decoder.alu_op -r]
75
// src1         (in)  first operand [oc8051_alu_src1_sel.des]
76
// src2         (in)  second operand [oc8051_alu_src2_sel.des]
77
// src3         (in)  third operand [oc8051_alu_src3_sel.des]
78
// srcCy        (in)  carry input [oc8051_cy_select.data_out]
79
// srcAc        (in)  auxiliary carry input [oc8051_psw.data_out[6] ]
80
// bit_in       (in)  bit input, used for logic operatins on bits [oc8051_ram_sel.bit_out]
81
// des1         (out)
82
// des2         (out)
83
// 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]
84
// desAc        (out) auxiliary carry output [oc8051_psw.ac_in]
85
// desOv        (out) Overflow output [oc8051_psw.ov_in]
86
//
87
 
88 132 simont
input srcCy, srcAc, bit_in, clk, rst;
89 82 simont
input [3:0] op_code;
90
input [7:0] src1, src2, src3;
91
output desCy, desAc, desOv;
92
output [7:0] des1, des2;
93
 
94
reg desCy, desAc, desOv;
95
reg [7:0] des1, des2;
96
 
97
 
98
//
99
//add
100
//
101
wire [4:0] add1, add2, add3, add4;
102
wire [3:0] add5, add6, add7, add8;
103
wire [1:0] add9, adda, addb, addc;
104
 
105
//
106
//sub
107
//
108
wire [4:0] sub1, sub2, sub3, sub4;
109
wire [3:0] sub5, sub6, sub7, sub8;
110
wire [1:0] sub9, suba, subb, subc;
111
 
112
//
113
//mul
114
//
115
  wire [7:0] mulsrc1, mulsrc2;
116
  wire mulOv;
117
  reg enable_mul;
118
 
119
//
120
//div
121
//
122
wire [7:0] divsrc1,divsrc2;
123
wire divOv;
124
reg enable_div;
125
 
126
//
127
//da
128
//
129
reg da_tmp;
130
//reg [8:0] da1;
131
 
132
oc8051_multiply oc8051_mul1(.clk(clk), .rst(rst), .enable(enable_mul), .src1(src1), .src2(src2), .des1(mulsrc1), .des2(mulsrc2), .desOv(mulOv));
133
oc8051_divide oc8051_div1(.clk(clk), .rst(rst), .enable(enable_div), .src1(src1), .src2(src2), .des1(divsrc1), .des2(divsrc2), .desOv(divOv));
134
 
135
/* Add */
136
assign add1 = {1'b0,src1[3:0]};
137
assign add2 = {1'b0,src2[3:0]};
138
assign add3 = {3'b000,srcCy};
139
assign add4 = add1+add2+add3;
140
 
141
assign add5 = {1'b0,src1[6:4]};
142
assign add6 = {1'b0,src2[6:4]};
143
assign add7 = {1'b0,1'b0,1'b0,add4[4]};
144
assign add8 = add5+add6+add7;
145
 
146
assign add9 = {1'b0,src1[7]};
147
assign adda = {1'b0,src2[7]};
148
assign addb = {1'b0,add8[3]};
149
assign addc = add9+adda+addb;
150
 
151
/* Sub */
152
assign sub1 = {1'b1,src1[3:0]};
153
assign sub2 = {1'b0,src2[3:0]};
154
assign sub3 = {1'b0,1'b0,1'b0,srcCy};
155
assign sub4 = sub1-sub2-sub3;
156
 
157
assign sub5 = {1'b1,src1[6:4]};
158
assign sub6 = {1'b0,src2[6:4]};
159
assign sub7 = {1'b0,1'b0,1'b0, !sub4[4]};
160
assign sub8 = sub5-sub6-sub7;
161
 
162
assign sub9 = {1'b1,src1[7]};
163
assign suba = {1'b0,src2[7]};
164
assign subb = {1'b0,!sub8[3]};
165
assign subc = sub9-suba-subb;
166
 
167
 
168
always @(op_code or src1 or src2 or srcCy or srcAc or bit_in or src3 or mulsrc1 or mulsrc2 or mulOv or divsrc1 or divsrc2 or divOv or addc or add8 or add4 or sub4 or sub8 or subc or da_tmp)
169
begin
170
 
171
  case (op_code)
172
//operation add
173
    `OC8051_ALU_ADD: begin
174
      des1 = {addc[0],add8[2:0],add4[3:0]};
175
      des2 = src3+ {7'b0, addc[1]};
176
      desCy = addc[1];
177
      desAc = add4[4];
178
      desOv = addc[1] ^ add8[3];
179
 
180
      enable_mul = 1'b0;
181
      enable_div = 1'b0;
182
    end
183
//operation subtract
184
    `OC8051_ALU_SUB: begin
185
      des1 = {subc[0],sub8[2:0],sub4[3:0]};
186
      des2 = 8'h00;
187
      desCy = !subc[1];
188
      desAc = !sub4[4];
189 133 simont
      desOv = !subc[1] ^ !sub8[3];
190 82 simont
 
191
      enable_mul = 1'b0;
192
      enable_div = 1'b0;
193
    end
194
//operation multiply
195
    `OC8051_ALU_MUL: begin
196
      des1 = mulsrc1;
197
      des2 = mulsrc2;
198
      desOv = mulOv;
199
      desCy = 1'b0;
200
      desAc = 1'bx;
201
      enable_mul = 1'b1;
202
      enable_div = 1'b0;
203
    end
204
//operation divide
205
    `OC8051_ALU_DIV: begin
206
      des1 = divsrc1;
207
      des2 = divsrc2;
208
      desOv = divOv;
209
      desAc = 1'bx;
210
      desCy = 1'b0;
211
      enable_mul = 1'b0;
212
      enable_div = 1'b1;
213
    end
214
//operation decimal adjustment
215
    `OC8051_ALU_DA: begin
216
 
217
      if (srcAc==1'b1 | src1[3:0]>4'b1001) {da_tmp, des1[3:0]} = {1'b0, src1[3:0]}+ 5'b00110;
218
      else {da_tmp, des1[3:0]} = {1'b0, src1[3:0]};
219
 
220
      if (srcCy==1'b1 | src1[7:4]>4'b1001)
221
        {desCy, des1[7:4]} = {srcCy, src1[7:4]}+ 5'b00110 + {4'b0, da_tmp};
222
      else {desCy, des1[7:4]} = {srcCy, src1[7:4]} + {4'b0, da_tmp};
223
 
224
      des2 = 8'h00;
225
      desAc = 1'b0;
226
      desOv = 1'b0;
227
      enable_mul = 1'b0;
228
      enable_div = 1'b0;
229
    end
230
//operation not
231
// bit operation not
232
    `OC8051_ALU_NOT: begin
233
      des1 = ~src1;
234
      des2 = 8'h00;
235
      desCy = !srcCy;
236
      desAc = 1'bx;
237
      desOv = 1'bx;
238
      enable_mul = 1'b0;
239
      enable_div = 1'b0;
240
    end
241
//operation and
242
//bit operation and
243
    `OC8051_ALU_AND: begin
244
      des1 = src1 & src2;
245
      des2 = 8'h00;
246
      desCy = srcCy & bit_in;
247
      desAc = 1'bx;
248
      desOv = 1'bx;
249
      enable_mul = 1'b0;
250
      enable_div = 1'b0;
251
    end
252
//operation xor
253
// bit operation xor
254
    `OC8051_ALU_XOR: begin
255
      des1 = src1 ^ src2;
256
      des2 = 8'h00;
257
      desCy = srcCy ^ bit_in;
258
      desAc = 1'bx;
259
      desOv = 1'bx;
260
      enable_mul = 1'b0;
261
      enable_div = 1'b0;
262
    end
263
//operation or
264
// bit operation or
265
    `OC8051_ALU_OR: begin
266
      des1 = src1 | src2;
267
      des2 = 8'h00;
268
      desCy = srcCy | bit_in;
269
      desAc = 1'bx;
270
      desOv = 1'bx;
271
      enable_mul = 1'b0;
272
      enable_div = 1'b0;
273
    end
274
//operation rotate left
275
// bit operation cy= cy or (not ram)
276
    `OC8051_ALU_RL: begin
277
      des1 = {src1[6:0], src1[7]};
278
      des2 = 8'h00;
279
      desCy = srcCy | !bit_in;
280
      desAc = 1'bx;
281
      desOv = 1'bx;
282
      enable_mul = 1'b0;
283
      enable_div = 1'b0;
284
    end
285
//operation rotate left with carry and swap nibbles
286
    `OC8051_ALU_RLC: begin
287
      des1 = {src1[6:0], srcCy};
288
      des2 = {src1[3:0], src1[7:4]};
289
      desCy = src1[7];
290
      desAc = 1'b0;
291
      desOv = 1'b0;
292
      enable_mul = 1'b0;
293
      enable_div = 1'b0;
294
    end
295
//operation rotate right
296
    `OC8051_ALU_RR: begin
297
      des1 = {src1[0], src1[7:1]};
298
      des2 = 8'h00;
299
      desCy = srcCy & !bit_in;
300
      desAc = 1'b0;
301
      desOv = 1'b0;
302
      enable_mul = 1'b0;
303
      enable_div = 1'b0;
304
    end
305
//operation rotate right with carry
306
    `OC8051_ALU_RRC: begin
307
      des1 = {srcCy, src1[7:1]};
308
      des2 = 8'h00;
309
      desCy = src1[0];
310
      desAc = 1'b0;
311
      desOv = 1'b0;
312
      enable_mul = 1'b0;
313
      enable_div = 1'b0;
314
    end
315
//operation pcs Add
316 132 simont
/*    `OC8051_ALU_PCS: begin
317 82 simont
      if (src1[7]) begin
318 123 simont
        {desCy, des1} = {1'b0, src2} + {1'b0, src1};
319
        des2 = {1'b0, src3} - {8'h0, !desCy};
320 82 simont
      end else {des2, des1} = {src3,src2} + {8'h00, src1};
321
      desCy = 1'b0;
322
      desAc = 1'b0;
323
      desOv = 1'b0;
324
      enable_mul = 1'b0;
325
      enable_div = 1'b0;
326 132 simont
    end*/
327 82 simont
//operation exchange
328
//if carry = 0 exchange low order digit
329
    `OC8051_ALU_XCH: begin
330
      if (srcCy)
331
      begin
332
        des1 = src2;
333
        des2 = src1;
334
      end else begin
335
        des1 = {src1[7:4],src2[3:0]};
336
        des2 = {src2[7:4],src1[3:0]};
337
      end
338
      desCy = 1'b0;
339
      desAc = 1'b0;
340
      desOv = 1'b0;
341
      enable_mul = 1'b0;
342
      enable_div = 1'b0;
343
    end
344
    default: begin
345
      des1 = src1;
346
      des2 = src2;
347
      desCy = srcCy;
348
      desAc = srcAc;
349 123 simont
      desOv = 1'b0;
350 82 simont
      enable_mul = 1'b0;
351
      enable_div = 1'b0;
352
    end
353
  endcase
354
end
355
 
356
endmodule

powered by: WebSVN 2.1.0

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