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

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

1) compatible gcc 4.4.3
2) Translation file in MORPHEO_PREFIX directory

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