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

Subversion Repositories scarm

[/] [scarm/] [trunk/] [src/] [scID.cpp] - Blame information for rev 5

Go to most recent revision | 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
23
// scID.cpp: implementation of the scID class.
24
//
25
//////////////////////////////////////////////////////////////////////
26
 
27
#include "scID.h"
28
#include "scDP1.h"
29
#include "scDP2.h"
30
#include "scDP3.h"
31
#include "scB.h"
32
#include "scSW1.h"
33
#include "scSW2.h"
34
#include "scUNDEF.h"
35
#include "scSWI.h"
36
#include "scSWP.h"
37
#include "scMULT.h"
38
#include "scHWT.h"
39
#include "scMRT.h"
40
#include "scMRS.h"
41
#include "scCD.h"
42
#include "scCR.h"
43
#include "scCDP.h"
44
#include "scNOOP.h"
45
 
46
 
47
//////////////////////////////////////////////////////////////////////
48
// Construction/Destruction
49
//////////////////////////////////////////////////////////////////////
50
 
51
 
52
 
53
 
54
 
55
scID::~scID()
56
{
57
 
58
}
59
 
60
void  scID::entry()
61
{
62
  m_pc=in_n_PC;
63
 
64
  m_ir=in_n_Instruction;
65
 
66
  trigger0.notify(SC_ZERO_TIME);
67
}
68
 
69
 
70
 
71
 
72
// use little endian
73
 
74
scARMInstruction* scID::create_instru(uint32_t i)
75
{
76
  scARMInstruction* p;
77
  if((i&BRANCH_MASK)==BRANCH_SIG) p=new scB(i);
78
  else if((i & DP1_MASK) == DP1_SIG) p=new scDP1(i);
79
  else if((i & DP2_MASK) == DP2_SIG) p=new scDP2(i);
80
  else if((i & DP3_MASK) == DP3_SIG) p=new scDP3(i);
81
  else if((i & SWT1_MASK) == SWT1_SIG) p=new scSW1(i);
82
  else if((i & SWT2_MASK) == SWT2_SIG) p=new scSW2(i);
83
 
84
  else if((i & SWI_MASK)  == SWI_SIG) {  p=new scSWI(i);}
85
 
86
  else if((i & HWT_MASK)  == HWT_SIG)  p=new scHWT(i);
87
  else if((i & SWP_MASK)  == SWP_SIG)  p=new scSWP(i);
88
  else if((i & MULT_MASK)  == MULT_SIG)  p=new scMult(i);
89
  else if((i & MRT_MASK)  == MRT_SIG)  p=new scMRT(i);
90
  else if((i & MRS_MASK)  == MRS_SIG)  p=new scMRS(i);
91
  else if((i & CDT_MASK)  == CDT_SIG)  p=new scCD(i);
92
  else if((i & CRT_MASK)  == CRT_SIG)  p=new scCR(i);
93
  else if((i & CDP_MASK)  == CDP_SIG)  p=new scCDP(i);
94
  else if((i & NOP_MASK)  == NOP_SIG)  p=new scNOOP(i);
95
  else
96
          p=new scUNDEF(i);
97
 
98
 
99
  return p;
100
}
101
 
102
 
103
void scID::display()
104
{
105
          s_is_mrt=m_b_is_mrt;
106
         s_reg_in_list=m_reg_in_list-1;
107
  s_b_flush_debug=save_flush;
108
  if(s_b_flush_debug==1)
109
  {
110
          flush_number=2;
111
          s_b_flush_debug=0;
112
  }
113
  s_pc_debug=m_last_pc;
114
  s_ir_debug=m_last_ir;
115
  uint32_t temp=s_ir_debug;
116
  s_A_debug=m_A;
117
  s_dist_debug=m_Dist;
118
  s_B_debug=m_B;
119
 
120
  if(flush_number==0)
121
  {
122
 
123
  cout<<s_pc_debug<<":"<<s_ir_debug<<" ";
124
 
125
  scARMInstruction* j=create_instru(temp);
126
 
127
  if(((j->kind())=="DP1")||((j->kind())=="DP2")||((j->kind())=="DP3"))
128
  {
129
   switch(j->op())
130
   {
131
      case 0:  cout<<"AND"; break;     case 1:  cout<<"EOR"; break;
132
      case 2:  cout<<"SUB"; break;     case 3:  cout<<"RSB"; break;
133
      case 4:  cout<<"ADD"; break;     case 5:  cout<<"ADC"; break;
134
      case 6:  cout<<"SBC"; break;     case 7:  cout<<"RSC"; break;
135
      case 8:  cout<<"TST"; break;     case 9:  cout<<"TEQ"; break;
136
      case 10:  cout<<"CMP"; break;     case 11:  cout<<"CMN"; break;
137
      case 12:  cout<<"ORR"; break;     case 13:  cout<<"MOV"; break;
138
      case 14:  cout<<"BIC"; break;     case 15:  cout<<"MVN"; break;
139
      default: cout<<"unknow op"<<endl;
140
   }
141
  }
142
  else  cout<<j->kind();
143
 
144
  switch(j->cond())
145
  {
146
        case 0x0: cout<<"eq";break;  case 0x1:cout<<"ne";break;
147
        case 0x2: cout<<"cs";break;  case 0x3:cout<<"cc";break;
148
        case 0x4: cout<<"mi";break;  case 0x5:cout<<"pl";break;
149
        case 0x6: cout<<"vs";break;  case 0x7:cout<<"vc";break;
150
        case 0x8: cout<<"hi";break;  case 0x9:cout<<"ls";break;
151
        case 0xa: cout<<"ge";break;  case 0xb:cout<<"lt";break;
152
        case 0xc: cout<<"gt";break;  case 0xd:cout<<"le";break;
153
        case 0xe: cout<<"al";break;  case 0xf:cout<<"nv";break;
154
    default: cout<<"unknow condition"<<endl;
155
  }
156
 
157
  if(j->Rd()==R_PC)
158
          {
159
                  cout<<" pc";
160
 }else{
161
                  if(s_is_mrt){
162
                          cout<<" r"<<s_reg_in_list;
163
                  }else
164
           cout<<" r"<<(j->Rd());
165
  }
166
 
167
 
168
                   cout<<",[";
169
 
170
   if(j->A()==R_PC)
171
   {
172
      cout<<"pc ="<<hex<<(s_pc_debug+8)<<",";
173
   }else
174
 
175
     cout<<"r"<<(j->A())<<"="<<hex<<s_A_debug<<",";
176
 
177
 
178
   if(j->is_imm())      cout<<"#0x";  else  cout<<"r"<<hex<<(j->B())<<"=";
179
 
180
 
181
   cout<<hex<<s_B_debug;
182
 
183
   if(j->is_shift()){
184
 
185
           cout<<" shift "<<s_dist_debug;
186
   }
187
 
188
   cout<<"] "<<endl;
189
   delete j;
190
  }else
191
  {
192
        flush_number--;
193
 
194
    //cout<<"flush";
195
  }
196
 
197
}
198
 
199
void scID::regs()
200
{
201
 
202
        uint32_t R=0;
203
         cout<<"        ";
204
                for(int i=0;i<15;i++)
205
                {
206
 
207
                     //out_b_RW=0;
208
                     out_REG=REGS(i);
209
                     R=inout_n_Data;
210
                         cout<<"r"<<i<<"="<<R<<" ";
211
                         if((i==4)||(i==9)) cout<<endl<<"       ";
212
                }
213
                cout<<endl;
214
}
215
 
216
void scID::delay1()
217
{
218
        next_trigger(trigger1   );
219
 
220
        trigger2.notify(SC_ZERO_TIME);
221
}
222
 
223
void scID::delay2()
224
{
225
  next_trigger(trigger2);
226
          scARMInstruction* i;
227
 if(in_b_hold==0){
228
 
229
          i=create_instru(m_ir);
230
          m_last_ir=m_ir;
231
          m_last_pc=m_pc;
232
  }else
233
  {
234
          i=create_instru(m_last_ir);
235
        //        cout<<"m_last_ir="<<m_last_ir<<endl;
236
 
237
  }
238
 
239
  //i=create_instru(m_ir);
240
  m_b_predict=predict();
241
  m_COND=i->cond();
242
  m_b_S=i->is_shift();
243
  m_b_ls=i->is_ls();
244
  m_Rn=i->Rn();
245
  m_Rd=i->Rd();
246
  m_b_Pre=i->pre();
247
  m_b_up=i->up();
248
  m_b_is_mrt=i->is_mrt();
249
  m_b_Load=i->load();
250
  m_b_WB=i->wb();
251
  m_SET=i->set();
252
  m_OP=i->op();
253
  m_SHIFT_TYPE=i->shift_type();
254
  if(m_b_is_mrt&&m_b_ls)
255
  {
256
 
257
     m_Dist=0;
258
         m_n_list=i->dist();
259
         for(int i=0;i<=15;i++)
260
         {
261
           if((m_n_list&(0x1<<i))==(0x1<<i))
262
           {
263
               m_index++;
264
 
265
           }
266
         }
267
 
268
         for(m_reg_in_list;m_reg_in_list<=15;m_reg_in_list++)
269
         {
270
                if((m_n_list&(0x1<<m_reg_in_list))==(0x1<<m_reg_in_list))
271
                {
272
                m_Rd=REGS(m_reg_in_list);
273
                        m_order++;
274
                        //cout<<"order="<<m_order<<endl;
275
                        m_reg_in_list++;
276
 
277
                        break;
278
                }
279
 
280
         }
281
         if(m_reg_in_list>15){
282
            m_b_is_mrt=0;
283
         }
284
         if(m_reg_in_list>15)
285
         {
286
            m_reg_in_list=0;
287
                m_order=0;
288
                        m_index=0;
289
         }
290
 
291
 
292
  }else
293
  {
294
     m_Dist=i->dist();
295
        m_Rd=i->Rd();
296
                        m_order=0;
297
                        m_index=0;
298
  }
299
  m_b_M=i->is_mult();
300
  if(m_Rd==R_PC){
301
        //m_b_flush=i->is_branch();
302
        m_b_flush=1;
303
  }else
304
  {
305
   m_b_flush=0;
306
  }
307
 
308
  m_A=i->A();
309
  m_B=i->B();
310
  m_Rm=REGS(i->B());
311
  m_Rs=REGS(i->dist());
312
  is_Rm=(i->is_imm())?0:1;
313
  m_b_is_Rm=!(i->is_imm());
314
  m_b_is_Rs=i->is_rs();
315
 
316
  m_b_interrupt=0;
317
 
318
 delete i;
319
trigger2_1.notify(SC_ZERO_TIME);
320
 
321
}
322
 
323
void scID::delay3()
324
{
325
         next_trigger(trigger3);
326
 
327
     if((save_flush==0)&&(in_b_flush_2==0))
328
        {
329
    out_n_A=m_A;
330
        out_n_B=m_B;
331
        //cout<<"A"<<m_A<<"B="<<m_B<<endl;
332
        //shift
333
        out_b_S=m_b_S;
334
 
335
        //cout<<endl<<(m_b_S?"shitf":"dont shift");
336
        out_n_Dist=m_Dist;
337
        //cout<<"ID; a="<<m_A<<" b="<<m_B<<" shift="<<m_Dist<<endl;
338
        out_SHIFT_TYPE=m_SHIFT_TYPE;
339
        //base and target
340
        out_Rn=m_Rn;
341
        out_Rd=m_Rd;
342
        //operator
343
        out_OP=m_OP;
344
    out_COND=m_COND;
345
    out_branch_taken=m_b_predict;
346
        out_b_flush=m_b_flush;
347
        out_b_ls=m_b_ls;
348
        out_b_Pre=m_b_Pre;
349
        out_b_Load=m_b_Load;
350
        out_b_WB=m_b_WB;
351
        //cout<<"WB?"<<(m_b_WB?"yes":"no")<<endl;
352
        out_SET=m_SET;
353
    out_Rm=m_Rm;
354
        out_Rs=m_Rs;
355
        out_interrupt=m_b_interrupt;
356
 
357
    is_Rm=m_b_is_Rm;
358
        is_Rs=m_b_is_Rs;
359
        out_b_is_mrt=m_b_is_mrt;
360
 
361
        }else
362
        {
363
       out_b_is_mrt=0;
364
        out_n_A=0;
365
        out_n_B=0;
366
        out_n_Dist=0;
367
        out_Rn=R_R0;
368
        out_Rd=R_R0;
369
        out_OP=OP_CMP;
370
    out_COND=C_NV;
371
        out_SHIFT_TYPE=SHIFT(0);
372
        out_b_flush=0;
373
        out_b_ls=0;
374
        out_b_Pre=0;
375
        out_b_Load=0;
376
        out_b_WB=0;
377
        out_SET=0;
378
        out_b_S=0;
379
        is_Rm=0;
380
        is_Rs=0;
381
        out_branch_taken=0;
382
        out_interrupt=0;
383
        }
384
   save_flush=m_b_flush;
385
}
386
 
387
void scID::delay0()
388
{
389
        next_trigger(trigger0);
390
 
391
 
392
        trigger0_1.notify(SC_ZERO_TIME);
393
}
394
 
395
void scID::delay0_1()
396
{
397
        next_trigger(trigger0_1);
398
 
399
        trigger1.notify(SC_ZERO_TIME);
400
}
401
 
402
bool scID::predict()
403
{
404
  return 1;
405
}
406
 
407
void scID::delay2_1()
408
{
409
        next_trigger(trigger2_1);
410
 
411
 
412
    //read A
413
  if(m_b_flush)
414
  {
415
          //
416
        //out_b_RW=0;
417
          //don't care, this value will be changed because of forwarding
418
        //out_REG=R_PC;
419
        //m_A=inout_n_Data;
420
        //cout<<"current pc="<<m_A<<endl;
421
        m_A=in_n_PC+8;
422
        m_b_flush=1;
423
 
424
  }else
425
  {
426
 
427
        //out_b_RW=0;
428
         if(m_b_is_mrt==0)
429
         {
430
                out_REG=REGS(m_A);
431
                m_A=inout_n_Data;
432
         }else
433
         {
434
                 //base
435
                        out_REG=REGS(m_A);
436
                        m_A=inout_n_Data;
437
                 //
438
            if((m_b_Pre==0)&&(m_b_up==1))
439
                {
440
              m_A=m_A+(m_order-1)*4;
441
 
442
                }else if((m_b_Pre==1)&&(m_b_up==1))
443
                {
444
                        m_A=m_A+(m_order-1+1)*4;
445
 
446
                }else if((m_b_Pre==0)&&(m_b_up==0))
447
                {
448
 
449
                        m_A=m_A-m_index*4+(m_order-1)*4;
450
                }
451
                else if((m_b_Pre==1)&&(m_b_up==0))
452
                {
453
                   m_A=m_A-(m_index+1)*4+(m_order-1)*4;
454
                }
455
         }
456
        //don't flush 
457
        m_b_flush=0;
458
 
459
  }
460
    if(m_b_is_Rm!=1)
461
  {
462
 
463
        m_B=m_B;
464
  }else
465
  {
466
    //out_b_RW=0;
467
        out_REG=REGS(m_B);
468
        m_B=inout_n_Data;
469
 
470
  }
471
     //RS or imm shift
472
  if(!(m_b_is_Rs))
473
  {
474
 
475
 
476
  }
477
  else
478
  {
479
        //out_b_RW=0;
480
    out_REG=REGS(m_Dist);
481
        m_Dist=inout_n_Data;
482
 
483
 
484
  }
485
    if(m_b_ls)
486
  {
487
                 if(!(m_b_Load))
488
                 {
489
                         //out_b_RW=0;
490
                         out_REG=m_Rd;
491
                         //when is store, use out_b_Dist transfer data
492
             m_Dist=inout_n_Data;
493
                         m_b_is_Rs=false;
494
                 }
495
 
496
 
497
  }
498
 
499
        #if defined(DEBUG)
500
 
501
   display();
502
   //regs();
503
        //out_REG=REGS(15);
504
        //uint32_t temp=inout_n_Data;
505
        //cout<<"pc:="<<temp<<endl;
506
#endif
507
 
508
   trigger3.notify(SC_ZERO_TIME);
509
}

powered by: WebSVN 2.1.0

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