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

Subversion Repositories scarm

[/] [scarm/] [trunk/] [src/] [scALU.cpp] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 zhong
///////////////////////////////////////////////////////////////////////////////
2
// This program is free software; you can redistribute it and/or
3
// modify it under the terms of the GNU General Public License
4
// as published by the Free Software Foundation; either version 2
5
// of the License, or (at your option) any later version.
6
//
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
// GNU General Public License for more details.
11
//
12
// You should have received a copy of the GNU General Public License
13
// along with this program; if not, write to the Free Software
14
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15
//////////////////////////////////////////////////////////////////////
16
 
17
///////////////////////////////////////////////////////////////////              
18
//          
19
//  Original Author: Allen Tao Zhong,
20
//  University of Electronic Science and Technology in China
21
//  email: zhong@opencores.org
22
//  info   This is a SystemC ARM model,I "stole" some codes from 
23
//       "swarm" , author Michael Dales (michael@dcs.gla.ac.uk)
24
//        
25
// scALU.cpp: implementation of the scALU class.
26
//
27
//////////////////////////////////////////////////////////////////////
28
 
29
#include "scALU.h"
30
#define DEBUG
31
//////////////////////////////////////////////////////////////////////
32
// Construction/Destruction
33
//////////////////////////////////////////////////////////////////////
34
 
35
#include "scALU.h"
36
#include"scARMInstruction.h"
37
#define CARRY_FROM(_a,_b,_r) ((_a >> 31) ? ((_b >> 31) | ((~_r) >> 31)) : ((_b >> 31) * ((~_r) >> 31)))
38
 
39
#define BORROWED_FROM(_a,_b,_r) ((_a >> 31) ? ((_b >> 31) & (_r >> 31)) : ((_b >> 31) | (_r >> 31)))
40
 
41
//////////////////////////////////////////////////////////////////////
42
// Construction/Destruction
43
//////////////////////////////////////////////////////////////////////
44
 
45
 
46
 
47
scALU::~scALU()
48
{
49
 
50
}
51
/******************************************************************************
52
 *
53
 */
54
uint32_t scALU::adc_op(uint32_t a, uint32_t b, uint32_t* cond)
55
{
56
  int64_t temp;
57
  //int64_t result;
58
  uint32_t short_res;
59
  uint32_t c = (*cond);
60
 
61
  temp = (int32_t)a;
62
  temp += (int32_t)b;
63
  if (c & C_FLAG)
64
    temp++;
65
 
66
  //result = temp & 0x00000000FFFFFFFFL;
67
  short_res = (uint32_t)((uint64_t)temp);
68
 
69
  // Clear flags 
70
  *cond &= 0x0FFFFFFF;
71
 
72
  // N Flags = Rd[31] 
73
  if (((temp >> 31) & 0x1) == 1)
74
    (*cond) |= N_FLAG;
75
 
76
  // Z Flag = if Rd == 0 then 1 else 0
77
  if (short_res == 0)
78
    (*cond) |= Z_FLAG;
79
 
80
  // C Flag = CarryFrom(Rn + shifter_operand + C Flag)
81
  if (CARRY_FROM((uint32_t)a, (uint32_t)b, short_res))
82
    (*cond) |= C_FLAG;
83
 
84
  // V Flag = OverflowFrom(Rn + shifter_operand + C Flag)
85
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
86
    (*cond) |= V_FLAG;
87
 
88
  return (uint32_t)short_res;
89
}
90
 
91
 
92
 
93
uint32_t scALU::add_op(uint32_t a, uint32_t b, uint32_t* cond)
94
{
95
  int64_t temp;
96
  //int64_t result;
97
  uint32_t short_res;
98
  uint32_t c = (*cond);
99
 
100
  temp = (int64_t)((int32_t)a);
101
  temp += (int64_t)((int32_t)b);
102
 
103
  //result = temp & 0x00000000FFFFFFFFL;
104
  short_res = (uint32_t)((uint64_t)temp);
105
 
106
  // Clear flags 
107
  *cond &= 0x0FFFFFFF;
108
 
109
  // N Flags = Rd[31] 
110
  if (((temp >> 31) & 0x1) == 1)
111
    (*cond) |= N_FLAG;
112
 
113
  // Z Flag = if Rd == 0 then 1 else 0
114
  if (short_res == 0)
115
    (*cond) |= Z_FLAG;
116
 
117
  // C Flag = CarryFrom(Rn + shifter_operand)
118
  if (CARRY_FROM((uint32_t)a, (uint32_t)b, short_res))
119
    (*cond) |= C_FLAG;
120
 
121
  // V Flag = OverflowFrom(Rn + shifter_operand)
122
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1)) {
123
    (*cond) |= V_FLAG;
124
  }
125
 
126
  return (uint32_t)short_res;
127
}
128
 
129
/******************************************************************************
130
 *
131
 */
132
uint32_t scALU::and_op(uint32_t a, uint32_t b, uint32_t* cond)
133
{
134
  uint32_t temp;
135
 
136
  temp = a & b;
137
 
138
  // Clear flags - V flag uneffected
139
  *cond &= (0x0FFFFFFF | V_FLAG);
140
 
141
  // N Flag = Rd[31]
142
  if (((temp >> 31) & 0x1) == 1)
143
    (*cond) |= N_FLAG;
144
 
145
  // Z Flag = if Rd == 0 then 1 else 0
146
  if (temp == 0)
147
    (*cond) |= Z_FLAG;
148
 
149
  // C Flag = shifter_carry_out 
150
  // Done otherwhere
151
 
152
  // V Flag = unaffected
153
 
154
  return temp;
155
}
156
 
157
 
158
/******************************************************************************
159
 *
160
 */
161
uint32_t scALU::bic_op(uint32_t a, uint32_t b, uint32_t* cond)
162
{
163
  uint32_t temp;
164
 
165
  temp = a & ~b;
166
 
167
  // Clear flags
168
  *cond &= (0x0FFFFFFF | V_FLAG);
169
 
170
  // N Flag = Rd[31]
171
  if (((temp >> 31) & 0x1) == 1)
172
    (*cond) |= N_FLAG;
173
 
174
  // Z Flag = if Rd == 0 then 1 else 0
175
  if (temp == 0)
176
    (*cond) |= Z_FLAG;
177
 
178
  // C Flag = shifter_carry_out 
179
  // Done otherwhere
180
 
181
  // V Flag = unaffected
182
 
183
  return temp;
184
}
185
 
186
 
187
/******************************************************************************
188
 *
189
 */
190
uint32_t scALU::cmn_op(uint32_t a, uint32_t b, uint32_t* cond)
191
{
192
  int64_t temp;
193
  //int64_t result;
194
  uint32_t short_res;
195
  uint32_t c = (*cond);
196
 
197
  temp = (int64_t)a;
198
  temp += (int64_t)b;
199
 
200
  //result = temp & 0x00000000FFFFFFFFL;
201
  short_res = (uint32_t)((uint64_t)temp);
202
 
203
  // Clear flags
204
  *cond &= 0x0FFFFFFF;
205
 
206
  // N Flags = Rd[31] 
207
  if (((temp >> 31) & 0x1) == 1)
208
    (*cond) |= N_FLAG;
209
 
210
  // Z Flag = if Rd == 0 then 1 else 0
211
  if (short_res == 0)
212
    (*cond) |= Z_FLAG;
213
 
214
  // C Flag = CarryFrom(Rn + shifter_operand)
215
  if (CARRY_FROM((uint32_t)a, (uint32_t)b, short_res))
216
    (*cond) |= C_FLAG;
217
 
218
  temp = (int64_t)((int32_t)a);
219
  temp += (int32_t)b;
220
 
221
  // V Flag = OverflowFrom(Rn + shifter_operand)
222
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
223
    (*cond) |= V_FLAG;
224
 
225
  return 0;
226
}
227
 
228
 
229
/******************************************************************************
230
 *
231
 */
232
uint32_t scALU::cmp_op(uint32_t a, uint32_t b, uint32_t* cond)
233
{
234
  int64_t temp, result;
235
  uint32_t short_res;
236
  uint32_t c = (*cond);
237
 
238
  temp = (int32_t)a;
239
  temp -= (int32_t)b;
240
 
241
  result = temp & 0x00000000FFFFFFFFL;
242
  short_res = (uint32_t)((uint64_t)temp);
243
 
244
  uint64_t temp2 = (uint32_t)a;
245
  temp2 -= (uint32_t)b;
246
 
247
  uint64_t result2 = temp2 & 0x00000000FFFFFFFF;
248
 
249
  // Clear flags
250
  *cond &= 0x0FFFFFFF;
251
 
252
  // N Flag = Rd[31]
253
  if (((temp >> 31) & 0x1) == 1)
254
    (*cond) |= N_FLAG;
255
 
256
  // Z Flag = if Rd == 0 then 1 else 0
257
  if (short_res == 0)
258
    (*cond) |= Z_FLAG;
259
 
260
  // C Flag = NOT BorrowFrom(Rn - shifter_operand)
261
  //if (result2 == temp2)
262
  if (BORROWED_FROM((uint32_t)a, (uint32_t)b, short_res) == 0)
263
    (*cond) |= C_FLAG;
264
 
265
  // V Flag = OverFlowFrom (Rn - shifter_operand)
266
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
267
    (*cond) |= V_FLAG;
268
 
269
  return 0;
270
}
271
 
272
 
273
/******************************************************************************
274
 *
275
 */
276
uint32_t scALU::eor_op(uint32_t a, uint32_t b, uint32_t* cond)
277
{
278
  uint32_t temp;
279
 
280
  temp = a ^ b;
281
 
282
  // Clear flags (overflow unaffected)
283
  *cond &= (0x0FFFFFFF | V_FLAG);
284
 
285
  // N Flag = Rd[31]
286
  if (((temp >> 31) & 0x1) == 1)
287
    (*cond) |= N_FLAG;
288
 
289
  // Z Flag = if Rd == 0 then 1 else 0
290
  if (temp == 0)
291
    (*cond) |= Z_FLAG;
292
 
293
  // C Flag = shifter_carry_out 
294
  // Done otherwhere
295
 
296
  // V Flag = unaffected
297
 
298
  return temp;
299
}
300
 
301
 
302
/******************************************************************************
303
 *
304
 */
305
uint32_t scALU::mov_op(uint32_t a, uint32_t b, uint32_t* cond)
306
{
307
  // Clear flags (overflow unaffected)
308
  *cond &= (0x0FFFFFFF | V_FLAG);
309
 
310
  // N Flag = Rd[31]
311
  if (((b >> 31) & 0x1) == 1)
312
    (*cond) |= N_FLAG;
313
 
314
  // Z Flag = if Rd == 0 then 1 else 0
315
  if (b == 0)
316
    (*cond) |= Z_FLAG;
317
 
318
  //cout<<"move"<<endl;
319
  // C Flag = shifter_carry_out 
320
  // Done otherwhere
321
 
322
  // V Flag = unaffected
323
 
324
  return b;
325
}
326
 
327
 
328
/******************************************************************************
329
 *
330
 */
331
uint32_t scALU::mvn_op(uint32_t a, uint32_t b, uint32_t* cond)
332
{
333
  // Clear flags (overflow unaffected)
334
  *cond &= (0x0FFFFFFF | V_FLAG);
335
 
336
  // N Flag = Rd[31]
337
  if (((b >> 31) & 0x1) == 1)
338
    (*cond) |= N_FLAG;
339
 
340
  // Z Flag = if Rd == 0 then 1 else 0
341
  if (~b == 0)
342
    (*cond) |= Z_FLAG;
343
 
344
  // C Flag = shifter_carry_out 
345
  // Done otherwhere
346
 
347
  // V Flag = unaffected
348
 
349
  return ~b;
350
}
351
 
352
 
353
/******************************************************************************
354
 *
355
 */
356
uint32_t scALU::orr_op(uint32_t a, uint32_t b, uint32_t* cond)
357
{
358
  uint32_t temp;
359
 
360
  temp = a | b;
361
 
362
  // Clear flags (overflow unaffected)
363
  *cond &= (0x0FFFFFFF | V_FLAG);
364
 
365
  // N Flag = Rd[31]
366
  if (((b >> 31) & 0x1) == 1)
367
    (*cond) |= N_FLAG;
368
 
369
  // Z Flag = if Rd == 0 then 1 else 0
370
  if (temp == 0)
371
    (*cond) |= Z_FLAG;
372
 
373
  // C Flag = shifter_carry_out 
374
  // Done otherwhere
375
 
376
  // V Flag = unaffected
377
 
378
  return temp;
379
}
380
 
381
 
382
/******************************************************************************
383
 *
384
 */
385
uint32_t scALU::rsb_op(uint32_t a, uint32_t b, uint32_t* cond)
386
{
387
  int64_t temp, result;
388
  uint32_t short_res;
389
  uint32_t c = (*cond);
390
 
391
  temp = (int32_t)b;
392
  temp -= (int32_t)a;
393
 
394
  result = temp & 0x00000000FFFFFFFFL;
395
  short_res = (uint32_t)((uint64_t)temp);
396
 
397
  // Clear flags
398
  *cond &= 0x0FFFFFFF;
399
 
400
  // N Flag = Rd[31]
401
  if (((temp >> 31) & 0x1) == 1)
402
    (*cond) |= N_FLAG;
403
 
404
  // Z Flag = If Rd == 0 then 1 else 0
405
  if (result == 0)
406
    (*cond) |= Z_FLAG;
407
 
408
  // C Flag = NOT BorrowedFrom(shifter_operand - Rn)
409
  if (BORROWED_FROM((uint32_t)b, (uint32_t)a, short_res) == 0)
410
    (*cond) |= C_FLAG;
411
 
412
  // V Flag = OverflowFrom(shifter_operand - Rn)
413
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
414
    (*cond) |= V_FLAG;
415
 
416
  return (uint32_t)result;
417
}
418
 
419
 
420
/******************************************************************************
421
 *
422
 */
423
uint32_t scALU::rsc_op(uint32_t a, uint32_t b, uint32_t* cond)
424
{
425
  int64_t temp, result;
426
  uint32_t short_res;
427
  uint32_t c = (*cond);
428
 
429
  temp = (int32_t)b;
430
  temp -= (int32_t)a;
431
  if (!(c & C_FLAG))
432
    temp--;
433
 
434
  result = temp & 0x00000000FFFFFFFFL;
435
  short_res = (uint32_t)((uint64_t)temp);
436
 
437
  // Clear flags
438
  *cond &= 0x0FFFFFFF;
439
 
440
  // N Flag = Rd[31]
441
  if (((temp >> 31) & 0x1) == 1)
442
    (*cond) |= N_FLAG;
443
 
444
  // Z Flag = If Rd == 0 then 1 else 0
445
  if (result == 0)
446
    (*cond) |= Z_FLAG;
447
 
448
  // C Flag = NOT BorrowedFrom(shifter_operand - Rn - NOT(C Flag))
449
  if (BORROWED_FROM((uint32_t)b, (uint32_t)a, short_res) == 0)
450
    (*cond) |= C_FLAG;
451
 
452
  // V Flag = OverflowFrom(shifter_operand - Rn - NOT(C Flag))
453
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
454
    (*cond) |= V_FLAG;
455
 
456
  return (uint32_t)result;
457
}
458
 
459
 
460
/******************************************************************************
461
 *
462
 */
463
uint32_t scALU::sbc_op(uint32_t a, uint32_t b, uint32_t* cond)
464
{
465
  int64_t temp, result;
466
  uint32_t short_res;
467
  uint32_t c = (*cond);
468
 
469
  temp = (int32_t)a;
470
  temp -= (int32_t)b;
471
  if (!(c & C_FLAG))
472
    temp--;
473
 
474
  result = temp & 0x00000000FFFFFFFFL;
475
  short_res = (uint32_t)((uint64_t)temp);
476
 
477
  // Clear flags
478
  *cond &= 0x0FFFFFFF;
479
 
480
  // N Flag = Rd[31]
481
  if (((temp >> 31) & 0x1) == 1)
482
    (*cond) |= N_FLAG;
483
 
484
  // Z Flag = If Rd == 0 then 1 else 0
485
  if (result == 0)
486
    (*cond) |= Z_FLAG;
487
 
488
  // C Flag = NOT BorrowedFrom(Rn - shifter_operand - NOT(C Flag))
489
  if (BORROWED_FROM((uint32_t)a, (uint32_t)b, short_res) == 0)
490
    (*cond) |= C_FLAG;
491
 
492
  // V Flag = OverflowFrom(Rn - shifter_operand - NOT(C Flag))
493
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
494
    (*cond) |= V_FLAG;
495
 
496
  return (uint32_t)result;
497
}
498
 
499
 
500
/******************************************************************************
501
 *
502
 */
503
uint32_t scALU::sub_op(uint32_t a, uint32_t b, uint32_t* cond)
504
{
505
  int64_t temp, result, foo;
506
  uint32_t c = (*cond);
507
  //uint32_t res;
508
 
509
  temp = (int32_t)a;
510
  temp -= (int32_t)b;
511
 
512
  result = temp & 0x00000000FFFFFFFFL;
513
 
514
  // Clear flags
515
  *cond &= 0x0FFFFFFF;
516
 
517
  // N Flag = Rd[31]
518
  if (((temp >> 31) & 0x1) == 1)
519
    (*cond) |= N_FLAG;
520
 
521
  // Z Flag = If Rd == 0 then 1 else 0
522
  if (result == 0)
523
    (*cond) |= Z_FLAG;
524
 
525
// C Flag = NOT BorrowedFrom(Rn - shifter_operand - NOT(C Flag))
526
#if 0
527
  if (result == temp)
528
    (*cond) |= C_FLAG;
529
#else
530
  foo = (uint32_t)((uint64_t)result);
531
  //cout.form("foo = 0x%08x\n", foo);
532
  if (BORROWED_FROM(a, b, foo) == 0)
533
    (*cond) |= C_FLAG;
534
 
535
#endif
536
 
537
  // V Flag = OverflowFrom(Rn - shifter_operand - NOT(C Flag))
538
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
539
    (*cond) |= V_FLAG;
540
 
541
  return (uint32_t)result;
542
}
543
 
544
 
545
/******************************************************************************
546
 *
547
 */
548
uint32_t scALU::teq_op(uint32_t a, uint32_t b, uint32_t* cond)
549
{
550
  uint32_t result;
551
 
552
  result = a ^ b;
553
 
554
  // Clear Flags (overflow unaffected)
555
  *cond &= (0x0FFFFFFF | V_FLAG);
556
 
557
  // N Flag = Rd[31]
558
  if (((result >> 31) & 0x1) == 1)
559
    (*cond) |= N_FLAG;
560
 
561
  // Z Flag = If Rd == 0 then 1 else 0
562
  if (result == 0)
563
    (*cond) |= Z_FLAG;
564
 
565
  // C Flag = shifter_carry_out 
566
  // Done otherwhere
567
 
568
  // V Flag = unaffected
569
 
570
  return 0;
571
}
572
 
573
 
574
/******************************************************************************
575
 *
576
 */
577
uint32_t scALU::tst_op(uint32_t a, uint32_t b, uint32_t* cond)
578
{
579
  int32_t result;
580
 
581
  result = a & b;
582
 
583
  // Clear Flags (overflow unaffected)
584
  *cond &= (0x0FFFFFFF | V_FLAG);
585
 
586
  // N Flag = Rd[31]
587
  if (((result >> 31) & 0x1) == 1)
588
    (*cond) |= N_FLAG;
589
 
590
  // Z Flag = If Rd == 0 then 1 else 0
591
  if (result == 0)
592
    (*cond) |= Z_FLAG;
593
 
594
  // C Flag = shifter_carry_out 
595
  // Done otherwhere
596
 
597
  // V Flag = unaffected
598
 
599
  return 0;
600
}
601
void scALU::entry()
602
{
603
   OPCODE   op   =in_OP;
604
   uint32_t condition=inout_n_Flag;
605
   uint32_t a    =in_n_A;
606
   uint32_t b    =in_n_B;
607
 
608
   //sc_time local_time = sc_time_stamp();
609
 
610
   uint32_t result=0;
611
   switch (op)
612
   {
613
    case OP_AND: {      result=and_op(a,b,&condition);/*cout<<"and_op";*/   break; }
614
    case OP_EOR: {      result=eor_op(a,b,&condition);/*cout<<"eor_op";*/       break; }
615
    case OP_SUB: {      result=sub_op(a,b,&condition);/*cout<<"sub_op";*/       break; }
616
    case OP_RSB: {      result=rsb_op(a,b,&condition);/*cout<<"rsb_op";*/       break; }
617
    case OP_ADD: {      result=add_op(a,b,&condition);/*cout<<"add_op";*/       break; }
618
    case OP_ADC: {      result=adc_op(a,b,&condition);/*cout<<"adc_op";*/   break; }
619
    case OP_SBC: {      result=sbc_op(a,b,&condition);/*cout<<"sbc_op";*/       break; }
620
    case OP_RSC: {      result=rsc_op(a,b,&condition);/*cout<<"rsc_op";*/       break; }
621
    case OP_TST: {      result=tst_op(a,b,&condition);/*cout<<"tst_op";*/       break; }
622
    case OP_ORR: {      result=orr_op(a,b,&condition);/*cout<<"orr_op";*/       break; }
623
    case OP_TEQ: {      result=teq_op(a,b,&condition);/*cout<<"teq_op";*/       break; }
624
    case OP_CMP: {      result=cmp_op(a,b,&condition);/*cout<<"cmp_op";*/       break; }
625
    case OP_CMN: {      result=cmn_op(a,b,&condition);/*cout<<"cmn_op";*/       break; }
626
    case OP_MOV: {      result=mov_op(a,b,&condition);/*cout<<"mov_op";*/       break; }
627
    case OP_BIC: {      result=bic_op(a,b,&condition);/*cout<<"bic_op";*/       break; }
628
    case OP_MVN: {      result=mvn_op(a,b,&condition);/*cout<<"mvn_op";*/       break; }
629
    default:
630
                {
631
          cout<<"ALU: unknown op="<<op<<endl;
632
 
633
                }
634
   }//end of switch op
635
   inout_n_Flag=condition;
636
   //cout<<"flag="<<condition<<endl;
637
   out_n_Out=result;
638
 
639
#if defined(DEBUG)
640
   // cout<<" ALU: output="<<result<<endl;
641
#endif
642
}
643
 
644
void scALU::display()
645
{
646
   cout<<"A="<<in_n_A<<" B="<<in_n_B<<endl;
647
}

powered by: WebSVN 2.1.0

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