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

Subversion Repositories scarm

[/] [scarm/] [trunk/] [src/] [components/] [ALU/] [scALU.cpp] - Blame information for rev 10

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

Line No. Rev Author Line
1 2 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
 
31
//////////////////////////////////////////////////////////////////////
32
// Construction/Destruction
33
//////////////////////////////////////////////////////////////////////
34
 
35
#include ".\components\alu\scALU.h"
36
#include".\instructions\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
  // C Flag = shifter_carry_out 
319
  // Done otherwhere
320
 
321
  // V Flag = unaffected
322
 
323
  return b;
324
}
325
 
326
 
327
/******************************************************************************
328
 *
329
 */
330
uint32_t scALU::mvn_op(uint32_t a, uint32_t b, uint32_t* cond)
331
{
332
  // Clear flags (overflow unaffected)
333
  *cond &= (0x0FFFFFFF | V_FLAG);
334
 
335
  // N Flag = Rd[31]
336
  if (((b >> 31) & 0x1) == 1)
337
    (*cond) |= N_FLAG;
338
 
339
  // Z Flag = if Rd == 0 then 1 else 0
340
  if (~b == 0)
341
    (*cond) |= Z_FLAG;
342
 
343
  // C Flag = shifter_carry_out 
344
  // Done otherwhere
345
 
346
  // V Flag = unaffected
347
 
348
  return ~b;
349
}
350
 
351
 
352
/******************************************************************************
353
 *
354
 */
355
uint32_t scALU::orr_op(uint32_t a, uint32_t b, uint32_t* cond)
356
{
357
  uint32_t temp;
358
 
359
  temp = a | b;
360
 
361
  // Clear flags (overflow unaffected)
362
  *cond &= (0x0FFFFFFF | V_FLAG);
363
 
364
  // N Flag = Rd[31]
365
  if (((b >> 31) & 0x1) == 1)
366
    (*cond) |= N_FLAG;
367
 
368
  // Z Flag = if Rd == 0 then 1 else 0
369
  if (temp == 0)
370
    (*cond) |= Z_FLAG;
371
 
372
  // C Flag = shifter_carry_out 
373
  // Done otherwhere
374
 
375
  // V Flag = unaffected
376
 
377
  return temp;
378
}
379
 
380
 
381
/******************************************************************************
382
 *
383
 */
384
uint32_t scALU::rsb_op(uint32_t a, uint32_t b, uint32_t* cond)
385
{
386
  int64_t temp, result;
387
  uint32_t short_res;
388
  uint32_t c = (*cond);
389
 
390
  temp = (int32_t)b;
391
  temp -= (int32_t)a;
392
 
393
  result = temp & 0x00000000FFFFFFFFL;
394
  short_res = (uint32_t)((uint64_t)temp);
395
 
396
  // Clear flags
397
  *cond &= 0x0FFFFFFF;
398
 
399
  // N Flag = Rd[31]
400
  if (((temp >> 31) & 0x1) == 1)
401
    (*cond) |= N_FLAG;
402
 
403
  // Z Flag = If Rd == 0 then 1 else 0
404
  if (result == 0)
405
    (*cond) |= Z_FLAG;
406
 
407
  // C Flag = NOT BorrowedFrom(shifter_operand - Rn)
408
  if (BORROWED_FROM((uint32_t)b, (uint32_t)a, short_res) == 0)
409
    (*cond) |= C_FLAG;
410
 
411
  // V Flag = OverflowFrom(shifter_operand - Rn)
412
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
413
    (*cond) |= V_FLAG;
414
 
415
  return (uint32_t)result;
416
}
417
 
418
 
419
/******************************************************************************
420
 *
421
 */
422
uint32_t scALU::rsc_op(uint32_t a, uint32_t b, uint32_t* cond)
423
{
424
  int64_t temp, result;
425
  uint32_t short_res;
426
  uint32_t c = (*cond);
427
 
428
  temp = (int32_t)b;
429
  temp -= (int32_t)a;
430
  if (!(c & C_FLAG))
431
    temp--;
432
 
433
  result = temp & 0x00000000FFFFFFFFL;
434
  short_res = (uint32_t)((uint64_t)temp);
435
 
436
  // Clear flags
437
  *cond &= 0x0FFFFFFF;
438
 
439
  // N Flag = Rd[31]
440
  if (((temp >> 31) & 0x1) == 1)
441
    (*cond) |= N_FLAG;
442
 
443
  // Z Flag = If Rd == 0 then 1 else 0
444
  if (result == 0)
445
    (*cond) |= Z_FLAG;
446
 
447
  // C Flag = NOT BorrowedFrom(shifter_operand - Rn - NOT(C Flag))
448
  if (BORROWED_FROM((uint32_t)b, (uint32_t)a, short_res) == 0)
449
    (*cond) |= C_FLAG;
450
 
451
  // V Flag = OverflowFrom(shifter_operand - Rn - NOT(C Flag))
452
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
453
    (*cond) |= V_FLAG;
454
 
455
  return (uint32_t)result;
456
}
457
 
458
 
459
/******************************************************************************
460
 *
461
 */
462
uint32_t scALU::sbc_op(uint32_t a, uint32_t b, uint32_t* cond)
463
{
464
  int64_t temp, result;
465
  uint32_t short_res;
466
  uint32_t c = (*cond);
467
 
468
  temp = (int32_t)a;
469
  temp -= (int32_t)b;
470
  if (!(c & C_FLAG))
471
    temp--;
472
 
473
  result = temp & 0x00000000FFFFFFFFL;
474
  short_res = (uint32_t)((uint64_t)temp);
475
 
476
  // Clear flags
477
  *cond &= 0x0FFFFFFF;
478
 
479
  // N Flag = Rd[31]
480
  if (((temp >> 31) & 0x1) == 1)
481
    (*cond) |= N_FLAG;
482
 
483
  // Z Flag = If Rd == 0 then 1 else 0
484
  if (result == 0)
485
    (*cond) |= Z_FLAG;
486
 
487
  // C Flag = NOT BorrowedFrom(Rn - shifter_operand - NOT(C Flag))
488
  if (BORROWED_FROM((uint32_t)a, (uint32_t)b, short_res) == 0)
489
    (*cond) |= C_FLAG;
490
 
491
  // V Flag = OverflowFrom(Rn - shifter_operand - NOT(C Flag))
492
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
493
    (*cond) |= V_FLAG;
494
 
495
  return (uint32_t)result;
496
}
497
 
498
 
499
/******************************************************************************
500
 *
501
 */
502
uint32_t scALU::sub_op(uint32_t a, uint32_t b, uint32_t* cond)
503
{
504
  int64_t temp, result, foo;
505
  uint32_t c = (*cond);
506
  //uint32_t res;
507
 
508
  temp = (int32_t)a;
509
  temp -= (int32_t)b;
510
 
511
  result = temp & 0x00000000FFFFFFFFL;
512
 
513
  // Clear flags
514
  *cond &= 0x0FFFFFFF;
515
 
516
  // N Flag = Rd[31]
517
  if (((temp >> 31) & 0x1) == 1)
518
    (*cond) |= N_FLAG;
519
 
520
  // Z Flag = If Rd == 0 then 1 else 0
521
  if (result == 0)
522
    (*cond) |= Z_FLAG;
523
 
524
// C Flag = NOT BorrowedFrom(Rn - shifter_operand - NOT(C Flag))
525
#if 0
526
  if (result == temp)
527
    (*cond) |= C_FLAG;
528
#else
529
  foo = (uint32_t)((uint64_t)result);
530
  //cout.form("foo = 0x%08x\n", foo);
531
  if (BORROWED_FROM(a, b, foo) == 0)
532
    (*cond) |= C_FLAG;
533
 
534
#endif
535
 
536
  // V Flag = OverflowFrom(Rn - shifter_operand - NOT(C Flag))
537
  if (((temp >> 32) & 0x1) != ((temp >> 31) & 0x1))
538
    (*cond) |= V_FLAG;
539
 
540
  return (uint32_t)result;
541
}
542
 
543
 
544
/******************************************************************************
545
 *
546
 */
547
uint32_t scALU::teq_op(uint32_t a, uint32_t b, uint32_t* cond)
548
{
549
  uint32_t result;
550
 
551
  result = a ^ b;
552
 
553
  // Clear Flags (overflow unaffected)
554
  *cond &= (0x0FFFFFFF | V_FLAG);
555
 
556
  // N Flag = Rd[31]
557
  if (((result >> 31) & 0x1) == 1)
558
    (*cond) |= N_FLAG;
559
 
560
  // Z Flag = If Rd == 0 then 1 else 0
561
  if (result == 0)
562
    (*cond) |= Z_FLAG;
563
 
564
  // C Flag = shifter_carry_out 
565
  // Done otherwhere
566
 
567
  // V Flag = unaffected
568
 
569
  return 0;
570
}
571
 
572
 
573
/******************************************************************************
574
 *
575
 */
576
uint32_t scALU::tst_op(uint32_t a, uint32_t b, uint32_t* cond)
577
{
578
  int32_t result;
579
 
580
  result = a & b;
581
 
582
  // Clear Flags (overflow unaffected)
583
  *cond &= (0x0FFFFFFF | V_FLAG);
584
 
585
  // N Flag = Rd[31]
586
  if (((result >> 31) & 0x1) == 1)
587
    (*cond) |= N_FLAG;
588
 
589
  // Z Flag = If Rd == 0 then 1 else 0
590
  if (result == 0)
591
    (*cond) |= Z_FLAG;
592
 
593
  // C Flag = shifter_carry_out 
594
  // Done otherwhere
595
 
596
  // V Flag = unaffected
597
 
598
  return 0;
599
}
600
void scALU::entry()
601
{
602
   OPCODE   op   =in_OP;
603
   COND     c    =in_COND;
604
   uint32_t a    =in_n_A;
605
   uint32_t b    =in_n_B;
606
   uint32_t condition  =c;
607
   sc_time local_time = sc_time_stamp();
608
   condition=(condition<<28);
609
   switch (op)
610
   {
611
    case OP_AND: {      out_n_Out=and_op(a,b,&condition);cout<<"and_op";  break; }
612
    case OP_EOR: {      out_n_Out=eor_op(a,b,&condition);cout<<"eor_op";        break; }
613
    case OP_SUB: {      out_n_Out=sub_op(a,b,&condition);cout<<"sub_op";        break; }
614
    case OP_RSB: {      out_n_Out=rsb_op(a,b,&condition);cout<<"rsb_op";        break; }
615
    case OP_ADD: {      out_n_Out=add_op(a,b,&condition);cout<<"add_op";        break; }
616
    case OP_ADC: {      out_n_Out=adc_op(a,b,&condition);cout<<"adc_op";    break; }
617
    case OP_SBC: {      out_n_Out=sbc_op(a,b,&condition);cout<<"sbc_op";        break; }
618
    case OP_RSC: {      out_n_Out=rsc_op(a,b,&condition);cout<<"rsc_op";        break; }
619
    case OP_TST: {      out_n_Out=tst_op(a,b,&condition);cout<<"tst_op";        break; }
620
    case OP_TEQ: {      out_n_Out=teq_op(a,b,&condition);cout<<"teq_op";        break; }
621
    case OP_CMP: {      out_n_Out=cmp_op(a,b,&condition);cout<<"cmp_op";        break; }
622
    case OP_CMN: {      out_n_Out=cmn_op(a,b,&condition);cout<<"cmn_op";        break; }
623
    case OP_MOV: {      out_n_Out=mov_op(a,b,&condition);cout<<"mov_op";        break; }
624
    case OP_BIC: {      out_n_Out=bic_op(a,b,&condition);cout<<"bic_op";        break; }
625
    case OP_MVN: {      out_n_Out=mvn_op(a,b,&condition);cout<<"mvn_op";        break; }
626
    default:
627
                {
628
          cout<<" unknown op="<<op;
629
 
630
                }
631
   }//end of switch op
632
   out_n_Flag=condition;
633
   cout<<"  a="<<a<<"  b="<<b<<"  output="<<out_n_Out<<endl;
634
}

powered by: WebSVN 2.1.0

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