source: trunk/IPs/systemC/shared/soclib_segment_table.h @ 140

Last change on this file since 140 was 138, checked in by rosiere, 14 years ago

1) add counters_t type for interface
2) fix in check load in load_store_unit
3) add parameters (but not yet implemented)
4) change environment and add script (distcc_env.sh ...)
5) add warning if an unser change rename flag with l.mtspr instruction
6) ...

  • Property svn:keywords set to Id
File size: 19.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////
2// File : soclib_segment_table.h
3// Date : 08/07/2004
4// authors : François Pécheux & Alain Greiner
5//
6// Copyright : UPMC - LIP6
7// This program is released under the GNU public license
8//
9// This object is used to describe the memory mapping and address
10// decoding scheme. It supports a two level hierarchical interconnect :
11// All VCI initiators and VCI targets share the same address space.
12// - Several sub-systems can be interconnected thanks to a VCI ADVANCED
13// global interconnect that can be either a micro-network, or a global system bus.
14// - Each sub-system can contain as many targets as the LSB size allows.
15// They are connected by a VCI ADVANCED local interconnect, that can be
16// a local bus, or a VCI to VCI bridge such as the TARGET_DEMUX
17// and INITIATOR_MUX components of the SoCLib library.
18//
19// The VCI ADDRESS is structured as follows (three fields): | MSB | LSB | OFFSET |
20// The MSB bits of the VCI ADDRESS are decoded by the global interconnect
21// to route a VCI CMD/RSP packet to a given sub-system.
22// In each sub-system, the LSB bits of the VCI ADDRESS are decoded by the
23// local interconnect to route the a VCI CMD/RSP packet to the selected target/initiator.
24//
25// If the number of bits of the LSB field is zero, a global "flat" interconnect
26// is used, and both the VCI target index and the VCI initiator index are coded
27// on 8 bits.
28//
29// The segment table is an associative table that is organized as a
30// list of segments. This table must be built in the system top cell.
31//
32// Each segment descriptor contains the following fields:
33//
34// - const char         *name     : segment name
35// - unsigned int       base      : base address
36// - unsigned int       size      : segment size (in bytes)
37// - unsigned int       globalindex     : VCI subsystem index
38// - unsigned int       localindex      : VCI target index in the subsystem
39// - bool               uncached  : uncached when true
40//
41// The constraints on the memory mapping are the following :
42//
43// 1/ The system designer must define the number of bits for the address
44// MSB and LSB fields. Both numbers can be zero. (For example the number
45// of LSB bits will be zero, in case of a "flat" VCI interconnect).
46//
47// 2/ The (MSB | LSB) bits are indexing a "page" in the address space.
48// Several pages can be mapped to the same VCI target.
49//
50// 3/ A segment is allocated to a VCI target, and must be contained in
51// a single page or in several contiguous pages.
52//
53// 4/ Several segments can be mapped to the same VCI target
54// (thanks to the SOCLIB_VCI_MULTIRAM component)
55//
56// 5/ A given page cannot contain two segments that are not
57// mapped to the same VCI target.
58//
59// The segment table is used by most SoCLib  components :
60//
61// - The constructors of the VCI interconnect components can use it to build
62// the ROMs implementing the routing tables
63// - The constructors of all VCI targets use it to implement the segmentation
64// violation detection mechanism, and allocate the buffers representing
65// the memory in case of an embedded memory component.
66// - The constructors of several processors (MIPS, SPARC) use it to build
67// the ROM implementing the uncached table.
68///////////////////////////////////////////////////////////////////////////
69
70#ifndef SEGMENT_TABLE_H
71#define SEGMENT_TABLE_H
72
73#include <list>
74#include <iostream>
75// using namespace std;
76
77//////////////////////////////////////////////
78//      SEGMENT_TABLE_ENTRY definition
79//////////////////////////////////////////////
80
81struct SEGMENT_TABLE_ENTRY
82{
83
84private:
85
86  const char            *name;
87  unsigned int          base;
88  unsigned int          size;
89  unsigned int          globalTarget;
90  unsigned int          localTarget;
91  bool                  uncached ;
92  //-----[ SIM2OS - begin ]-----------------------------------------
93  void *                addr_alloc;
94  //-----[ SIM2OS - end   ]-----------------------------------------
95
96public:
97
98// constructor
99
100SEGMENT_TABLE_ENTRY(const char *nm ,
101                    unsigned int ba , 
102                    unsigned int sz ,
103                    unsigned int glt,
104                    unsigned int lct,
105                    bool unc
106                    )
107        {
108        name=nm;
109        base=ba;
110        size=sz;
111        globalTarget=glt;
112        localTarget=lct;
113        uncached=unc;
114  //-----[ SIM2OS - begin ]-----------------------------------------
115        addr_alloc = (void *) 0;
116  //-----[ SIM2OS - end   ]-----------------------------------------
117        }; // end constructor
118
119// basic methods
120
121void print()
122        { 
123        printf("  * [%s]\n", name);
124        printf("    * base = %.8x, size = %.8x, Global target = %d, Local Target = %d, unc = %d, addr_alloc : %.8x\n",
125               base,
126               size,
127               globalTarget,
128               localTarget,
129               uncached,
130               (unsigned int)((long long)addr_alloc));
131
132        };
133
134const char *getName()
135        {
136        return name;
137        };
138
139unsigned int getBase()
140        {
141        return base;
142        };
143
144unsigned int getSize()
145        {
146        return size;
147        };
148
149unsigned int getGlobalTarget()
150        {
151        return globalTarget;
152        };
153       
154unsigned int getLocalTarget()
155        {
156        return localTarget;
157        };
158
159bool getUncached()
160        {
161        return uncached;
162        };
163
164  //-----[ SIM2OS - begin ]-----------------------------------------
165  void * getAddrAlloc()
166  {
167    return addr_alloc;
168  }
169
170  void setAddrAlloc (void * addr)
171  {
172    addr_alloc = addr;
173  }
174  //-----[ SIM2OS - end   ]-----------------------------------------
175
176  };// end struct SEGMENT_TABLE_ENTRY
177
178
179//////////////////////////////////////////////////////////
180//      SegmentTable definition
181//////////////////////////////////////////////////////////
182
183// using namespace std;
184
185struct SOCLIB_SEGMENT_TABLE {
186       
187private :
188
189std::list<SEGMENT_TABLE_ENTRY>  segList;
190int                             MSBNumber;
191int                             LSBNumber;
192unsigned int                    defaultTargetGlobalIndex;
193unsigned int                    defaultTargetLocalIndex;
194bool                            MSBNumberCalled;
195bool                            defaultTargetCalled;
196bool                            LSBNumberCalled;
197
198public :       
199
200//      CONSTRUCTOR
201
202SOCLIB_SEGMENT_TABLE()
203        {
204        MSBNumberCalled=false;
205        LSBNumberCalled=false;
206        defaultTargetCalled=false;
207        };  // end constructor
208
209//      BASIC METHODS
210
211void setMSBNumber (int number) 
212        {
213        if ((number<0)||(number>16))
214                {
215                std::cerr << "ERROR in the Segment Table :" << std::endl ;
216                std::cerr << "MSB number must be in the [0..16] range !" << std::endl ;
217                //sc_stop();
218                }
219                MSBNumberCalled=true;
220                MSBNumber=number;
221        };
222
223void setLSBNumber (int number) 
224        {
225        if ((number<0)||(number>16))
226                {
227                std::cerr << "ERROR in the Segment Table :" << std::endl ;
228                std::cerr << "LSB number must be in the [0..16] range !" << std::endl ;
229                //sc_stop();
230                }
231                LSBNumberCalled=true;           
232                LSBNumber=number;
233        };
234
235int getMSBNumber()
236        {
237        return MSBNumber;
238        };
239
240int getLSBNumber()
241        {
242        return LSBNumber;
243        };
244
245void setDefaultTarget (int _defTargetGlobalIndex , int _defTargetLocalIndex)
246        {
247                defaultTargetCalled=true;
248        defaultTargetGlobalIndex=_defTargetGlobalIndex;
249        defaultTargetLocalIndex=_defTargetLocalIndex;
250        };
251
252int getdefaultTargetGlobalIndex()
253        {
254        return defaultTargetGlobalIndex;
255        };
256       
257int getdefaultTargetLocalIndex()
258                {
259                return defaultTargetLocalIndex;
260                };     
261
262void addSegment(const char *nm,
263                unsigned int ba,
264                unsigned int sz,
265                unsigned int glt,
266                unsigned int lct,
267                bool unc)
268        {
269        SEGMENT_TABLE_ENTRY *seg=new SEGMENT_TABLE_ENTRY(nm,ba,sz,glt,lct,unc);
270        segList.push_back(*seg);
271        delete seg;
272        };
273
274  //-----[ SIM2OS - begin ]-----------------------------------------
275  void setAddrAlloc(unsigned int ba  ,
276                    void *       addr)
277  {
278    std::list<SEGMENT_TABLE_ENTRY>::iterator segIterator;
279    // Scan of all list
280    for (segIterator = segList.begin() ; segIterator != segList.end() ; ++segIterator) 
281      {
282        // Find a entry match with number of base
283        // NOTE : The memory is shared, also we can't have 2 segment with the same base
284        if (ba == (*segIterator).getBase ())
285          {
286            (*segIterator).setAddrAlloc(addr);
287          }
288      }
289  };
290
291  void * getAddrAlloc(unsigned int addr)
292  {
293    std::list<SEGMENT_TABLE_ENTRY>::iterator segIterator;
294
295    // Scan of all list
296    for (segIterator = segList.begin() ; segIterator != segList.end() ; ++segIterator) 
297      {
298        unsigned int addr_min = (*segIterator).getBase ();
299        unsigned int addr_max = addr_min + (*segIterator).getSize ();
300       
301        if ((addr >= addr_min) && (addr <= addr_max))
302          {
303            unsigned int offset = (addr-addr_min);
304            return (void*)((unsigned int)(long long)((*segIterator).getAddrAlloc()) + offset);
305          }
306      }
307    return NULL;
308  }
309  //-----[ SIM2OS - end   ]-----------------------------------------
310
311void print()
312        {
313          std::cout << "{SEGMENT_TABLE}"<< std::endl;
314          std::list<SEGMENT_TABLE_ENTRY>::iterator iter;
315          for (iter = segList.begin() ; iter != segList.end() ; ++iter)
316            {
317              (*iter).print();
318            }
319          std::cout << std::endl;
320        }
321
322void printMSBRoutingTable()
323        {
324          std::cout << "\n                 MSB ROUTING_TABLE\n\n" ;
325          int size = 1 << MSBNumber+LSBNumber;
326          unsigned int  *tab = new unsigned int[size];
327          initRoutingTable(tab);
328          for(int index = 0 ; index < size ; index++) {
329            if (tab[index]!=0xFFFFFFFF){
330              printf("TAB[%x] = %d\n", index, tab[index]);
331            }
332          }
333          std::cout << "\n" ;
334        };
335 
336  void printLSBRoutingTable(int glt)
337  {
338    printf( "\n    LSB_ROUTING_TABLE OF GLOBAL TARGET :%d \n\n", glt );
339    int size = 1 << MSBNumber+LSBNumber;
340    unsigned int        *tab = new unsigned int[size];
341    initLocalRoutingTable(tab,glt);
342    for(int index = 0 ; index < size ; index++) {
343      if (tab[index]!=0xFFFFFFFF){
344        printf("TAB[%d] = %d\n", index, tab[index]);
345      }
346    }
347    std::cout << "\n" ;
348  };
349       
350
351
352void initRoutingTable(unsigned int* tab) {
353        if (MSBNumberCalled==false) {
354                std::cerr << "ERROR in initMSBRoutingTable:" << std::endl ;
355                std::cerr << "MSB number has not been defined !" << std::endl ;
356                //sc_stop();
357        }
358        if (LSBNumberCalled==false) {
359          std::cout << "WARNING in initMSBRoutingTable:" << std::endl ;
360          std::cout << "LSB number has not been defined !" << std::endl ;
361          std::cout << "it is set to 0" << std::endl ;
362          LSBNumberCalled=true;
363          LSBNumber=0;
364        }
365       
366       
367        if (defaultTargetCalled==false) {
368                std::cerr << "ERROR in initMSBRoutingTable:" << std::endl ;
369                std::cerr << "Default Target has not been defined!" << std::endl ;
370                //sc_stop();
371        }
372
373        int RoutingTableSize = 1 << MSBNumber+LSBNumber;
374        int PageSize         = 1 << (32 - MSBNumber - LSBNumber);
375       
376        // The 0xFFFFFFFF value means "not allocated"
377        for (int i=0 ; i < RoutingTableSize ; i++) {
378                tab[i] = 0xFFFFFFFF;
379        }
380//              printf ( " tableau rempli de 0xFFFFFFFF \n");
381
382        // loop on the segment list
383        std::list<SEGMENT_TABLE_ENTRY>::iterator seg;
384        for (seg = segList.begin() ; seg != segList.end() ; ++seg) {
385                const char    *name   = (*seg).getName();
386                unsigned int  base    = (*seg).getBase();
387                unsigned int  size    = (*seg).getSize();
388                unsigned int globalTarget  = (*seg).getGlobalTarget();
389
390                unsigned int page = base >> (32-MSBNumber - LSBNumber) ;
391               
392                for (int x = (int) size ; x > 0 ; x = x - PageSize) {               
393                        if(tab[page] != 0xFFFFFFFF) {
394                //              printf("\n page n° %x can not be added to cluster %x because it is already allocated to %x\n",page,globalTarget,tab[page]);
395                                std::cerr << "Error in initMSBRoutingTable:" << std::endl ;
396                                std::cerr << "Segment " << name << " allocated to VCI target " << globalTarget << std::endl;
397                                std::cerr << "overlap another segment... or is in the same page" << std::endl;
398                                std::cerr << "as another segment allocated to another VCI target" << std::endl;
399                                //sc_stop();
400                        } else {
401                                tab[page]=globalTarget;
402                               
403                //              printf("\n page n° %x allocated to cluster °%x i.e %s \n",page,tab[page],name);
404                                }
405                        page = page + 1;
406                        } // end for x
407        } // end for seg
408       
409        // Default target
410        for (int i=0 ; i < RoutingTableSize ; i++) {
411                if(tab[i] == 0xFFFFFFFF) tab[i] = defaultTargetGlobalIndex;
412        }
413       
414};  // end initRoutingTable()
415
416////////////////////////////////////////////////////////////////
417//              initGlobalRoutingTable()
418//      This method can be used by any global VCI interconnect.
419//      It initializes the routing table that implements
420//      the VCI address MSB bits decoding ROM.
421//      - The argument is a pointer to the int table that
422//      has been allocated by the constructor of the
423//      VCI interconnect component.
424//      - Each entry contains a VCI target global index.
425//      The VCI local Target index is not used here
426////////////////////////////////////////////////////////////////
427
428
429void initGlobalRoutingTable(unsigned int* tab) {
430        if (MSBNumberCalled==false) {
431                std::cerr << "ERROR in initMSBRoutingTable:" << std::endl ;
432                std::cerr << "MSB number has not been defined !" << std::endl ;
433                //sc_stop();
434        }
435       
436        if (defaultTargetCalled==false) {
437                std::cerr << "ERROR in initMSBRoutingTable:" << std::endl ;
438                std::cerr << "Default Target has not been defined!" << std::endl ;
439                //sc_stop();
440        }
441
442        int RoutingTableSize = 1 << MSBNumber;
443        int PageSize         = 1 << (32 - MSBNumber);
444       
445        // The 0xFFFFFFFF value means "not allocated"
446        for (int i=0 ; i < RoutingTableSize ; i++) {
447                tab[i] = 0xFFFFFFFF;
448        }
449//              printf ( " tableau rempli de 0xFFFFFFFF \n");
450
451        // loop on the segment list
452        std::list<SEGMENT_TABLE_ENTRY>::iterator seg;
453        for (seg = segList.begin() ; seg != segList.end() ; ++seg) {
454                const char    *name   = (*seg).getName();
455                unsigned int  base    = (*seg).getBase();
456                unsigned int  size    = (*seg).getSize();
457                unsigned int globalTarget  = (*seg).getGlobalTarget();
458
459                unsigned int page = base >> (32-MSBNumber) ;
460               
461                for (int x = (int) size ; x > 0 ; x = x - PageSize) {               
462                        if(tab[page] != 0xFFFFFFFF) {
463                //              printf("\n page n° %x can not be added to cluster %x because it is already allocated to %x\n",page,globalTarget,tab[page]);
464                                std::cerr << "Error in initGlobalRoutingTable:" << std::endl ;
465                                std::cerr << "Segment " << name << " allocated to VCI target " << globalTarget << std::endl;
466                                std::cerr << "overlap another segment... or is in the same page" << std::endl;
467                                std::cerr << "as another segment allocated to another VCI target" << std::endl;
468                                //sc_stop();
469                        } else {
470                                tab[page]=globalTarget;
471                               
472                //              printf("\n page n° %x allocated to cluster °%x i.e %s \n",page,tab[page],name);
473                                }
474                        page = page + 1;
475                        } // end for x
476        } // end for seg
477       
478        // Default target
479        for (int i=0 ; i < RoutingTableSize ; i++) {
480                if(tab[i] == 0xFFFFFFFF) tab[i] = defaultTargetGlobalIndex;
481        }
482       
483};  // end initGlobalRoutingTable()
484
485
486////////////////////////////////////////////////////////////////
487//              initLocalRoutingTable()
488//      This method can be used by the local VCI interconnect.
489//      It initializes the routing table that implements
490//      the VCI address LSB bits decoding ROM.
491//      - The argument is a pointer to the char table that
492//      has been allocated by the constructor of the local
493//      VCI interconnect component.
494//      - Each entry contains a VCI target local index as well as a global index .
495//      - This method needs a parameter : the global index of the subsystem ,
496//      because it only fills the pages corresponding to a segment in this subsystem
497//      other pages are adressed to the Default Target
498////////////////////////////////////////////////////////////////
499
500void initLocalRoutingTable(unsigned int* tab, unsigned int cluster) {
501        if (MSBNumberCalled==false) {
502                std::cerr << "ERROR in initLocalRoutingTable:" << std::endl ;
503                std::cerr << "MSB number has not been defined !" << std::endl ;
504                //sc_stop();
505        }
506               
507        if (defaultTargetCalled==false) {
508                std::cerr << "ERROR in initLocalRoutingTable:" << std::endl ;
509                std::cerr << "Default Target has not been defined!" << std::endl ;
510                //sc_stop();
511        }
512
513        int RoutingTableSize = 1 << MSBNumber+LSBNumber;
514        int PageSize         = 1 << (32 - MSBNumber - LSBNumber );
515       
516        // The 0xFF value means "not allocated"
517        for (int i=0 ; i < RoutingTableSize ; i++) {
518                tab[i] = 0xFF;
519        }
520        // printf ( " Local routing table cluster %x: tableau rempli de 0xFF \n",cluster);
521        // loop on the segment list
522        std::list<SEGMENT_TABLE_ENTRY>::iterator seg;
523        for (seg = segList.begin() ; seg != segList.end() ; ++seg) {
524                const char    *name   = (*seg).getName();
525                unsigned int  base    = (*seg).getBase();
526                unsigned int  size    = (*seg).getSize();
527                unsigned int localTarget  = (*seg).getLocalTarget();
528                unsigned int globalTarget = (*seg).getGlobalTarget();
529
530                unsigned int page = base >> (32 - MSBNumber - LSBNumber) ;
531               
532                for (int x = (int) size ; x > 0 ; x = x - PageSize) {               
533                          if(tab[page] != 0xFF) {
534                          // printf("\n page n° %x ne peut etre adressée à target n°%x car elle est allouée à %x \n",page,localTarget,tab[page]);       
535                          std::cerr << "Error in initLocalRoutingTable:" << std::endl ;
536                          std::cerr << "Segment " << name << " allocated to VCI target " << localTarget << std::endl;
537                          std::cerr << "overlap another segment... or is in the same page" << std::endl;
538                          std::cerr << "as another segment allocated to another VCI target" << std::endl;
539                          //sc_stop();
540                          } else {
541                                if (globalTarget==cluster){
542                                        tab[page] = localTarget;
543                                        // printf(" page n° %x adressée à target n°%x dans cluster %x i.e %s \n",page,tab[page],cluster,name);
544                                  }
545                          page = page + 1;
546                         
547                          }
548                } 
549        } // end loop segment list
550
551        for (int i=0 ; i < RoutingTableSize ; i++) {
552                if ((tab[i]==0xFF) && (defaultTargetGlobalIndex==cluster))
553                        tab[i]=defaultTargetLocalIndex;
554        }
555               
556};  // end initLocalRoutingTable()
557
558//////////////////////////////////////////////////////////////
559//              getSegmentList()
560//      returns the list of all segments
561//      allocated to a given VCI target.
562//      This method tests both the local and global VCI target index
563//////////////////////////////////////////////////////////////
564
565std::list<SEGMENT_TABLE_ENTRY> getSegmentList(unsigned int globalIndex,unsigned int localIndex){
566        std::list<SEGMENT_TABLE_ENTRY> targetlist;
567        std::list<SEGMENT_TABLE_ENTRY>::iterator segIterator;
568        unsigned int localTarget;
569        unsigned int globalTarget;
570       
571        for (segIterator = segList.begin() ; segIterator != segList.end() ; ++segIterator) {
572                localTarget=(*segIterator).getLocalTarget();
573                globalTarget=(*segIterator).getGlobalTarget();
574                if ((localTarget==localIndex)&&(globalTarget==globalIndex)){
575                        targetlist.push_back(*segIterator);
576                }
577        }
578        return(targetlist);
579       
580}; // end getSegmentList()
581
582////////////////////////////////////////////////////
583// function getTotalsegmentList
584// used to get the whole segmentlist
585///////////////////////////////////////////////////
586
587std::list<SEGMENT_TABLE_ENTRY> getTotalSegmentList()
588{
589
590return(segList);
591
592}; // end getSegmentList()
593
594////////////////////////////////////////////////////////////////
595//              initUncachedTable()
596//      This method can be used by any SoCLib processor.
597//      It initializes an "Uncached Table" that implements
598//      the address MSB bits decoding ROM.
599//      - The argument is a pointer to the bool table that
600//      has been allocated by the constructor of the processor.
601//      - Each ROM entry contains a boolean that is true when
602//      the adress Ris to an uncached segment.
603///////////////////////////////////////////////////////////////:
604
605void initUncachedTable(bool* tab) {
606        if ((MSBNumberCalled==false)||(LSBNumberCalled==false))
607                {
608                std::cerr << "ERROR in initUncachedTable:" << std::endl ;
609                std::cerr << "MSB or LSB number has not been defined !" << std::endl ;
610                //sc_stop();
611                }
612
613        int UncachedTableSize  = 1 << (MSBNumber+LSBNumber);
614        int PageSize           = 1 << (32 - (MSBNumber + LSBNumber));
615       
616        for (int i=0 ; i < UncachedTableSize ; i++) 
617                {
618                tab[i] = true;
619                }
620
621        std::list<SEGMENT_TABLE_ENTRY>::iterator iter;
622
623        for (   iter = segList.begin() ; 
624                iter != segList.end() ; 
625                ++iter)
626                {
627                unsigned int  base      = (*iter).getBase();
628                unsigned int  size      = (*iter).getSize();
629                bool          uncached  = (*iter).getUncached();
630
631                unsigned int page_index = base >> (32-((MSBNumber + LSBNumber))) ;
632
633                for (int x = (int) size ; x > 0 ; x = x - PageSize) 
634                        {                   
635                        tab[page_index] = uncached;
636                        page_index = page_index + 1;
637                        } 
638                } // end for segment list
639};  // end initUncachedTable()
640
641};  // end struct SOCLIB_SEGMENT_TABLE
642
643
644#endif
Note: See TracBrowser for help on using the repository browser.