Changes between Version 55 and Version 56 of Writing Rules/Tlmt


Ignore:
Timestamp:
Nov 14, 2008, 1:53:25 PM (15 years ago)
Author:
fpecheux
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Writing Rules/Tlmt

    v55 v56  
    11{{{
    22#!html
    3 <h1>Writing efficient TLM-T SystemC simulation models for SoCLib</h1>
    4 }}}
    5 
    6 Authors : Alain Greiner, François Pêcheux, Emmanuel Viaud, Nicolas Pouillon
     3<h1>Writing TLM2.0-compliant timed SystemC simulation models for SoCLib</h1>
     4}}}
     5
     6Authors : Alain Greiner, François Pêcheux, Emmanuel Viaud, Nicolas Pouillon, Aline Vieira de Mello
    77 
    88[[PageOutline]]
     
    1010= A) Introduction =
    1111
    12 A new version of this document is under development.
    13 This document describes the modeling rules for writing TLM-T SystemC simulation models for SoCLib.
     12This document is still under development.
     13It describes the modeling rules for writing TLM-T SystemC simulation models for SoCLib that are
     14compliant with the new TLM2.0 OSCI standard.
    1415These rules enforce the PDES (Parallel Discrete Event Simulation) principles. Each PDES process involved in
    1516the simulation has its own local time, and PDES processes synchronize through messages piggybacked with time information.
    16 Models complying to these rules can be used with the "standard" OSCI simulation engine (SystemC 2.x), but can
     17Models complying to these rules can be used with the "standard" OSCI simulation engine (SystemC 2.x) and
     18the TLM2.0 protocol, but can
    1719also be used also with others simulation engines, especially distributed, parallelized simulation engines.
    1820
     
    2123= B) Single VCI initiator and single VCI target =
    2224
    23 Figure 1 presents a minimal system containing one single initiator, '''!VciSimpleInitiator''' , and one single
    24 target, '''!VciSimpleTarget''' . The '''!VciSimpleInitiator''' module behavior is modeled by
     25Figure 1 presents a minimal system containing one single initiator, '''!my_initiator''' , and one single
     26target, '''!my_target''' . The '''!my_initiator''' module behavior is modeled by
    2527the SC_THREAD  '''execLoop()''', that contains an infinite loop.
    26 The call-back function '''rspReceived()''' is executed when a VCI response packet is received by the initiator module.
     28The call-back function '''my_nb_transport_bw()''' is executed when a VCI response packet is received by the initiator module.
    2729
    2830[[Image(tlmt_figure_1.png, nolink)]]
    2931
    3032Unlike the initiator, the target module has a purely reactive behaviour and is therefore modeled as a call-back function.
    31 In other words, there is no need to use a SC_THREAD : The target behaviour is entirely described by the call-back function '''cmdReceived()''',
     33In other words, there is no need to use a SC_THREAD : The target behaviour is entirely described by the call-back
     34function '''my_nb_transport_fw()''',
    3235that is executed when a VCI command packet is received by the target module.
    3336
     
    3740= C) VCI initiator Modeling =
    3841
    39 In the proposed example, the initiator module is modeled by the '''!VciSimpleInitiator''' class.
    40 This class inherits from the '''soclib::tlmt::!BaseModule''' class, that acts as the root class for all TLM-T modules.
    41 The process time, as well as other useful process attributes, is contained in a C++ structure called
    42 a '''tlmt_core::tlmt_thread_context'''. As there is only one thread in this module, there is only one member
    43 variable '''c0''' of type '''tlmt_core::tlmt_thread_context'''. '''c0''' mostly contains the PDES process local
    44 time ('''H''' on the figure). In all the TLM-T models, time is handled by the '''tlmt_core::tlmt_time''' class.
    45 In order to get the time associated to the initiator process, one should use the getter
    46 function '''time()''' on the '''c0''' object, and should use the setter functions
    47 '''set_time()''' and '''update_time()''' to assign a new time to the PDES process.
     42In the proposed example, the initiator module is modeled by the '''!my_initiator''' class.
     43This class inherits from the SystemC '''sc_core::!sc_module''' class, that acts as the root class for all TLM-T modules.
     44
     45The initiator local time is contained in a member variable named '''m_localTime''', of type '''sc_core::sc_time'''. The
     46local time can be accessed through the use of the following accessors: '''addLocalTime()''', '''setLocalTime()'''
     47and '''getLocalTime()'''.
     48{{{
     49  sc_core::sc_time m_localTime;                     // the initiator local time
     50  ...
     51  void addLocalTime(sc_core::sc_time t);            // add a value to the local time
     52  void setLocalTime(sc_core::sc_time& t);           // set the local time
     53  sc_core::sc_time getLocalTime(void);              // get the local time
     54}}}
     55
     56The initiator activity corresponds to the boolean member '''m_activity''' that indicates if the initiator is currently active
     57(i.e. '''true''', wants to participate in the arbitration in the interconnect) or inactive (i.e. '''false''', does not want
     58to participate in the arbitration in the interconnect). The corresponding access functions are '''setActivity()''' and '''getActivity()'''.
     59{{{
     60  bool m_activity;
     61  ...
     62  void setActivity(bool t);                         // set the activity status (true if the component is active)
     63  bool getActivity(void);                           // get the activity state
     64}}}
    4865
    4966The '''execLoop()''' method, describing the initiator behaviour must be declared as a member function of
    50 the '''!VciSimpleInitiator''' class.
    51 
    52 Finally, the class '''!VciSimpleInitiator''' must contain a member variable '''p_vci''', of type '''!VciInitiator'''.
    53 This object has a template parameter <'''vci_param'''> defining the widths of the VCI ADDRESS and DATA fields.
     67the '''!my_initiator''' class.
     68
     69Finally, the class '''!my_initiator''' must contain a member variable '''p_vci_init''', of type '''tlmt_simple_initiator_socket'''.
     70This member variable represents the VCI initiator port. It has 3 template parameters, two of which are used to help
     71connecting the response callback function ('''my_initiator''' in the example, first template parameter) to the port and
     72defining the port type
     73('''soclib_vci_types''' in the following example, third template parameter). '''soclib_vci_types''' is indeed a C++ structure containing two
     74typedef: the first typedef defines the payload type as VCI, and the other defines the TLM phase type. The phase type can either
     75be '''!TLMT_CMD''' (i.e. the transaction indicates the emission of a command by an initiator and its reception by a target),
     76'''!TLMT_RSP''' (i.e. the transaction indicates the emission of a response by a target and its reception by an initiator),
     77or '''!TLMT_INFO''' (i.e. a TLM-T transaction emitted by one side of a link (vci, irq or fifo) to get information such as time
     78and activity on the other side of the link).
    5479
    5580== C.1) Sending a VCI command packet ==
    5681
    57 To send a VCI command packet, the '''execLoop()''' method must use the '''send()''' method, that is a member function of
    58 the '''p_vci''' port. The prototype is the following:
    59 {{{
    60 void send(soclib::tlmt::vci_cmd_packet<vci_param> *cmd, // pointer to a VCI command packet     
    61           tlmt_core::tlmt_time time);                   // initiator local time
    62 }}}
    63 
    64 The contents of a VCI command packet is defined below:
    65 {{{
    66 template<typename vci_param>
    67 class vci_cmd_packet
    68 {
    69 public:
    70         typename vci_param::cmd_t cmd;        // VCI transaction type
    71         typename vci_param::addr_t address;   // address on the target side
    72         uint32_t int be;                      // byte_enable value (same value for all packet words)
    73         bool contig;                          // contiguous addresses (when true)
    74         typename vci_param::data_t *buf;      // pointer to the local buffer on the initiator
    75         size_t nwords;                        // number of words in the packet
    76         uint32_t srcid;                       // VCI Source ID
    77         uint32_t trdid;                       // VCI Thread ID
    78         uint32_t pktid;                       // VCI Packet ID
    79 };
    80 }}}
    81 
    82 The possible values for the '''cmd''' filed are  `vci_param::CMD_READ`, `vci_param::CMD_WRITE`, `vci_param::CMD_READ_LOCKED`,
    83 and `vci_param::CMD_STORE_COND`.
    84 The '''contig''' field can be used for optimization.
    85 
    86 The '''send()''' function is non-blocking.
     82To send a VCI command packet, the '''execLoop()''' method must use the '''nb_transport_fw()''' method, that is a member
     83function of the '''p_vci_init''' port. The prototype is the following:
     84{{{
     85
     86  tlm::tlm_sync_enum nb_transport_fw               /// sync status
     87  ( soclib_vci_types::vci_payload_type &payload,      ///< VCI payload pointer
     88    soclib_vci_types::tlmt_phase_type   &phase,       ///< transaction phase
     89    sc_core::sc_time                   &time);        ///< time
     90}}}
     91
     92The first parameter of this member function is the VCI packet, the second represents the phase (TLMT_CMD in this case), and the third
     93parameter contains the initiator local time.
     94
     95To prepare a VCI packet for sending, the '''execLoop''' function must declare two objects locally, '''payload''' and '''phase'''.
     96{{{
     97  soclib_vci_types::vci_payload_type payload;
     98  soclib_vci_types::tlmt_phase_type phase;
     99}}}
     100A payload of type '''soclib_vci_types::vci_payload_type''' corresponds to a '''tlmt_vci_transaction''' and thus
     101contains three kinds of structure fields: TLM2.0 related fields,VCI related fields, and TLM-T related fields.
     102
     103The contents of a '''tlmt_transaction''' is defined below:
     104{{{
     105class tlmt_vci_transaction
     106{
     107        ...
     108private:
     109  // TLM2.0 related fields and common structure
     110
     111  sc_dt::uint64        m_address;               // address
     112  unsigned char*       m_data;                  // buf
     113  unsigned int         m_length;                // nword
     114  tlmt_response_status m_response_status;       // rerror
     115  bool                 m_dmi;                   // nothing
     116  unsigned char*       m_byte_enable;           // be
     117  unsigned int         m_byte_enable_length;
     118  unsigned int         m_streaming_width;       //
     119
     120  // VCI related fields
     121 
     122  tlmt_command         m_command;               // cmd
     123  unsigned int         m_src_id;                // srcid
     124  unsigned int         m_trd_id;                // trdid
     125  unsigned int         m_pkt_id;                // pktid
     126
     127  // TLM-T related fields
     128 
     129  bool*                m_activity_ptr;
     130  sc_core::sc_time*    m_local_time_ptr;
     131
     132}}}
     133
     134The TLM2.0 compliant accessors allow to set the TLM2.0 related fields, such as the transaction address, the byte enable
     135array pointer and its associated size in bytes, and the data array pointer and its associated size in bytes. The byte
     136enable array allows to build versatile packets thanks to a powerful but slow data masking scheme. Further experiments are
     137currently done. It is likely that the types of the '''m_data''' and '''m_byte_enable''' of the '''tlmt_vci_transaction'''
     138will be changed to '''uint32*''' in a near future.
     139
     140The VCI accessors are used to define the VCI transaction type, that can either be '''set_read()''' (for read command),
     141'''set_write()''' (for write command),'''set_locked_read()''' (for atomic locked read),
     142and '''set_store_cond()''' (for atomic store conditional). The '''set_src_id()''', '''set_trd_id()''' and '''set_pkt_id()''' functions
     143respectively set the VCI source, thread and packet identifiers.
     144
     145{{{
     146    payload.set_address(0x10000000);//ram 0
     147    payload.set_byte_enable_ptr(byte_enable);
     148    payload.set_byte_enable_length(nbytes);
     149    payload.set_data_ptr(data);
     150    payload.set_data_length(nbytes); // 5 words of 32 bits
     151
     152    payload.set_write();
     153    payload.set_src_id(m_id);
     154    payload.set_trd_id(0);
     155    payload.set_pkt_id(pktid);
     156
     157    phase= soclib::tlmt::TLMT_CMD;
     158    sendTime = getLocalTime();
     159
     160    p_vci_init->nb_transport_fw(payload, phase, sendTime);
     161}}}
     162
     163
     164The '''nb_transport_fw()''' function is non-blocking.
    87165To implement a blocking transaction (such as a cache line read, where the processor is ''frozen'' during the VCI transaction),
    88166the model designer must use the SystemC '''sc_core::wait(x)''' primitive ('''x''' being of type '''sc_core::sc_event'''):
     
    92170
    93171To receive a VCI response packet, a call-back function must be defined as a member function of the
    94 class '''!VciSimpleInitiator'''. This call-back function (named '''rspReceived()''' in the example), must be
    95 declared in the '''!VciSimpleInitiator''' class and
    96 is executed each time a VCI response packet is received on the '''p_vci''' port. The function name is not
     172class '''!my_initiator'''. This call-back function (named '''my_nb_transport_bw()''' in the example), must be
     173declared in the '''my_initiator''' class and
     174is executed each time a VCI response packet is received on the '''p_vci_init''' port. The function name is not
    97175constrained, but the arguments must respect the following prototype:
    98176{{{
    99 tlmt_core::tlmt_return &rspReceived(soclib::tlmt::vci_rsp_packet<vci_param> *pkt,
    100          const tlmt_core::tlmt_time &time,
    101          void *private_data);
    102 }}}
    103 
    104 The contents of a VCI response packet is defined below:
    105 {{{
    106 template<typename vci_param>
    107 class vci_rsp_packet
    108 {
    109 public:
    110         typename vci_param::cmd_t cmd;    // VCI transaction type
    111         size_t nwords;                    // number of words in the packet
    112         uint32_t error;                   // error code (0 if no error)
    113         uint32_t srcid;                   // VCI Source ID
    114         uint32_t trdid;                   // VCI Thread ID
    115         uint32_t pktid;                   // VCI Packet ID
    116 };
    117 }}}
    118 
    119 The second parameter, '''time''', is of type '''tlmt_core::tlmt_time''' and corresponds to the time of the response. The third parameter,
    120 '''private_data''' has a default value of '''NULL''' and is not used when transmitting or receiving VCI packets.
    121 
    122 
    123 The actions executed by the call-back function depend on the response transaction type ('''cmd''' field), as well as
     177  tlm::tlm_sync_enum my_nb_transport_bw                // for resp messages
     178    ( soclib_vci_types::vci_payload_type &payload,     // payload
     179      soclib_vci_types::tlmt_phase_type   &phase,      // transaction phase
     180      sc_core::sc_time                   &time);       // resp time
     181}}}
     182
     183The function parameters are identical to those described in the forward transport function
     184
     185The actions executed by the call-back function depend on the response transaction type ('''m_command''' field), as well as
    124186the '''pktid''' and '''trdid''' fields.
    125187
     
    130192== C.3) Initiator Constructor ==
    131193
    132 The constructor of the class '''!VciSimpleInitiator''' must initialize all the member variables, including
    133 the '''p_vci''' port. The '''rspReceived()''' call-back function being executed in the context of the thread sending
    134 the response packet, a link between the '''p_vci''' port and the call-back function must be established.
    135 Moreover, the '''p_vci''' port must contain a pointer to the initiator thread context '''c0'''. This allows the target to
     194The constructor of the class '''!my_initiator''' must initialize all the member variables, including
     195the '''p_vci_init''' port. The '''my_nb_transport_bw()''' call-back function being executed in the context of the thread sending
     196the response packet, a link between the '''p_vci_init''' port and the call-back function must be established.
     197The TLMT_INFO transaction allows the target to
    136198get information on the initiator that actually sends VCI packets (the initiator local time, the initiator activity, etc).
    137199
    138 The '''!VciInitiator''' constructor for the '''p_vci_''' object must be called with the following arguments:
    139 {{{
    140 p_vci("vci", new tlmt_core::tlmt_callback<VciSimpleInitiator,soclib::tlmt::vci_rsp_packet<vci_param> *>(
    141                                          this, &VciSimpleInitiator<vci_param>::rspReceived), &c0)
    142 }}}
    143  
     200The '''my_initiator''' constructor for the '''p_vci_init''' object must be called with the following arguments:
     201{{{
     202  p_vci_init.register_nb_transport_bw(this, &my_initiator::my_nb_transport_bw);
     203}}}
     204
     205where '''my_nb_transport_bw''' is the name of the callback function
     206
    144207== C.4) Lookahead parameter ==
    145208
     
    159222{{{
    160223
    161 ////////////////////////// vci_simple_initiator.h ////////////////////////////////
    162 
    163 #ifndef VCI_SIMPLE_INITIATOR_H
    164 #define VCI_SIMPLE_INITIATOR_H
    165 
    166 #include <tlmt>
    167 #include "tlmt_base_module.h"
    168 #include "vci_ports.h"
    169 
    170 namespace soclib { namespace tlmt {
    171 
    172 template<typename vci_param>
    173 class VciSimpleInitiator
    174     : public soclib::tlmt::BaseModule
    175 {
    176     tlmt_core::tlmt_thread_context c0;
    177     sc_core::sc_event m_rsp_received;
    178     tlmt_core::tlmt_return m_return;
    179     soclib::tlmt::vci_cmd_packet<vci_param> cmd;
    180 
    181     uint32_t addresses[8];       // address table,
    182     uint32_t localbuf[8];        // local buffer
    183    
    184     uint32_t m_counter;          // iteration counter
    185     uint32_t m_lookahead;        // lookahead value
    186     uint32_t m_index;            // initiator index
    187    
     224////////////////////////// my_initiator.h ////////////////////////////////
     225#ifndef __MY_INITIATOR_H__
     226#define __MY_INITIATOR_H__
     227
     228#include "tlm.h"                                // TLM headers
     229#include "tlmt_transactions.h"                  // VCI headers
     230#include "tlmt_simple_initiator_socket.h"       // VCI socket
     231#include "mapping_table.h"
     232
     233class my_initiator                              // my_initiator
     234:         public sc_core::sc_module             // inherit from SC module base class
     235{
     236private:
     237  //Variables
     238  typedef soclib::tlmt::VciParams<uint32_t,uint32_t,4> vci_param;
     239  sc_core::sc_event m_rspEvent;
     240  sc_core::sc_time m_localTime;
     241  bool m_activity;
     242  uint32_t m_initid;
     243  uint32_t m_counter;
     244  uint32_t m_lookahead;
     245 
     246  /////////////////////////////////////////////////////////////////////////////////////
     247  // Fuctions
     248  /////////////////////////////////////////////////////////////////////////////////////
     249  void execLoop(void);                              // initiator thread
     250  void addLocalTime(sc_core::sc_time t);            // add a value to the local time
     251  void setLocalTime(sc_core::sc_time& t);           // set the local time
     252  sc_core::sc_time getLocalTime(void);              // get the local time
     253  void setActivity(bool t);                         // set the activity status (true if the component is active)
     254  bool getActivity(void);                           // get the activity state
     255
     256  /////////////////////////////////////////////////////////////////////////////////////
     257  // Virtual Fuctions  tlm::tlm_bw_transport_if (VCI INITIATOR SOCKET)
     258  /////////////////////////////////////////////////////////////////////////////////////
     259
     260  /// Receive rsp from target
     261  tlm::tlm_sync_enum my_nb_transport_bw                // for resp messages
     262    ( soclib_vci_types::vci_payload_type &payload,     // payload
     263      soclib_vci_types::tlmt_phase_type   &phase,      // transaction phase
     264      sc_core::sc_time                   &time);       // resp time
     265
    188266protected:
    189     SC_HAS_PROCESS(VciSimpleInitiator);
    190 
     267  SC_HAS_PROCESS(my_initiator);
     268 
    191269public:
    192     soclib::tlmt::VciInitiator<vci_param> p_vci;
    193 
    194     VciSimpleInitiator( sc_core::sc_module_name name,
    195                                 uint32_t initiator index,
    196                                 uint32_t lookahead );
    197 
    198     tlmt_core::tlmt_return &rspReceived(soclib::tlmt::vci_rsp_packet<vci_param> *pkt,
    199          const tlmt_core::tlmt_time &time,
    200          void *private_data);
    201     void behavior();
    202 };
    203 
    204 }}
    205 
    206 #endif
    207 
    208 ////////////////////////// vci_simple_initiator.cpp ////////////////////////////////
    209 
    210 #include "../include/vci_simple_initiator.h"
    211 
    212 namespace soclib { namespace tlmt {
    213 
    214 #define tmpl(x) template<typename vci_param> x VciSimpleInitiator<vci_param>
    215 
    216 tmpl(tlmt_core::tlmt_return&)::rspReceived(soclib::tlmt::vci_rsp_packet<vci_param> *pkt,
    217         const tlmt_core::tlmt_time &time,
    218         void *private_data)
    219 {
    220     if(pkt->cmd == vci_param::VCI_CMD_READ) {
    221         c0.set_time(time + tlmt_core::tlmt_time(pkt->length));
    222         m_rsp_received.notify(sc_core::SC_ZERO_TIME) ;
     270  tlmt_simple_initiator_socket<my_initiator,32,soclib_vci_types> p_vci_init;   // VCI initiator port
     271
     272  //constructor
     273  my_initiator(                                              // constructor
     274               sc_core::sc_module_name name,                 // module name
     275               const soclib::common::IntTab &index,          // VCI initiator index
     276               const soclib::common::MappingTable &mt,       // mapping table
     277               uint32_t lookahead                            // lookahead
     278               );
     279 
     280};
     281 #endif /* __MY_INITIATOR_H__ */
     282
     283////////////////////////// my_initiator.cpp ////////////////////////////////
     284
     285#include "my_initiator.h"                       // Our header
     286
     287#ifndef MY_INITIATOR_DEBUG
     288#define MY_INITIATOR_DEBUG 1
     289#endif
     290
     291#define tmpl(x) x my_initiator
     292
     293///Constructor
     294tmpl (/**/)::my_initiator
     295            ( sc_core::sc_module_name name,           // module name
     296              const soclib::common::IntTab &index,    // index of mapping table
     297              const soclib::common::MappingTable &mt, // mapping table
     298              uint32_t lookahead                      // lookahead
     299              )
     300            : sc_module(name)                         // init module name
     301           , p_vci_init("p_vci_init")                 // vci initiator socket name
     302{
     303  //register callback function
     304  p_vci_init.register_nb_transport_bw(this, &my_initiator::my_nb_transport_bw);
     305
     306  // initiator identification
     307  m_initid = mt.indexForId(index);
     308
     309  //lookahead control
     310  m_counter = 0;
     311  m_lookahead = lookahead;
     312
     313  //initialize the local time
     314  m_localTime= 0 * UNIT_TIME;
     315
     316  // initialize the activity variable
     317  setActivity(true);
     318
     319  // register thread process
     320  SC_THREAD(execLoop);
     321}
     322
     323/////////////////////////////////////////////////////////////////////////////////////
     324// Fuctions
     325/////////////////////////////////////////////////////////////////////////////////////
     326tmpl (sc_core::sc_time)::getLocalTime()
     327{
     328  return m_localTime;
     329}
     330
     331tmpl (bool)::getActivity()
     332{
     333  return m_activity;
     334}
     335
     336tmpl (void)::setLocalTime(sc_core::sc_time &t)
     337{
     338  m_localTime=t;
     339}
     340
     341tmpl (void)::addLocalTime(sc_core::sc_time t)
     342{
     343  m_localTime= m_localTime + t;
     344}
     345
     346tmpl (void)::setActivity(bool t)
     347{
     348  m_activity =t;
     349}
     350
     351tmpl (void)::execLoop(void)   // initiator thread
     352{
     353  soclib_vci_types::vci_payload_type payload;
     354  soclib_vci_types::tlmt_phase_type phase;
     355  sc_core::sc_time sendTime;
     356  unsigned char data[32];
     357  unsigned char byte_enable[32];
     358  int pktid = 0;
     359  int nbytes = 4; // 1 word of 32 bits
     360
     361  uint32_t int_data = 12345678;
     362  std::ostringstream name;
     363  name << "" << int_data;
     364  std::cout << "NAME = " << std::dec << name << std::endl;
     365
     366  for(int i=0; i<nbytes; i++)
     367    byte_enable[i] = TLMT_BYTE_ENABLED;
     368
     369  for(int i=0; i<32; i++)
     370    data[i] = 0x0;
     371
     372  data[0]='a';
     373  data[1]='b';
     374  data[2]='c';
     375  data[3]='d';
     376  data[4]='\0';
     377
     378  std ::cout<< "DATA = " << data << std::endl;
     379
     380  while ( 1 ){
     381    addTime(10 * UNIT_TIME);
     382
     383    payload.set_address(0x10000000);//ram 0
     384    payload.set_byte_enable_ptr(byte_enable);
     385    payload.set_byte_enable_length(nbytes);
     386    payload.set_data_ptr(data);
     387    payload.set_data_length(nbytes); // 5 words of 32 bits
     388
     389    payload.set_write();
     390    payload.set_src_id(m_id);
     391    payload.set_trd_id(0);
     392    payload.set_pkt_id(pktid);
     393
     394    phase= soclib::tlmt::TLMT_CMD;
     395    sendTime = getLocalTime();
     396
     397#if MY_INITIATOR_DEBUG
     398    std::cout << "[INITIATOR " << m_id << "] send cmd packet id = " << payload.get_pkt_id() << " time = " << getLocalTime().value() << std::endl;
     399#endif
     400
     401    p_vci_init->nb_transport_fw(payload, phase, sendTime);
     402    wait(m_rspEvent);
     403
     404#if MY_INITIATOR_DEBUG
     405    std::cout << "[INITIATOR " << m_id << "] receive rsp packet id = " << payload.get_pkt_id() << " time = " << getLocalTime().value() << std::endl;
     406#endif
     407
     408    pktid++;
     409
     410    addTime(10 * UNIT_TIME);
     411
     412    payload.set_address(0x10000000);//ram 0
     413    payload.set_byte_enable_ptr(byte_enable);
     414    payload.set_byte_enable_length(nbytes);
     415    payload.set_data_ptr(data);
     416    payload.set_data_length(nbytes); // 5 words of 32 bits
     417
     418    payload.set_read();
     419    payload.set_src_id(m_id);
     420    payload.set_trd_id(0);
     421    payload.set_pkt_id(pktid);
     422
     423    phase= soclib::tlmt::TLMT_CMD;
     424    sendTime = getLocalTime();
     425
     426#if MY_INITIATOR_DEBUG
     427    std::cout << "[INITIATOR " << m_id << "] send cmd packet id = " << payload.get_pkt_id() << " time = " << getLocalTime().value() << std::endl;
     428#endif
     429
     430    p_vci_init->nb_transport_fw(payload, phase, sendTime);
     431    wait(m_rspEvent);
     432
     433#if MY_INITIATOR_DEBUG
     434    std::cout << "[INITIATOR " << m_id << "] receive rsp packet id = " << payload.get_pkt_id() << " time = " << getLocalTime().value() << std::endl;
     435
     436#endif
     437
     438    pktid++;
     439
     440    // lookahead management
     441    m_counter++ ;
     442    if (m_counter >= m_lookahead) {
     443      m_counter = 0 ;
     444      wait(sc_core::SC_ZERO_TIME) ;
    223445    }
    224     return m_return;
    225 }
    226 
    227 tmpl(void)::behavior()
    228 {
    229 
    230         for(;;) {
    231 
    232                 // sending a read VCI packet
    233                
    234                 cmd.cmd = vci_param::CMD_READ;  // a VCI read packet
    235                 addresses[0] = 0xBFC00000;      // the start address
    236                 cmd.address = addresses;        // assigned
    237                 cmd.be = 0xF;                   // reading full words
    238                 cmd.contig = true;              // at successive addresses
    239                 cmd.buf = localbuf;             // storing the read results in localbuf
    240                 cmd.length = 8;                 // packet of 8 words
    241                 cmd.srcid = 0;                  // srcid=0
    242                 cmd.trdid = 0;                  // trdid=0
    243                 cmd.pktid = 0;                  // pktid=0
    244 
    245                 tlmt_core::tlmt_return ret;        // in case a test on the send function is needed
    246                 ret = p_vci.send(&cmd, c0.time()); // sending the packet
    247                 sc_core::wait(m_rsp_received);     // and waiting for the response packet
    248 
    249                 // sending a write VCI packet
    250                
    251                 localbuf[0]=0x00112233;         // first, fill the write local buffer with write data
    252                
    253                 cmd.cmd = vci_param::CMD_WRITE; // then issue the VCI write packet
    254                 addresses[0] = 0x10000000;      // starting with this address
    255                 cmd.address = addresses;
    256                 cmd.be = 0xF;
    257                 cmd.contig = 0;
    258                 cmd.buf = localbuf;
    259                 cmd.length = 1;
    260                 cmd.srcid = 0;
    261                 cmd.trdid = 0;
    262                 cmd.pktid = 0;
    263 
    264                 ret = p_vci.send(&cmd, c0.time()); // Don't wait for the answer
    265 
    266                 // lookahead management
    267                 m_counter++ ;
    268                 if (m_counter >= m_lookahead) {
    269                    m_counter = 0 ;
    270                    sc_core::wait(sc_core::SC_ZERO_TIME) ;
    271                 } // end if
    272                
    273                 // process time= process time+1
    274                 c0.set_time(c0.time()+tlmt_core::tlmt_time(1)) ;
    275 
    276         }
    277 }
    278 
    279 tmpl(/**/)::VciSimpleInitiator( sc_core::sc_module_name name,
    280                                 uint32_t initiator index,
    281                                 uint32_t lookahead)
    282                    : soclib::tlmt::BaseModule(name),
    283                      m_index(initiator_index),
    284                      m_lookahead(lookahead),
    285                      m_counter(0),
    286                    p_vci("vci", new tlmt_core::tlmt_callback<VciSimpleInitiator,soclib::tlmt::vci_rsp_packet<vci_param> *>(
    287                                          this, &VciSimpleInitiator<vci_param>::rspReceived), &c0)
    288 {
    289         SC_THREAD(behavior);
    290 }
    291 
    292 }}
     446
     447  } // end while true
     448  setActivity(false);
     449} // end initiator_thread
     450
     451
     452/////////////////////////////////////////////////////////////////////////////////////
     453// Virtual Fuctions  tlm::tlm_bw_transport_if (VCI SOCKET)
     454/////////////////////////////////////////////////////////////////////////////////////
     455
     456/// receive the response packet from target socket
     457tmpl (tlm::tlm_sync_enum)::my_nb_transport_bw // inbound nb_transport_bw
     458( soclib_vci_types::vci_payload_type &payload,       // VCI payload
     459  soclib_vci_types::tlmt_phase_type   &phase,        // tlm phase
     460  sc_core::sc_time                   &rspTime        // the response timestamp
     461 )
     462{
     463  switch(phase){
     464  case soclib::tlmt::TLMT_RSP :
     465    setLocalTime(rspTime);
     466    m_rspEvent.notify(0 * UNIT_TIME);
     467    break;
     468  case soclib::tlmt::TLMT_INFO :
     469    payload.set_local_time_ptr(&m_localTime);
     470    payload.set_activity_ptr(&m_activity);
     471    break;
     472  }
     473  return tlm::TLM_COMPLETED;
     474} // end backward nb transport
    293475
    294476}}}
     
    296478= D) VCI target modeling =
    297479
    298 In the proposed example, the target handles two types of command: a read burst of 8 words, and a write burst of 8 words.
    299 To simplify the model, there is no error management.
    300 
    301 The class '''!VciSimpleTarget''' inherits from the class '''!BaseModule'''. The class '''!VciSimpleTarget''' contains a member
    302 variable '''p_vci''' of type '''!VciTarget'''. This object has a template parameter '''<vci_param>''' defining the widths of
    303 the VCI ADDRESS and DATA fields.
     480In the proposed example, the target handles all VCI commands in the same way. To simplify the model, there is no real error management.
     481
     482The class '''!my_target''' inherits from the class '''sc_core::sc_module'''. The class '''!my_target''' contains a member
     483variable '''p_vci_target''' of type '''tlmt_simple_target_socket'''. This object has 3 template parameters, that are identical to
     484those used for declaring initiator ports (see above).
    304485
    305486== D.1) Receiving a VCI command packet ==
    306487
    307 To receive a VCI command packet, a call-back function must be defined as a member function of the class '''!VciSimpleTarget'''.
    308 This call-back function (named '''cmdReceived()''' in the example), will be executed each time a VCI command packet is received on
    309 the '''p_vci''' port. The function name is not constrained, but the arguments must respect the following prototype:
    310 {{{
    311 tlmt_core::tlmt_return &cmdReceived(soclib::tlmt::vci_cmd_packet<vci_param> *pkt,
    312          const tlmt_core::tlmt_time &time,
    313          void *private_data);
     488To receive a VCI command packet, a call-back function must be defined as a member function of the class '''my_target'''.
     489This call-back function (named '''my_nb_transport_fw()''' in the example), will be executed each time a VCI command packet is received on
     490the '''p_vci_target''' port. The function name is not constrained, but the arguments must respect the following prototype:
     491{{{
     492  tlm::tlm_sync_enum my_nb_transport_fw               /// sync status
     493  ( soclib_vci_types::vci_payload_type &payload,      ///< VCI payload pointer
     494    soclib_vci_types::tlmt_phase_type   &phase,       ///< transaction phase
     495    sc_core::sc_time                   &time);        ///< time
    314496}}} 
    315 For the read and write transactions, the actual data transfer is performed by this '''cmdReceived()''' function.
    316 To avoid multiple data copies, only the pointer on the initiator data buffer is transported in the VCI command packet
    317 (source buffer for a write transaction, or destination buffer for a read transaction).
     497
    318498
    319499== D.2) Sending a VCI response packet ==
    320500
    321 To send a VCI response packet the '''cmdReceived()''' function must use the '''send()''' method, that is a member function of
    322 the class '''!VciTarget''', and has the following prototype:
    323 {{{
    324 void send(soclib::tlmt::vci_rsp_packet<vci_param> *rsp, // pointer to a VCI response packet     
    325           tlmt_core::tlmt_time time);                   // initiator local time
     501To send a VCI response packet the '''my_nb_transport_fw()''' function must use the '''nb_transport_bw()''' method, that is a member function of
     502the class '''tlmt_simple_target_socket''', and has the following prototype:
     503{{{
     504        payload.set_response_status(soclib::tlmt::TLMT_OK_RESPONSE);
     505 
     506        phase = soclib::tlmt::TLMT_VCI_RSP;
     507        time = time + (nwords * UNIT_TIME);
     508 
     509        p_vci_target->nb_transport_bw(payload, phase, time);
    326510}}}
    327511For a reactive target, the response packet time is computed as the command packet time plus the target intrinsic latency.
     
    329513== D.3) Target Constructor ==
    330514
    331 The constructor of the class '''!VciSimpleTarget''' must initialize all the member variables, including
    332 the '''p_vci''' port. The '''cmdReceived()''' call-back function being executed in the context of the thread sending the command packet,
    333 a link between the '''p_vci''' port and the call-back function must be established.
    334 The '''!VciTarget''' constructor must be called with the following arguments:
    335 {{{
    336 p_vci("vci", new tlmt_core::tlmt_callback<VciSimpleTarget,soclib::tlmt::vci_cmd_packet<vci_param> *>(
    337                                    this, &VciSimpleTarget<vci_param>::cmdReceived))
    338 }}}
    339  
     515The constructor of the class '''!my_target''' must initialize all the member variables, including
     516the '''p_vci_target''' port. The '''my_nb_transport_fw()''' call-back function being executed in the context of the thread sending
     517the command packet, a link between the '''p_vci_target''' port and the call-back function must be established.
     518The '''my_target''' constructor must be called with the following arguments:
     519{{{
     520  p_vci_target.register_nb_transport_fw(this, &my_target::my_nb_transport_fw);
     521}}}
     522
     523where '''my_nb_transport_fw''' is the name of the forward callback function.
     524
    340525== D.4) VCI target example ==
    341526 {{{
    342527
    343 ////////////////////////// vci_simple_target.h ////////////////////////////////
    344 
    345 #ifndef VCI_SIMPLE_TARGET_H
    346 #define VCI_SIMPLE_TARGET_H
    347 
    348 #include <tlmt>
    349 #include "tlmt_base_module.h"
    350 #include "vci_ports.h"
    351 
    352 namespace soclib { namespace tlmt {
    353 
    354 template<typename vci_param>
    355 class VciSimpleTarget
    356     : public soclib::tlmt::BaseModule
    357 {
    358 private:
    359     tlmt_core::tlmt_return m_return;
    360     uint32_t m_index;
    361     uint32_t m_latency;
    362     soclib::tlmt::vci_rsp_packet<vci_param> rsp;
    363    
    364 public:
    365     soclib::tlmt::VciTarget<vci_param> p_vci;
    366 
    367     VciSimpleTarget(sc_core::sc_module_name name,
    368               uint32_t  targetIndex,
    369               uint32_t  latency);
    370 
    371     tlmt_core::tlmt_return &cmdReceived(soclib::tlmt::vci_cmd_packet<vci_param> *pkt,
    372          const tlmt_core::tlmt_time &time,
    373          void *private_data);
     528////////////////////////// my_target.h ////////////////////////////////
     529
     530#ifndef __MY_TARGET_H__
     531#define __MY_TARGET_H__
     532
     533#include "tlm.h"                        // TLM headers
     534#include "tlmt_transactions.h"          // VCI headers
     535#include "tlmt_simple_target_socket.h"  // VCI SOCKET
     536#include "mapping_table.h"
     537#include "soclib_endian.h"
     538
     539class my_target
     540  : public sc_core::sc_module
     541{
     542 private:
     543  typedef soclib::tlmt::VciParams<uint32_t,uint32_t,4> vci_param;
     544
     545  uint32_t m_targetid;
     546  soclib::common::MappingTable m_mt;
     547
     548
     549  /////////////////////////////////////////////////////////////////////////////////////
     550  // Virtual Fuctions  tlm::tlm_fw_transport_if (VCI SOCKET)
     551  /////////////////////////////////////////////////////////////////////////////////////
     552 
     553  // receive command from initiator
     554  tlm::tlm_sync_enum my_nb_transport_fw               /// sync status
     555  ( soclib_vci_types::vci_payload_type &payload,      ///< VCI payload pointer
     556    soclib_vci_types::tlmt_phase_type   &phase,       ///< transaction phase
     557    sc_core::sc_time                   &time);        ///< time
     558
     559 protected:
     560  SC_HAS_PROCESS(my_target);
     561 public:
     562  tlmt_simple_target_socket<my_target,32,soclib_vci_types> p_vci_target;        ///<  VCI target socket
     563
     564  my_target(sc_core::sc_module_name            name,
     565         const soclib::common::IntTab       &index,
     566         const soclib::common::MappingTable &mt);
     567 
     568  ~my_target();
    374569};
    375570
    376 }}
    377 
    378 #endif
    379 
    380 ////////////////////////// vci_simple_target.cpp ////////////////////////////////
    381 
    382 #include "../include/vci_simple_target.h"
    383 
    384 namespace soclib { namespace tlmt {
    385 
    386 #define tmpl(x) template<typename vci_param> x VciSimpleTarget<vci_param>
    387 
    388 tmpl(tlmt_core::tlmt_return&)::cmdReceived(soclib::tlmt::vci_cmd_packet<vci_param> *pkt,
    389         const tlmt_core::tlmt_time &time,
    390         void *private_data)
    391 {
    392     uint32_t m_data[128];
    393        
    394     if(pkt->cmd == vci_param::VCI_CMD_WRITE) {
    395         for(int i = 0 ; i < pkt->length ; i++)
    396                 m_data[i] = cmd->buf[i];
    397         }
    398     if(pkt->cmd == vci_param::VCI_CMD_READ) {
    399         for(int i = 0 ; i < pkt->length ; i++)
    400                 cmd->buf[i] = m_data[i];
    401         }
    402     rsp.srcid = pkt->srcid;
    403     rsp.trdid  = pkt->trdid;
    404     rsp.pktid = pkt->pktid;
    405     rsp.length = pkt->length;
    406     rsp.error = 0;
    407     p_vci.send(&m_rsp, time+tlmt_core::tlmt_time(latency+pkt->length)) ;
    408     m_return.time=time+tlmt_core::tlmt_time(latency+pkt->length;
    409     return (m_return);
    410 }
    411 
    412 tmpl(/**/)::VciSimpleTarget(sc_core::sc_module_name name,
    413               uint32_t  targetIndex,
    414               uint32_t  latency)
    415         : soclib::tlmt::BaseModule(name),
    416         m_index(targetIndex),
    417         m_latency(latency),
    418         p_vci("vci", new tlmt_core::tlmt_callback<VciSimpleTarget,soclib::tlmt::vci_cmd_packet<vci_param> *>(
    419                                    this, &VciSimpleTarget<vci_param>::cmdReceived))
    420 {
    421 }
    422 
    423 }}
     571#endif
     572
     573////////////////////////// my_target.cpp ////////////////////////////////
     574
     575#include "my_target.h"
     576
     577#ifndef MY_TARGET_DEBUG
     578#define MY_TARGET_DEBUG 1
     579#endif
     580
     581#define tmpl(x) x my_target
     582
     583//////////////////////////////////////////////////////////////////////////////////////////
     584// CONSTRUCTOR
     585//////////////////////////////////////////////////////////////////////////////////////////
     586tmpl(/**/)::my_target
     587           ( sc_core::sc_module_name name,
     588             const soclib::common::IntTab &index,
     589             const soclib::common::MappingTable &mt)
     590           : sc_module(name),
     591           m_mt(mt),
     592           p_vci_target("p_vci_target")
     593{
     594  //register callback fuction
     595  p_vci_target.register_nb_transport_fw(this, &my_target::my_nb_transport_fw);
     596 
     597  m_id = m_mt.indexForId(index);
     598}
     599
     600tmpl(/**/)::~my_target(){}
     601
     602/////////////////////////////////////////////////////////////////////////////////////
     603// Virtual Fuctions  tlm::tlm_fw_transport_if VCI SOCKET
     604/////////////////////////////////////////////////////////////////////////////////////
     605
     606//nb_transport_fw implementation calls from initiators
     607tmpl(tlm::tlm_sync_enum)::my_nb_transport_fw                            // non-blocking transport call through Bus
     608                         ( soclib_vci_types::vci_payload_type &payload, // VCI payload pointer
     609                           soclib_vci_types::tlmt_phase_type   &phase,  // transaction phase
     610                           sc_core::sc_time                   &time)    // time
     611{
     612  int nwords = payload.get_data_length() / vci_param::nbytes;
     613  switch(payload.get_command()){
     614  case soclib::tlmt::VCI_READ_COMMAND:
     615  case soclib::tlmt::VCI_WRITE_COMMAND:
     616  case soclib::tlmt::VCI_LOCKED_READ_COMMAND:
     617  case soclib::tlmt::VCI_STORE_COND_COMMAND:
     618      {
     619#if MY_TARGET_DEBUG
     620        std::cout << "[RAM " << m_id << "] Receive from source " << payload.get_src_id() <<" a packet "<< payload.get_pkt_id() << " Time = "  << time.value() << std::endl;
     621#endif
     622
     623        payload.set_response_status(soclib::tlmt::TLMT_OK_RESPONSE);
     624 
     625        phase = soclib::tlmt::TLMT_VCI_RSP;
     626        time = time + (nwords * UNIT_TIME);
     627 
     628#if MY_TARGET_DEBUG
     629        std::cout << "[RAM " << m_id << "] Send to source "<< payload.get_src_id() << " a anwser packet " << payload.get_pkt_id() << " Time = "  << time.value() << std::endl;
     630#endif
     631 
     632        p_vci_target->nb_transport_bw(payload, phase, time);
     633        return tlm::TLM_COMPLETED;
     634      }
     635      break;
     636    default:
     637      break;
     638  }
     639 
     640  //send error message
     641  payload.set_response_status(soclib::tlmt::TLMT_ERROR_RESPONSE);
     642 
     643  phase = soclib::tlmt::TLMT_VCI_RSP;
     644  time = time + nwords * UNIT_TIME;
     645 
     646#if MY_TARGET_DEBUG
     647  std::cout << "[RAM " << m_id << "] Address " << payload.get_address() << " does not match any segment " << std::endl;
     648  std::cout << "[RAM " << m_id << "] Send to source "<< payload.get_src_id() << " a error packet with time = "  << time.value() << std::endl;
     649#endif
     650  p_vci_target->nb_transport_bw(payload, phase, time);
     651  return tlm::TLM_COMPLETED;
     652}
    424653
    425654}}}
     
    457686module describing a VCI target. For a VCI target, the local clock is actually the clock associated to the corresponding arbitration
    458687thread contained in the '''!VciVgmn''' module.
    459 
    460 As described in Figure 4, when a VCI command packet - sent by the corresponding arbitration thread - is received by a VCI target,
    461 two synchronization mechanisms are activated :
    462  * The '''cmdReceived()''' function sends a VCI response packet with an associated time to the source initiator, through
    463  the '''!VciVgmn''' response network. The corresponding time can be used to update the initiator local clock.
    464  * The '''cmdReceived()''' function returns a time to the arbitration thread. This time is used to update the arbitration thread local
    465  clock. 
    466 
    467 [[Image(tlmt_figure_4.png, nolink)]]
    468 
    469 = F) Interrupt modeling =
    470 
    471 Interrupts are asynchronous events that are not carried by the VCI network.
    472 
    473 As illustrated in Figure 5, each interrupt line is modeled by a specific point to point, uni-directional channel. This channel uses two ports of
    474 type '''tlmt_core::tlmt_out<bool>''' and '''tlmt_core::tlmt_in<bool>''' that must be declared as member variables of the source and
    475 destination modules respectively.
    476 
    477 [[Image(tlmt_figure_5.png, nolink)]]
    478 
    479 == F.1) Source modeling ==
    480 
    481 The source module (named '''!VciSimpleSourceInterrupt''' in this example) must contain a member variable '''p_irq''' of
    482 type '''tlmt_core::tlmt_out<bool>'''. To activate, or desactivate an interruption, the source module must use the '''send()''' method,
    483 that is a member function of the '''tlmt_core::tlmt_out<bool>''' class. These interrupt packets transport both a Boolean,
    484 and a time. The '''send()''' prototype is defined as follows :
    485 {{{
    486 void  send( bool  val, const tlmt_core::tlmt_time &time)
    487 }}}
    488 
    489 == F.2) Destination modeling ==
    490 
    491 The destination module (named here '''!VciProcessor''') must contain a member variable '''p_irq''' of type
    492 '''tlmt_core::tlmt_in<bool>''', and a call-back function (named here '''irqReceived()''' that is executed when an interrupt
    493 packet is received on the '''p_irq''' port.
    494 
    495 A link between the '''p_irq''' port and the call-back function must be established by the port constructor in the constructor of
    496 the class '''VciProcessor''' :
    497 {{{
    498 tlmt_core::tlmt_callback < VciProcessor,bool >(this, &VciProcessor < iss_t,
    499            vci_param >::irqReceived);
    500 }}}
    501 
    502 In the Parallel Discrete Event Simulation, the pessimistic approach relies on the fact that any PDES process is not allowed to update
    503 his local time until it has received messages on all its input ports with times greater than its local time.
    504 
    505 Therefore, a SC_THREAD modeling the behavior of a processor containing an '''tlmt_core::tlmt_in<bool>''' should in principle
    506 wait a timestamped packet on its interrupt port before executing instructions. However, such a behavior would be very inefficient,
    507 and is prone to dead-lock situations.
    508 
    509 The recommended policy for handling interrupts is the following:
    510  * The call-back function '''irqReceived()''' sets the member variables '''m_irqpending''' and '''m_irqtime''', when a interrupt packet
    511  is received on the '''p_irq''' port.
    512  * The '''execLoop()''' thread must test the '''m_irqpending''' variable at each cycle (i.e. in each iteration of
    513  the infinite loop).
    514  * If there is no interrupt pending, the thread continues its execution. If an interrupt is pending, and the interrupt time is greater
    515  than the local time, the thread continues execution. If the interrupt time is equal or smaller than the local time, the interrupt
    516  is handled.
    517 
    518 Such a violation of the the pessimistic parallel simulation principles creates a loss of accuracy on the interrupt handling
    519 timestamp. This loss of accuracy in the TLM-T simulation is acceptable, as interrupts are asynchronous events, and the timing error
    520 is bounded by the '''m_lookahead''' parameter.
    521 
    522 == F.3)  Processor with interrupt example ==
    523 
    524 {{{
    525 
    526 ////////////////////////// vci_processor.h ////////////////////////////////
    527 
    528 namespace soclib { namespace tlmt {
    529 
    530 template<typename iss_t,typename vci_param>
    531 class VciProcessor
    532     : public soclib::tlmt::BaseModule
    533 {
    534     tlmt_core::tlmt_thread_context c0;
    535     sc_core::sc_event m_rsp_received;
    536     tlmt_core::tlmt_return m_return;
    537     bool  m_irqpendig;  // pending interrupt request
    538     tlmt_core::tlmt_time  m_irqtime;  // irq date
    539     uint32_t  m_counter;  // iteration counter
    540     uint32_t  m_lookahead;  // lookahead value
    541    
    542 protected:
    543     SC_HAS_PROCESS(VciProcessor);
    544 
    545 public:
    546     soclib::tlmt::VciInitiator<vci_param> p_vci;
    547     tlmt_core::tlmt_in<bool> p_irq;
    548 
    549     VciProcessor( sc_core::sc_module_name name, int id );
    550 
    551     tlmt_core::tlmt_return &rspReceived(soclib::tlmt::vci_rsp_packet<vci_param> *pkt,
    552                 const tlmt_core::tlmt_time &time,
    553                 void *private_data);
    554     tlmt_core::tlmt_return &irqReceived(bool,
    555                 const tlmt_core::tlmt_time &time,
    556                 void *private_data);
    557     void execLoop();
    558 };
    559 
    560 }}
    561 
    562 ////////////////////////// vci_processor.cpp ////////////////////////////////
    563 
    564 #include "../include/vci_processor.h"
    565 
    566 namespace soclib
    567 {
    568   namespace tlmt
    569   {
    570 
    571 #define tmpl(x) template<typename iss_t, typename vci_param> x VciProcessor<vci_param>
    572 
    573     tmpl (tlmt_core::tlmt_return &)::rspReceived (soclib::tlmt:: vci_rsp_packet < vci_param > *pkt,
    574                                                   const tlmt_core:: tlmt_time & time, void *private_data)
    575     {
    576       if (pkt->cmd == vci_param::CMD_WRITE)
    577         m_write_error = (pkt->error != 0);
    578       else
    579         m_write_error = false;
    580       if (pkt->cmd == vci_param::CMD_READ)
    581         m_read_error = (pkt->error != 0);
    582       else
    583         m_read_error = false;
    584       m_rsptime = time + tlmt_core::tlmt_time (pkt->length);
    585       m_vci_pending = false;
    586       m_rsp_received.notify (sc_core::SC_ZERO_TIME);
    587 
    588       return m_return;
    589     }
    590 
    591     tmpl (tlmt_core::tlmt_return &)::irqReceived (bool v, const tlmt_core::
    592                                                   tlmt_time & time, void *private_data)
    593     {
    594       m_irqpending = val;
    595       m_irqtime = time;   
    596    
    597       return m_return;
    598     }
    599 
    600 
    601     tmpl (void)::execLoop ()
    602         {
    603                 while(1) {
    604                         ...
    605                         // test interrupts
    606                         if (m_irqpending && (m_irqtime <= c0.time()))
    607                         {
    608                                 // interrupt handling   
    609                         }
    610                                 ...
    611                         // lookahead management
    612                         m_counter++ ;
    613                         if (m_counter >= m_lookahead) {
    614                                 m_counter = 0 ;
    615                                 sc_core::wait(sc_core::SC_ZERO_TIME) ;
    616                         } // end if
    617                         c0.set_time(c0.time()+tlmt_core::tlmt_time(1)) ;
    618                 } // end while
    619         }
    620        
    621   tmpl ( /**/)::VciProcessor(
    622           sc_core::sc_module_name name,
    623           int id )
    624 : soclib::tlmt::BaseModule (name),
    625   m_counter (0),
    626   m_lookahead (10),
    627   p_vci("vci",new tlmt_core::tlmt_callback<VciProcessor,vci_rsp_packet<vci_param>*>(
    628         this,&VciProcessor<vci_param>::rspReceived),&c0),
    629   p_irq("irq",new tlmt_core::tlmt_callback<VciProcesspr,bool>(
    630         this,&VciProcessor<vci_param>::irqReceived))
    631     {
    632       SC_THREAD (execLoop);
    633     }
    634 
    635 }}
    636 
    637 }}}
    638