source: trunk/IPs/systemC/hierarchy_memory/hierarchy_memory.h @ 2

Last change on this file since 2 was 2, checked in by kane, 17 years ago

Import Morpheo

File size: 38.2 KB
Line 
1#ifndef HIERARCHY_MEMORY_H
2#define HIERARCHY_MEMORY_H
3#include <iostream>
4#include <stdint.h>
5#include <stdarg.h>
6
7#include <systemc.h>
8#include "shared/soclib_segment_table.h"
9#include "shared/soclib_caches_interfaces.h"
10
11#include "hierarchy_memory/data/data.h"
12#include "hierarchy_memory/file/sort_file.h"
13#include "hierarchy_memory/file/entry.h"
14#include "hierarchy_memory/cache/cache.h"
15#include "hierarchy_memory/ramlock/ramlock.h"
16#include "hierarchy_memory/tty/tty.h"
17#include "hierarchy_memory/sim2os/sim2os.h"
18
19#include "hierarchy_memory/cache/type_req_cache.h"
20
21using namespace std;
22using namespace hierarchy_memory::data;
23using namespace hierarchy_memory::sort_file;
24using namespace hierarchy_memory::cache;
25using namespace hierarchy_memory::ramlock;
26using namespace hierarchy_memory::tty;
27using namespace hierarchy_memory::sim2os;
28
29namespace hierarchy_memory
30{
31  template <class T>
32  class param_entity_t
33  {
34  public : uint32_t address ;
35  public : uint32_t size    ;
36  public : T        param   ;
37   
38  public : param_entity_t () {};
39
40  public : param_entity_t (uint32_t address ,
41                           uint32_t size    ,
42                           T        param   )
43    {
44      this->address = address ;
45      this->size    = size    ;
46      this->param   = param   ;
47    }
48  };//end param_entity_t
49
50  class param_t
51  {
52  public : uint32_t                            nb_entity_tty;
53  public : param_entity_t <tty::param_t>     * param_tty;
54  public : uint32_t                            nb_entity_ramlock;
55  public : param_entity_t <ramlock::param_t> * param_ramlock;
56  public : param_entity_t <sim2os::param_t>    param_sim2os;
57  public : cache::param_t                      param_cache;
58
59  public : param_t () {};
60
61  public : param_t (uint32_t                            nb_entity_tty     ,
62                    param_entity_t <tty::param_t>     * param_tty         ,
63                    uint32_t                            nb_entity_ramlock ,
64                    param_entity_t <ramlock::param_t> * param_ramlock     ,
65                    param_entity_t <sim2os::param_t>    param_sim2os      ,
66                    cache::param_t                      param_cache)
67    {
68      this->nb_entity_tty     = nb_entity_tty;
69      this->param_tty         = param_tty;
70      this->nb_entity_ramlock = nb_entity_ramlock;
71      this->param_ramlock     = param_ramlock;
72      this->param_sim2os      = param_sim2os;
73      this->param_cache       = param_cache;
74    }
75  };//end param_t
76
77  template<uint32_t SIZE_TRDID    ,
78           uint32_t SIZE_IPKTID   ,
79           uint32_t SIZE_IADDR    ,
80           uint32_t SIZE_IDATA    ,
81           uint32_t NB_IWORD      ,
82           uint32_t SIZE_DPKTID   ,
83           uint32_t SIZE_DADDR    ,
84           uint32_t SIZE_DDATA   
85           >
86
87  class HIERARCHY_MEMORY : sc_module
88  {
89    //---------------------------------------------------------------------------------------------
90    //-----[ PORT ]--------------------------------------------------------------------------------
91    //---------------------------------------------------------------------------------------------
92
93  public : sc_in_clk                                                                        CLK;
94  public : sc_in<bool>                                                                      NRESET;
95  public : ICACHE_CACHE_PORTS<SIZE_TRDID, SIZE_IPKTID, SIZE_IADDR, SIZE_IDATA, NB_IWORD> ** ICACHE;
96  public : DCACHE_CACHE_PORTS<SIZE_TRDID, SIZE_DPKTID, SIZE_DADDR, SIZE_DDATA>           ** DCACHE;
97
98    //---------------------------------------------------------------------------------------------
99    //-----[ INTERNAL SIGNAL ]---------------------------------------------------------------------
100    //---------------------------------------------------------------------------------------------
101  private: bool                                                                          ** irsp_val;
102  private: bool                                                                          ** drsp_val;
103
104  private: bool                                                                          ** ireq_ack;
105  private: bool                                                                          ** dreq_ack;
106   
107    //---------------------------------------------------------------------------------------------
108    //-----[ COMPONENT ]---------------------------------------------------------------------------
109    //---------------------------------------------------------------------------------------------
110  private: Data                                                                           * component_data;
111  private: Sort_File<Entry>                                                              ** component_buffer_irsp;
112  private: Sort_File<Entry>                                                              ** component_buffer_drsp;
113
114  private: Sim2os                                                                         * component_sim2os;
115  private: Tty                                                                           ** component_tty;
116  private: Ramlock                                                                       ** component_ramlock;
117
118  private: Cache                                                                          * component_cache;
119    //---------------------------------------------------------------------------------------------
120    //-----[ VARIABLE ] ---------------------------------------------------------------------------
121    //---------------------------------------------------------------------------------------------
122
123  private: char                                                                           * NAME;                    // instance name
124  private: uint32_t                                                                       * nb_iport;
125  private: uint32_t                                                                       * nb_dport;
126  private: const uint32_t                                                                   nb_context;
127  private: const uint32_t                                                                   nb_entity;
128  private: const uint32_t                                                                   nb_entity_tty;
129  private: const uint32_t                                                                   nb_entity_ramlock;
130
131  private: char **                                                                          read_iram;
132  private: char *                                                                           read_dram;
133  private: char *                                                                           write_dram;
134
135  private: bool                                                                           * context_stop;    // to determine which context have send the signal stop (a same thread can send many signal)
136  private: uint32_t                                                                         nb_context_stop; // stop the simulation when all context have send the stop signal
137    //---------------------------------------------------------------------------------------------
138    //-----[ CONSTRUCTOR ]-------------------------------------------------------------------------
139    //---------------------------------------------------------------------------------------------
140    SC_HAS_PROCESS(HIERARCHY_MEMORY);
141   
142  public : HIERARCHY_MEMORY (// Fixe parameter
143                             sc_module_name              insname               ,
144                             uint32_t                    globalIndex           , // VCI target index
145                             uint32_t                    localIndex            ,
146                             SOCLIB_SEGMENT_TABLE      * segtab                , // segment table pointer
147                             // variable parameter                                 
148                             uint32_t                    nb_entity             ,
149                             uint32_t                    nb_context            ,
150                             //*****[ buffer respons ]*****               
151                             uint32_t                    size_buffer_irsp      ,
152                             uint32_t                    size_buffer_drsp      ,
153                             //*****[ entity_param   ]*****
154                             param_t                     param                                   
155                             ):
156    nb_context        (nb_context             ),
157    nb_entity         (nb_entity              ),
158    nb_entity_tty     (param.nb_entity_tty    ),
159    nb_entity_ramlock (param.nb_entity_ramlock)
160    {
161      uint32_t size_name = strlen(insname)+1;
162      NAME               = new char [size_name];
163      strncpy(NAME,insname,size_name);
164
165      // *****[ Signal creation ]*****
166      ICACHE = new ICACHE_CACHE_PORTS<SIZE_TRDID, SIZE_IPKTID, SIZE_IADDR, SIZE_IDATA, NB_IWORD> * [nb_entity];
167      DCACHE = new DCACHE_CACHE_PORTS<SIZE_TRDID, SIZE_DPKTID, SIZE_DADDR, SIZE_DDATA>           * [nb_entity];
168
169      nb_iport     = new uint32_t     [nb_entity];
170      nb_dport     = new uint32_t     [nb_entity];
171                                     
172      irsp_val     = new bool *       [nb_entity];
173      drsp_val     = new bool *       [nb_entity];
174                                     
175      ireq_ack     = new bool *       [nb_entity];
176      dreq_ack     = new bool *       [nb_entity];
177
178      for (uint32_t it = 0; it < nb_entity; it++)
179        {
180          nb_iport     [it] = param.param_cache.param_icache_dedicated [it].nb_port;
181          nb_dport     [it] = param.param_cache.param_dcache_dedicated [it].nb_port;
182                     
183          irsp_val     [it] = new bool       [nb_iport[it]];
184          drsp_val     [it] = new bool       [nb_dport[it]];
185                     
186          ireq_ack     [it] = new bool       [nb_iport[it]];
187          dreq_ack     [it] = new bool       [nb_dport[it]];
188
189          ICACHE [it] = new ICACHE_CACHE_PORTS<SIZE_TRDID, SIZE_IPKTID, SIZE_IADDR, SIZE_IDATA, NB_IWORD> [nb_iport [it]];
190          DCACHE [it] = new DCACHE_CACHE_PORTS<SIZE_TRDID, SIZE_DPKTID, SIZE_DADDR, SIZE_DDATA>           [nb_dport [it]];
191        }
192
193      read_iram = new char * [NB_IWORD];
194      for (unsigned int num_word = 0; num_word < NB_IWORD; num_word ++)
195        read_iram [num_word] = new char [SIZE_IDATA/8]; 
196
197      read_dram  = new char [SIZE_DDATA/8];
198      write_dram = new char [SIZE_DDATA/8];
199
200      // *****[ Create internal structure ]*****
201
202      component_data        = new Data     (data::param_t("component_data", 16, globalIndex, localIndex, segtab));
203      component_buffer_irsp = new Sort_File<Entry> * [nb_entity];
204      component_buffer_drsp = new Sort_File<Entry> * [nb_entity];
205
206      for (uint32_t it = 0; it < nb_entity; it++)
207        {
208          char name [100];
209          sprintf(name,"component_buffer_irsp[%d]",it);
210          component_buffer_irsp [it] = new Sort_File<Entry> (sort_file::param_t(name,size_buffer_irsp));
211          sprintf(name,"component_buffer_drsp[%d]",it);
212          component_buffer_drsp [it] = new Sort_File<Entry> (sort_file::param_t(name,size_buffer_drsp));
213         
214        }
215
216      component_cache       = new Cache   (param.param_cache);
217      component_tty         = new Tty     * [nb_entity_tty    ];
218      component_ramlock     = new Ramlock * [nb_entity_ramlock];
219
220      for (uint32_t it = 0; it < nb_entity_tty    ; it++)
221        {
222          component_tty     [it] = new Tty     (param.param_tty[it]    .param);
223          entity_t entity = component_data->entity(param.param_tty[it].address,     param.param_tty[it].size);
224         
225          if (entity.present == false)
226            {
227              cerr << "<HIERARCHY_MEMORY> the tty [" << it << "] have not a segment in the segment table" << endl;
228              exit (1);
229            }
230
231          entity.segment->define_target(TYPE_TTY,it);
232        } 
233
234      for (uint32_t it = 0; it < nb_entity_ramlock; it++)
235        {
236          component_ramlock [it] = new Ramlock (param.param_ramlock[it].param);
237          entity_t entity = component_data->entity(param.param_ramlock[it].address, param.param_ramlock[it].size);
238
239          if (entity.present == false)
240            {
241              cerr << "<HIERARCHY_MEMORY> the ramlock [" << it << "] have not a segment in the segment table" << endl;
242              exit (1);
243            }
244
245          entity.segment->define_target(TYPE_RAMLOCK,it);
246        }
247
248      component_sim2os = new Sim2os   (param.param_sim2os.param);
249      entity_t entity  = component_data->entity(param.param_sim2os.address, param.param_sim2os.size);
250
251      if (entity.present == false)
252        {
253          cerr << "<HIERARCHY_MEMORY> the sim2os have not a segment in the segment table" << endl;
254          exit (1);
255        }
256     
257      entity.segment->define_target(TYPE_SIM2OS,0);
258
259      nb_context_stop = 0;
260      context_stop    = new bool [1<<SIZE_TRDID]; // the number of context is include in the REQ_TRDID
261      for (uint32_t num_thread = 0; num_thread < (1<<SIZE_TRDID); num_thread ++)
262        context_stop [num_thread] = false;
263     
264      // *****[ Definition of method ]*****
265      SC_METHOD (transition);
266      sensitive_pos << CLK;
267     
268      SC_METHOD (genMoore);
269      sensitive_neg << CLK;
270
271      cout << "<" << NAME << "> Successful Instanciation" << endl;
272    };
273   
274    //---------------------------------------------------------------------------------------------
275    //-----[ DESTRUCTOR ]--------------------------------------------------------------------------
276    //---------------------------------------------------------------------------------------------
277  public : ~HIERARCHY_MEMORY ()
278    {
279      for (uint32_t it = 0; it < nb_entity_ramlock; it++)
280        delete component_ramlock [it];     
281      for (uint32_t it = 0; it < nb_entity_tty    ; it++)
282        delete component_tty     [it];
283
284      for (uint32_t it = 0; it < nb_entity        ; it++)
285        {
286          delete component_buffer_drsp [it];
287          delete component_buffer_irsp [it];
288        }
289
290      delete component_cache       ;
291      delete component_data        ;
292      delete component_sim2os      ;
293    }
294
295    //---------------------------------------------------------------------------------------------
296    //-----[ req_type2cache_type ]-----------------------------------------------------------------
297    //---------------------------------------------------------------------------------------------
298
299    class req_type2cache_type_t
300    {
301    public : type_req_cache_t      type      ;
302    public : direction_req_cache_t direction ;
303
304    public : req_type2cache_type_t () {};
305
306    public : req_type2cache_type_t (type_req_cache_t      type      ,
307                                    direction_req_cache_t direction )
308      {
309        this->type      = type     ;
310        this->direction = direction;
311      };
312    };
313
314    req_type2cache_type_t ireq_type2cache_type (uint32_t ireq_type, bool uncached)
315    {
316      type_req_cache_t      type     ;
317      direction_req_cache_t direction;
318     
319      switch (ireq_type)
320        {
321        case ITYPE_READ       : direction=READ ; type=CACHED    ; break;
322        case ITYPE_INVALIDATE : direction=NONE ; type=INVALIDATE; break;
323        case ITYPE_PREFETCH   : direction=NONE ; type=PREFETCH  ; break;
324        default : cerr << "<HIERARCHY_MEMORY.ireq_type2cache_type> Unkown type (" << type << ")" << endl; exit(1);
325        }
326
327      return req_type2cache_type_t (type,direction);
328    }
329
330    req_type2cache_type_t dreq_type2cache_type (uint32_t dreq_type, bool uncached)
331    {
332      type_req_cache_t      type     ;
333      direction_req_cache_t direction;
334     
335      switch (dreq_type)
336        {
337        case DTYPE_READ       : direction=READ ; type=((uncached==true)?UNCACHED:CACHED); break;
338        case DTYPE_INVALIDATE : direction=NONE ; type=INVALIDATE                        ; break;
339        case DTYPE_WRITE      : direction=WRITE; type=((uncached==true)?UNCACHED:CACHED); break;
340        case DTYPE_WRITE_ACK  : direction=WRITE; type=((uncached==true)?UNCACHED:CACHED); break;
341        case DTYPE_FLUSH      : direction=NONE ; type=FLUSH                             ; break;
342        case DTYPE_PREFETCH   : direction=NONE ; type=INVALIDATE                        ; break;
343         
344        default : cerr << "<HIERARCHY_MEMORY.ireq_type2cache_type> Unkown type (" << type << ")" << endl; exit(1);
345        }
346
347      return req_type2cache_type_t (type,direction);
348    }
349    //---------------------------------------------------------------------------------------------
350    //-----[ init ]--------------------------------------------------------------------------------
351    //---------------------------------------------------------------------------------------------
352  public : bool init (char * section, const char * filename, const char ** list_section)
353    {
354      return component_data->init(section,filename,list_section);
355    }
356    //---------------------------------------------------------------------------------------------
357    //-----[ reset ]-------------------------------------------------------------------------------
358    //---------------------------------------------------------------------------------------------
359  public : void reset ()
360    {
361      component_cache -> reset();
362      // Reset buffer of respons
363      for (uint32_t it = 0; it < nb_entity; it++)
364        {
365          component_buffer_irsp [it] ->reset();
366          component_buffer_drsp [it] ->reset();
367        }
368      for (uint32_t it = 0; it < nb_entity_ramlock; it++)
369        component_ramlock [it]   ->reset();
370      for (uint32_t it = 0; it < nb_entity_tty    ; it++)
371        component_tty     [it]   ->reset();
372    }//end reset
373
374    //---------------------------------------------------------------------------------------------
375    //-----[ itoa ]--------------------------------------------------------------------------------
376    //---------------------------------------------------------------------------------------------
377  private :char * itoa (uint32_t int_src, char * string_dest, uint32_t size)
378    {
379      for (unsigned int it_size = 0; it_size < size; it_size ++)
380        {
381          string_dest [it_size] = (int_src & 0xFF);
382          //string_dest [size-it_size-1] = (int_src & 0xFF);
383
384          int_src >>= 8;
385        }
386      return string_dest;
387    }
388
389    //---------------------------------------------------------------------------------------------
390    //-----[ stop ]--------------------------------------------------------------------------------
391    //---------------------------------------------------------------------------------------------
392  public : bool stop ()
393    {
394      return (nb_context_stop >= nb_context);
395    }
396
397    //---------------------------------------------------------------------------------------------
398    //-----[ transition ]--------------------------------------------------------------------------
399    //---------------------------------------------------------------------------------------------
400  public : void transition()
401    {
402      if (NRESET.read() == false)
403        {
404          reset ();
405          return;
406        }
407     
408      //~~~~~[ respons ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
409      // POP All buffer of respons
410      for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++)
411        {
412          for (uint32_t num_port = nb_iport [num_entity]; num_port > 0 ; num_port --)
413            if ((irsp_val[num_entity][num_port-1] && ICACHE [num_entity][num_port-1].RSP_ACK.read())==true)
414              component_buffer_irsp [num_entity]->pop(num_port-1);
415         
416          for (uint32_t num_port = nb_dport [num_entity]; num_port > 0 ; num_port --)
417            if ((drsp_val[num_entity][num_port-1] && DCACHE [num_entity][num_port-1].RSP_ACK.read())==true)
418              component_buffer_drsp [num_entity]->pop(num_port-1);
419        }
420
421      //~~~~~[ request ]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
422      //       cout << "<HIERARCHY_MEMORY.transition>" << endl;
423      for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++)
424        {
425          // ******************
426          // ***** ICACHE *****
427          // ******************
428          for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++)
429            {
430              // Test if transaction
431              if ( (ICACHE [num_entity][num_port].REQ_VAL.read() && ireq_ack [num_entity][num_port]) == false)
432                continue;
433
434              entity_t entity    = component_data->entity((uint32_t)ICACHE [num_entity][num_port].REQ_ADDR.read(), SIZE_IDATA/8);
435              bool     uncached  = false;
436              bool     bus_error = false;
437             
438              sc_uint<2>           type           = ICACHE[num_entity][num_port].REQ_TYPE  .read();
439              // A lot of flag
440              bool                 must_read      = ((type == DTYPE_READ      ) );
441              bool                 must_ack       = ((type == DTYPE_READ      ) );
442             
443              // Test the type of the address : if != MEMORY -> error
444              if ((entity.present == true) && (entity.segment->getType() == TYPE_MEMORY))
445                {
446                if (must_read == true) // Test if must read the ram
447                  for (unsigned int num_word = 0; num_word < NB_IWORD; num_word ++)
448                    {
449                      uint32_t addr = (uint32_t) ICACHE [num_entity][num_port].REQ_ADDR.read()+num_word*(SIZE_IDATA/8);
450                      bus_error |= !component_data->read(addr               ,
451                                                        SIZE_IDATA/8       ,
452                                                        read_iram[num_word]);
453                     
454                      if (isSameEndianness((uint32_t)ICACHE[num_entity][num_port].REQ_TRDID.read()) == false) 
455                        read_iram[num_word] = swapBytes(read_iram[num_word],SIZE_IDATA/8,4);
456                    }
457                uncached = entity.segment->getUncached();
458                }
459                else
460                  {
461                    // Have a bus error
462                    bus_error = true;
463                    uncached  = true;
464                  }
465
466              req_type2cache_type_t cache_type = ireq_type2cache_type ((uint32_t)type,uncached);
467              // Simplification : the size of a line is a multiple of size_iword (no test)
468              uint32_t latence = component_cache->latence(INSTRUCTION_CACHE                                        ,
469                                                          num_entity                                               ,
470                                                          num_port                                                 ,
471                                                          (uint32_t)ICACHE [num_entity][num_port].REQ_ADDR .read() ,
472                                                          (uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() ,
473                                                          cache_type.type                                          ,
474                                                          cache_type.direction                                     );
475             
476              // If is a respons -> compute the latence and push in the write_buffer
477              if (must_ack == true)
478                {
479                  if (bus_error == true)
480                    cout << "Icache : have a bus error" << endl
481                         << "  * num_entity : " << num_entity << endl
482                         << "  * num_port   : " << num_port   << endl
483                         << hex
484                         << "  * req_addr   : " << (uint32_t)ICACHE [num_entity][num_port].REQ_ADDR .read() << endl
485                         << dec
486                         << "  * req_trdid  : " << (uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() << endl
487                         << "  * req_pktid  : " << (uint32_t)ICACHE [num_entity][num_port].REQ_PKTID.read() << endl;
488                 
489                  component_buffer_irsp [num_entity]->push(latence,
490                                                           Entry((uint32_t)ICACHE [num_entity][num_port].REQ_TRDID.read() ,
491                                                                 (uint32_t)ICACHE [num_entity][num_port].REQ_PKTID.read() ,
492                                                                 NB_IWORD                                                 ,
493                                                                 SIZE_IDATA/8                                             ,
494                                                                 read_iram                                                ,
495                                                                 (bus_error==true)?ERR_BUS:ERR_NO                         )
496                                                           );                   
497                }
498            }//num_port
499
500          // ******************
501          // ***** DCACHE *****
502          // ******************
503
504          for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++)
505            {
506              // Test if transaction
507//            cout << "[" << num_entity << "]"
508//                 << "[" << num_port   << "] "
509//                 << "dreq_val : " << DCACHE [num_entity][num_port].REQ_VAL.read() << " "
510//                 << "dreq_ack : " << dreq_ack [num_entity][num_port] << endl;
511
512              if ( (DCACHE [num_entity][num_port].REQ_VAL.read() && dreq_ack [num_entity][num_port]) == false)
513                continue;
514             
515              entity_t             entity         = component_data->entity((uint32_t)DCACHE [num_entity][num_port].REQ_ADDR.read(), SIZE_DDATA/8);
516
517              bool                 uncached       = DCACHE [num_entity][num_port].REQ_UNC.read();
518              bool                 bus_error      = false;
519             
520              uint32_t             addr           = (uint32_t) DCACHE [num_entity][num_port].REQ_ADDR.read();
521              sc_uint<SIZE_DDATA>  wdata          = DCACHE[num_entity][num_port].REQ_WDATA .read();
522              sc_uint<3>           type           = DCACHE[num_entity][num_port].REQ_TYPE  .read();
523              uint32_t             nb_bytes       = access_nb_bytes(DCACHE[num_entity][num_port].REQ_ACCESS.read());
524              // A lot of flag
525              bool                 must_read      = ((type == DTYPE_READ      ));
526              bool                 must_write     = ((type == DTYPE_WRITE     ) ||
527                                                     (type == DTYPE_WRITE_ACK ) );
528              bool                 must_ack       = ((type == DTYPE_READ      ) ||
529                                                     (type == DTYPE_WRITE_ACK ) );
530
531              // Test the type of the address
532              if (entity.present == true)
533                {
534                switch (entity.segment->getType())
535                  {
536                    // ACCESS AT A RAM
537                  case TYPE_MEMORY  : 
538                    {
539                      if (must_read == true)
540                        {
541                          // Read
542                          bus_error |= !component_data->read(addr         ,
543                                                            SIZE_DDATA/8 , // always read a complete word
544                                                            read_dram    );
545                         
546                          for (unsigned int it_size_data = nb_bytes; it_size_data < SIZE_DDATA/8; it_size_data+=nb_bytes)
547                            memcpy(&(read_dram[it_size_data]),&(read_dram[0]),nb_bytes);
548
549                          // Permutation if problem of endianness
550                          if (isSameEndianness((uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read()) == false) 
551                            read_dram  = swapBytes(read_dram , SIZE_DDATA/8, nb_bytes);
552                        }
553                     
554                      if (must_write == true)
555                        {
556                          // Write
557                          for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_DDATA / 8; it_nb_bytes ++)
558                            write_dram [it_nb_bytes] = wdata.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes);
559                        }
560                      break;
561                    }
562                    //ACCESS AT THE TTY
563                  case TYPE_TTY     :
564                    {
565                      if (must_write == false)
566                        {
567                          bus_error = true;
568                          break;
569                        }
570                      uint32_t num_tty           = (addr - entity.segment->getBase())>>4;
571                      uint32_t num_print         = ((addr>>2) & 0x3);
572                     
573                      switch (num_print)
574                        {
575                        case 0 : // Write TTY
576                          {
577                            uint32_t num_component_tty = entity.segment->getIndex();
578                            char     char_write        = (char)wdata.range( 7, 0);
579                            bus_error |= !component_tty [num_component_tty]->write(num_tty,char_write);
580                            break;
581                          }
582                        case 1 : // STOP
583                          {
584                            printf("\n\t***** [ stop    ] Time : %.10d - Address : %.8x - Wdata[31:0] : %.2x%.2x%.2x%.2x         *****\n"
585                                   ,(unsigned int)sc_simulation_time()
586                                   ,(unsigned int)addr
587                                   ,(unsigned int)wdata.range(31,24)
588                                   ,(unsigned int)wdata.range(23,16)
589                                   ,(unsigned int)wdata.range(15, 8)
590                                   ,(unsigned int)wdata.range( 7, 0)
591                                   );
592
593                            uint32_t trdid = (uint32_t) DCACHE[num_entity][num_port].REQ_TRDID.read();
594                           
595                            if (context_stop [trdid] == false)
596                              {
597                                context_stop [trdid] = true;
598                                nb_context_stop ++;
599
600                                if (nb_context_stop >= nb_context)
601                                  sc_stop();
602                              }
603
604                            break;
605                          }
606                        case 2 : // PRINT
607                          {
608                            printf("\n\t----- [ print   ] Time : %.10d - Address : %.8x - Wdata[31:0] : %.2x%.2x%.2x%.2x         -----\n"
609                                   ,(unsigned int)sc_simulation_time()
610                                   ,(unsigned int)addr
611                                   ,(unsigned int)wdata.range(31,24)
612                                   ,(unsigned int)wdata.range(23,16)
613                                   ,(unsigned int)wdata.range(15, 8)
614                                   ,(unsigned int)wdata.range( 7, 0)
615                                   );
616                           
617                            break;
618                          }
619                        default :
620                          {
621                            printf("<%s> : [address : %.8x] tty %d, reg %d don't exist\n",NAME,(unsigned int)addr,num_tty,num_print);
622                            exit(1);
623                          }
624                        }
625                     
626                      break;
627                    }
628                  case TYPE_RAMLOCK :
629                    {
630                      // Access is on a byte, else error
631                      if (nb_bytes != 1)
632                        {
633                          bus_error = true;
634                          break;
635                        }
636                      uint32_t num_ramlock           = (addr - entity.segment->getBase()); // Char access
637                      uint32_t num_component_ramlock = entity.segment->getIndex();
638                      bus_error |= !component_ramlock [num_component_ramlock]->test(num_ramlock);
639                     
640                      if (bus_error == true)
641                        break;
642                     
643                      memset (read_dram,0,SIZE_DDATA/8);
644                       
645                      if (must_read == true)
646                        read_dram [0] = (char)component_ramlock [num_component_ramlock]->read (num_ramlock);
647                      if (must_write == true)
648                        read_dram [0] = (char)component_ramlock [num_component_ramlock]->write(num_ramlock);
649
650                      /*
651                      printf("Access ramlock   ( %d )\n" ,(uint32_t)sc_simulation_time());
652                      printf(" * addr          : %.8x\n" ,(uint32_t)addr);
653                      printf(" * trdid         : %d\n"   ,(uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read());
654                      printf(" * r/w           : %d/%d\n",must_read,must_write);
655                      printf(" * val           : %d\n"   ,(uint32_t)read_dram[0]);
656                      */
657                      break;
658                    }
659                  case TYPE_SIM2OS  :
660                    {
661                      // Mapping :
662                      // [0]  number of service - Wonly - A write in this register lunch the execution of service
663                      // [1]  result            - Ronly - Content the result of the service
664                      // [2]  error             - Ronly - Content the code of errno
665                      // [3+] argument          - Wonly - it's all argument to execute the service
666
667                      uint32_t num_reg = (addr - entity.segment->getBase())>>2;
668                     
669                      switch (num_reg)
670                        {
671                        case 0  : // ---> number of service
672                          {
673                            if (must_write == false)
674                              {
675                                cerr << "<" << NAME << "> {ERROR} : SIM2OS[0] is not accessible in Read" << endl;
676                                bus_error = true;
677                              }
678                            else
679                              {
680                                printf("<sim2os> service     : %.8x\n",(uint32_t)wdata);
681                                component_sim2os->execute(int2service((uint32_t)wdata));
682                              }
683                          break;
684                          }
685                        case 1  : // ---> result
686                          { 
687                            if (must_read == false)
688                              {
689                                cerr << "<" << NAME << "> {ERROR} : SIM2OS[1] is not accessible in Write" << endl;
690                                bus_error = true;
691                              }
692                            else
693                              {
694                                // Decomposition en groupe octect
695                                uint32_t result = (uint32_t) component_sim2os->result;
696                                printf("<sim2os> result      : %.8x (%d)\n",result,result);
697                               
698                                read_dram = itoa(result,read_dram,SIZE_DDATA/8);
699                              }
700                            break;
701                          }
702                        case 2  : // ---> error
703                          {
704                            if (must_read == false)
705                              {
706                                cerr << "<" << NAME << "> {ERROR} : SIM2OS[2] is not accessible in Write" << endl;
707                                bus_error = true;
708                              }
709                            else
710                              {
711                                // Decomposition en groupe octect
712                                uint32_t error = (uint32_t) component_sim2os->error;
713                                printf("<sim2os> error       : %.8x\n",error);
714                                read_dram = itoa(error ,read_dram,SIZE_DDATA/8);
715                              }
716                            break;
717                          }
718                        default : // ---> argument
719                          { 
720                            if (must_write == false)
721                              {
722                                cerr << "<" << NAME << "> {ERROR} : SIM2OS[" << num_reg << "] is not accessible in Write" << endl;
723                                bus_error = true;
724                              }
725                            else
726                              {
727                                uint32_t data = (uint32_t)wdata;
728                                printf("<sim2os> argument[%d] : %.8x\n",num_reg-1,data);
729                                component_sim2os->parameter(num_reg-2,(void *)data);
730                              }
731                            break;
732                          }
733                        }//end switch num_reg
734                     
735                      break;
736                    }
737                  default           :
738                    {
739                      // Have a bus error
740                      bus_error = true;
741                      break;
742                    }
743                  }// switch
744                uncached |= entity.segment->getUncached();
745                }
746              else
747                uncached = true; // If segment don't exist : it's the system bus that determine if the segment exist
748
749
750              if ((must_write == true) && (bus_error == false))
751                {
752                  // Permutation if problem of endianness
753                  if (isSameEndianness((uint32_t)DCACHE[num_entity][num_port].REQ_TRDID.read()) == false) 
754                    write_dram = swapBytes(write_dram, SIZE_DDATA/8, nb_bytes);
755                 
756                  bus_error |= !component_data->write(addr                   ,
757                                                     nb_bytes, // take the good access
758                                                     write_dram             );
759                }
760             
761
762              // Acces at the cache !!!
763              req_type2cache_type_t cache_type = dreq_type2cache_type (type, uncached);
764             
765              uint32_t latence = component_cache->latence(DATA_CACHE                                               ,
766                                                          num_entity                                               ,
767                                                          num_port                                                 ,
768                                                          (uint32_t)DCACHE [num_entity][num_port].REQ_ADDR .read() ,
769                                                          (uint32_t)DCACHE [num_entity][num_port].REQ_TRDID.read() ,
770                                                          cache_type.type                                          ,
771                                                          cache_type.direction                                     );
772             
773              // If is a respons -> compute the latence and push in the write_buffer
774              if ( must_ack == true)
775                {
776                  if (bus_error == true)
777                    cout << "Dcache : have a bus error" << endl;
778                  component_buffer_drsp [num_entity]->push(latence,
779                                                           Entry((uint32_t)DCACHE [num_entity][num_port].REQ_TRDID.read() ,
780                                                                 (uint32_t)DCACHE [num_entity][num_port].REQ_PKTID.read() ,
781                                                                 1                                                        ,
782                                                                 SIZE_DDATA/8                                             ,
783                                                                 &read_dram                                               ,
784                                                                 (bus_error==true)?ERR_BUS:ERR_NO                         )
785                                                           );                   
786                }
787            }// dnb_port
788        }//num_entity
789     
790      // Transition for each component
791      component_cache -> transition();
792      // Transition buffer of respons
793      for (uint32_t it = 0; it < nb_entity; it++)
794        {
795          component_buffer_irsp [it] ->transition();
796          component_buffer_drsp [it] ->transition();
797        }
798      component_sim2os->transition();
799
800    }//end transition
801
802    //---------------------------------------------------------------------------------------------
803    //-----[ genMoore ]----------------------------------------------------------------------------
804    //---------------------------------------------------------------------------------------------
805  public : void genMoore()
806    {
807      //Scan all entity and for each entity scan all port
808      for (uint32_t num_entity = 0; num_entity < nb_entity; num_entity++)
809        {
810          //##### REQUEST #####
811          uint32_t nb_slot_free = component_buffer_irsp [num_entity]->nb_slot_free ();
812          for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++)
813            {
814              ireq_ack [num_entity][num_port] = (num_port < nb_slot_free);
815           
816              ICACHE [num_entity][num_port].REQ_ACK.write (ireq_ack [num_entity][num_port]);
817            }
818
819          nb_slot_free = component_buffer_drsp [num_entity]->nb_slot_free ();
820          for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++)
821            {
822              dreq_ack [num_entity][num_port] = (num_port < nb_slot_free );
823           
824              DCACHE [num_entity][num_port].REQ_ACK.write (dreq_ack [num_entity][num_port]);
825            }
826
827          //##### RESPONS #####
828          // ~~~~~> ICACHE <~~~~~
829          for (uint32_t num_port = 0; num_port < nb_iport [num_entity]; num_port ++)
830            {
831              // Test the number of element in the respons's buffer
832              if (num_port >= component_buffer_irsp [num_entity]->nb_slot_use())
833                {
834                  irsp_val[num_entity][num_port] = 0; // No respons
835                }
836              else
837                {
838                  slot_t<Entry> slot = component_buffer_irsp [num_entity]->read(num_port);
839                 
840                  irsp_val[num_entity][num_port] = (slot.delay == 0); // respons if have a result
841                  ICACHE  [num_entity][num_port].RSP_TRDID.write((sc_uint<SIZE_TRDID> )slot.data.trdid);
842                  ICACHE  [num_entity][num_port].RSP_PKTID.write((sc_uint<SIZE_IPKTID>)slot.data.pktid);
843                  ICACHE  [num_entity][num_port].RSP_ERR  .write((sc_uint<2>          )slot.data.error);
844                 
845                  for (uint32_t num_word = 0; num_word < NB_IWORD; num_word ++)
846                    {
847                      sc_uint<SIZE_IDATA> data;
848
849                      for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_IDATA / 8; it_nb_bytes ++)
850                        {
851#if defined(systemcass)
852                          RANGE_SET_VAL(SIZE_IDATA         ,
853                                        data               ,
854                                        8*(it_nb_bytes+1)-1,
855                                        8*it_nb_bytes      ,
856                                        slot.data.data [num_word][it_nb_bytes]);
857#else //#elif defined(systemc)
858                          data.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes) = slot.data.data [num_word][it_nb_bytes];
859#endif
860                        }
861                      ICACHE  [num_entity][num_port].RSP_INS [num_word].write(data);
862                    }
863                }
864
865              ICACHE  [num_entity][num_port].RSP_VAL.write(irsp_val[num_entity][num_port]);
866            }//end nb_iport
867
868          // ~~~~~> DCACHE <~~~~~
869          for (uint32_t num_port = 0; num_port < nb_dport [num_entity]; num_port ++)
870            {
871              if (num_port >= component_buffer_drsp [num_entity]->nb_slot_use())
872                {
873                  drsp_val[num_entity][num_port] = 0; // No respons
874                }
875              else
876                {
877                  slot_t<Entry> slot = component_buffer_drsp [num_entity]->read(num_port);
878                 
879                  drsp_val[num_entity][num_port] = (slot.delay == 0);
880                  DCACHE  [num_entity][num_port].RSP_TRDID   = (sc_uint<SIZE_TRDID> )slot.data.trdid;
881                  DCACHE  [num_entity][num_port].RSP_PKTID   = (sc_uint<SIZE_DPKTID>)slot.data.pktid;
882                  DCACHE  [num_entity][num_port].RSP_ERR     = (sc_uint<2>          )slot.data.error;
883
884                  sc_uint<SIZE_DDATA> data;
885
886                  for (unsigned int it_nb_bytes = 0; it_nb_bytes < SIZE_DDATA / 8; it_nb_bytes ++)
887                    {
888#if defined(systemcass)
889                      RANGE_SET_VAL(SIZE_DDATA         ,
890                                    data               ,
891                                    8*(it_nb_bytes+1)-1,
892                                    8*it_nb_bytes      ,
893                                    slot.data.data [0][it_nb_bytes]);
894#else //#elif defined(systemc)
895                      data.range(8*(it_nb_bytes+1)-1,8*it_nb_bytes) = slot.data.data [0][it_nb_bytes];
896#endif
897                    }
898                  DCACHE  [num_entity][num_port].RSP_RDATA.write(data);
899                }
900              DCACHE  [num_entity][num_port].RSP_VAL     = drsp_val[num_entity][num_port];
901            }//nb_dport
902        }//nb_entity
903    }//end genMoore
904
905    //---------------------------------------------------------------------------------------------
906    //-----[ operator<< ]--------------------------------------------------------------------------
907    //---------------------------------------------------------------------------------------------
908
909    friend ostream& operator<< (ostream& output_stream, const HIERARCHY_MEMORY &x)
910    {
911      output_stream << "<" << x.NAME << ">" << endl
912                    << "  * nb_entity         : " << x.nb_entity         << endl;
913
914      output_stream << "  -----[ component_data ]-----------------------------------" << endl;
915      output_stream << *x.component_data << endl;
916           
917      output_stream << "  -----[ component_cache ]----------------------------------" << endl;
918      output_stream << *x.component_cache;
919
920      output_stream << "  -----[ component_buffer_irsp ]----------------------------" << endl;
921      for (uint32_t num_entity = 0; num_entity < x.nb_entity; num_entity++)
922        {
923          output_stream << "  * nb_iport [" << num_entity << "]      : " << x.nb_iport [num_entity] << endl;
924          output_stream << *x.component_buffer_irsp [num_entity];
925        }
926     
927      output_stream << "  -----[ component_buffer_drsp ]----------------------------" << endl;
928      for (uint32_t num_entity = 0; num_entity < x.nb_entity; num_entity++)
929        {
930          output_stream << "  * nb_dport [" << num_entity << "]      : " << x.nb_dport [num_entity] << endl;
931          output_stream << *x.component_buffer_drsp [num_entity];
932        }
933
934      //       output_stream << "  -----[ component_ramlock ]--------------------------------" << endl;
935      //       output_stream << "  * nb_entity_ramlock : " << x.nb_entity_ramlock << endl;
936      //       for (uint32_t it = 0; it < x.nb_entity_ramlock; it++)
937      //        output_stream << *x.component_ramlock [it];     
938     
939      //       output_stream << "  -----[ component_tty ]------------------------------------" << endl;
940      //       output_stream << "  * nb_entity_tty     : " << x.nb_entity_tty     << endl;
941      //       for (uint32_t it = 0; it < x.nb_entity_tty    ; it++)
942      //        output_stream << *x.component_tty     [it];
943
944      //       output_stream << *x.component_sim2os;
945     
946      return output_stream;
947    }
948
949  };//class
950};
951
952#endif //!HIERARCHY_MEMORY_H
Note: See TracBrowser for help on using the repository browser.