Changes between Version 95 and Version 96 of Writing Rules/Tlmt
- Timestamp:
- Mar 2, 2009, 2:11:40 PM (15 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Writing Rules/Tlmt
v95 v96 21 21 the TLM2.0 library, but can also be used also with others simulation engines, especially distributed, parallelized simulation engines. 22 22 23 The pessimistic PDES algorithm used relies on temporal filtering. An active component is only allowed to process when it 24 has sufficient timing information on its input ports. For example, an interconnect is only allowed to let a packet reach 25 a given target only when all the initiators that are connected to it have sent at least one packet with their local times. 26 Several experiments have been realized to identify the best way to perform this temporal filtering. The previous 27 implementation relied on sollicited null message, i.e. the interconnect asks all the initiators for their times. This 28 solution only impacts the way the interconnect is written, and the initiators are not aware of the interconnect requests. 29 The experiments have shown that this technique simplifies the writing of the initiator models but also has a strong 30 impact on the simulation time, as the interconnect spends much of its effort consulting the time of the initiators 31 and not passing packets from initiators to targets. The induced overhead is about 90%. 32 33 The solution retained is now to strictly follow the Chandy-Misra pessimistic algorithm and to reverse the synchronization 34 process by letting the initiators transmit their local time to others according to their own null message policy. The 35 interconnect is much simpler to write, but the initiators have to be modified in order to handle explicitely the 36 sending of null messages. The performance of the simulation is therefore directly linked to the number of generated null 37 messages. When writing an initiator model, this number directly corresponds to the period that separates the sending of two successive null messages. 38 39 The models described with the writing rules defined herein are syntactically compliant with the TLM2.0 standard, but do 40 not respect its semantics. In particular, the third parameter of the transport functions is considered to be an absolute 41 time and not relative to a global simulation time that does prevail anymore. 42 23 43 The examples presented below use the VCI/OCP communication protocol selected by the SoCLib project, 24 44 but the TLM-T approach described here is very flexible, and is not limited to the VCI/OCP communication protocol. … … 73 93 74 94 The data members of the '''soclib_payload_extension''' can be accessed through the following access functions: 75 and several member functions: 76 {{{ 95 {{{ 96 // Command related method 97 bool is_read() const {return (m_soclib_command == VCI_READ_COMMAND);} 98 void set_read() {m_soclib_command = VCI_READ_COMMAND;} 99 bool is_write() const {return (m_soclib_command == VCI_WRITE_COMMAND);} 100 void set_write() {m_soclib_command = VCI_WRITE_COMMAND;} 101 bool is_locked_read() const {return (m_soclib_command == VCI_LOCKED_READ_COMMAND);} 102 void set_locked_read() {m_soclib_command = VCI_LOCKED_READ_COMMAND;} 103 bool is_store_cond() const {return (m_soclib_command == VCI_STORE_COND_COMMAND);} 104 void set_store_cond() {m_soclib_command = VCI_STORE_COND_COMMAND;} 105 bool is_null_message() const {return (m_soclib_command == VCI_NULL_MESSAGE);} 106 void set_null_message() {m_soclib_command = VCI_NULL_MESSAGE;} 107 bool is_active() const {return (m_soclib_command == VCI_ACTIVE);} 108 void set_active() {m_soclib_command = VCI_ACTIVE;} 109 bool is_inactive() const {return (m_soclib_command == VCI_INACTIVE);} 110 void set_inactive() {m_soclib_command = VCI_INACTIVE;} 111 vci_command get_command() const {return m_soclib_command;} 112 void set_command(const vci_command command) {m_soclib_command = command;} 113 114 unsigned int get_src_id(){ return m_src_id; } 115 unsigned int get_trd_id(){ return m_trd_id; } 116 unsigned int get_pkt_id(){ return m_pkt_id; } 117 118 void set_src_id(unsigned int id) { m_src_id = id; } 119 void set_trd_id(unsigned int id) { m_trd_id = id; } 120 void set_pkt_id(unsigned int id) { m_pkt_id = id; } 77 121 78 122 }}} … … 82 126 the following code: 83 127 {{{ 128 tlm::tlm_generic_payload *payload_ptr = new tlm::tlm_generic_payload(); 129 tlm::tlm_phase phase; 130 soclib_payload_extension *extension_ptr = new soclib_payload_extension(); 131 ... 132 84 133 // set the values in tlm payload 85 134 payload_ptr->set_command(tlm::TLM_IGNORE_COMMAND); 86 payload_ptr->set_address( address[idx]);135 payload_ptr->set_address(0x10000000]); 87 136 payload_ptr->set_byte_enable_ptr(byte_enable); 88 137 payload_ptr->set_byte_enable_length(nbytes); … … 110 159 This class inherits from the standard SystemC '''sc_core::sc_module''' class, that acts as the root class for all TLM-T modules. 111 160 161 TLM2.0 uses the notion of local time to allow temporal decoupling, that is the possibility for an initiator to be ahead 162 in time without synchronization. The temporal barrier associated to a model is called the time quantum in TLM2.0 and 163 is relative to the global simulation time. When the time quantum is reached, it is reset to 0. In the PDES paradigm, 164 the timestamps are absolute and this technique can not be used directly. 165 166 To respect the PDES principle, the initiator has its own local time, and runs independently of other initiators. This 167 assertion is very strong and has a deep impact on the models: '''The global SystemC time can not be used'''. This 168 local time is very similar to the local time proposed by the TLM2.0 standard, but it operates in a very different way 169 because it does not rely on the global simulation time. 170 112 171 The initiator local time is contained in a member variable named '''m_local_time''', of type '''sc_core::sc_time'''. The 113 172 local time can be accessed with the following accessors: '''addLocalTime()''', '''setLocalTime()''' … … 122 181 123 182 The boolean member variable '''m_activity_status''' indicates if the initiator is currently active. 124 It is used by the arbitrationthreads contained in the '''vci_vgmn''' interconnect, as described in section F.183 It is used by the temporal filtering threads contained in the '''vci_vgmn''' interconnect, as described in section F. 125 184 The corresponding access functions are '''setActivity()''' and '''getActivity()'''. 126 185 {{{ … … 133 192 The '''execLoop()''' method, describing the initiator behaviour must be declared as a member function. 134 193 135 The '''my_initiator''' class contains a member variable '''p_vci_init''', of type '''tlm t_simple_initiator_socket''', representing the VCI initiator port.194 The '''my_initiator''' class contains a member variable '''p_vci_init''', of type '''tlm_utils::simple_initiator_socket''', representing the VCI initiator port. 136 195 137 196 It must also define an interface function to handle the VCI response packets. … … 144 203 145 204 tlm::tlm_sync_enum nb_transport_fw 146 ( soclib_vci_types::tlm_payload_type &payload, // payload 147 soclib_vci_types::tlm_phase_type &phase, // phase (TLMT_CMD) 148 sc_core::sc_time &time); // local time 149 }}} 150 151 The first argument is a pointer to the payload, the second represents the phase, and the third 205 ( tlm::tlm_generic_payload &payload, // payload 206 tlm::tlm_phase &phase, // phase (TLM::BEGIN_REQ) 207 sc_core::sc_time &time); // absolute local time 208 }}} 209 210 The first argument is a pointer to the payload (including the soclib payload extension), 211 the second represents the phase (always set to TLM::BEGIN_REQ for requests), and the third 152 212 argument contains the initiator local time. The return value is not used in this TLM-T implementation. 153 213 … … 160 220 161 221 To receive a VCI response packet, an interface function must be defined as a member function of the 162 class '''my_initiator'''. This function (named ''' vci_rsp_received()''' in the example), must be linked to222 class '''my_initiator'''. This function (named '''nb_transport_bw()''' in the example), must be linked to 163 223 the '''p_vci_init''' port, and is executed each time a VCI response packet is received on the '''p_vci_init''' port. 164 224 The function name is not constrained, but the arguments must respect the following prototype: 165 225 {{{ 166 tlm::tlm_sync_enum vci_rsp_received167 ( soclib_vci_types::tlm_payload_type&payload, // payload168 soclib_vci_types::tlm_phase_type &phase, // phase (TLMT_RSP)226 tlm::tlm_sync_enum nb_transport_bw 227 ( tlm::tlm_generic_payload &payload, // payload 228 tlm::tlm_phase &phase, // phase (TLM::BEGIN_RESP) 169 229 sc_core::sc_time &time); // response time 170 230 }}} 171 231 The return value (type tlm::tlm_sync_enum) is not used in this TLM-T implementation, and must be sytematically set to tlm::TLM_COMPLETED. 172 232 173 In the general case, the actions executed by the interface function depend on both the phase argument, and on the transaction types (defined in the payload).174 For sake of simplicity, the interface function proposed below does not make any distinction between transaction types.175 176 233 == D.4) Initiator Constructor == 177 234 178 235 The constructor of the class '''my_initiator''' must initialize all the member variables, including 179 the '''p_vci_init''' port. The ''' vci_rsp_received()''' function being executed in the context of the thread sending236 the '''p_vci_init''' port. The '''nb_transport_bw()''' function being executed in the context of the thread sending 180 237 the response packet, a link between the '''p_vci_init''' port and this interface function must be established. 181 238 182 239 The constructor for the '''p_vci_init''' port must be called with the following arguments: 183 240 {{{ 184 p_vci_init.register_nb_transport_bw(this, &my_initiator:: vci_rsp_received);185 }}} 186 187 == D.5) Lookaheadparameter ==241 p_vci_init.register_nb_transport_bw(this, &my_initiator::nb_transport_bw); 242 }}} 243 244 == D.5) Time quantum parameter == 188 245 189 246 The SystemC simulation engine behaves as a cooperative, non-preemptive multi-tasks system. Any thread in the system must stop execution … … 191 248 it does not execute blocking communication (such as a processor that has all code and data in the L1 caches). 192 249 193 To solve this issue, it is necessary to define -for each initiator module- a ''' lookahead''' parameter. This parameter defines the maximum194 number of cycles that can be executed by the thread before it is descheduled. The '''lookahead''' parameter allows the system designer250 To solve this issue, it is necessary to define -for each initiator module- a '''time quantum''' parameter. This parameter defines the maximum 251 delay that separates the sending of two successive null messages. The '''time quantum''' parameter allows the system designer 195 252 to bound the de-synchronization time interval between threads. 196 253 … … 198 255 and a slower simulation speed. 199 256 257 This time quantum parameter is implemented using the '''QuantumKeeper''' construct already available in TLM2.0. The main 258 difference comes from the fact that this class is just used to manage the synchronization interval between two null 259 messages. More precisely, the '''sync()''' function of '''QuantumKeeper''' is not used at all, because it implicitely 260 calls a '''wait(x)''' statement (x being a time delay, which is valid in TLM2.0 but forbidden in the presented 261 distributed time approach). 262 263 200 264 == D.6) VCI initiator example == 201 265 202 266 {{{ 203 267 204 ////////////////////////// my_initiator.h ////////////////////////////////205 206 #include "tlm.h" // TLM headers207 #include "tlmt_transactions.h" // TLM-T headers208 #include "tlmt_simple_initiator_socket.h" // TLM-T initiator socket209 #include "mapping_table.h" // mapping Table210 211 class my_initiator // my_initiator212 : public sc_core::sc_module // inherit from SC module base clase213 {214 private:215 216 typedef soclib::tlmt::VciParams<uint32_t,uint32_t,4> vci_param;217 218 //////////////////////219 // Member Variables220 //////////////////////221 uint32_t m_srcid;222 soclib::common::MappingTable m_mt;223 uint32_t m_counter;224 uint32_t m_lookahead;225 sc_core::sc_time m_local_time;226 bool m_activity_status;227 sc_core::sc_event m_rsp_event;228 229 soclib_vci_types::tlm_payload_type m_payload;230 soclib_vci_types::tlm_phase_type m_phase;231 232 ///////////////////////233 // Member Functions234 ///////////////////////235 void execLoop(void); // initiator thread236 bool getActivity(void); // get the activity state237 void setActivity(bool t); // set the activity status (true if the component is active)238 sc_core::sc_time getLocalTime(void); // get the local time239 void setLocalTime(sc_core::sc_time& t); // set the local time240 void addLocalTime(sc_core::sc_time t); // add a value to the local time241 tlm::tlm_sync_enum vci_rsp_received // interface function to receive VCI response242 ( soclib_vci_types::tlm_payload_type &payload, // payload243 soclib_vci_types::tlm_phase_type &phase, // phase244 sc_core::sc_time &time); // time245 246 protected:247 248 SC_HAS_PROCESS(my_initiator);249 250 public:251 252 /////////////////253 // ports254 /////////////////255 tlmt_simple_initiator_socket<my_initiator,32,soclib_vci_types> p_vci_init; // VCI initiator port256 257 //constructor258 my_initiator( // constructor259 sc_core::sc_module_name name, // module name260 const soclib::common::IntTab &index, // index of mapping table261 const soclib::common::MappingTable &mt, // mapping table262 uint32_t lookahead); // lookahead263 };264 265 ////////////////////////// my_initiator.cpp ////////////////////////////////266 267 /////////////////268 // Constructor269 /////////////////270 my_initiator::my_initiator271 ( sc_core::sc_module_name name, // module name272 const soclib::common::IntTab &index, // index of mapping table273 const soclib::common::MappingTable &mt, // mapping table274 uint32_t lookahead) // lookahead275 : sc_module(name), // init module name276 m_mt(mt), // mapping table277 p_vci_init("socket") // vci initiator socket name278 {279 // link the interface function the TLM-T INITIATOR SOCKET280 p_vci_init.register_nb_transport_bw(this, &my_initiator::vci_rsp_received);281 282 // initiator identification283 m_srcid = mt.indexForId(index);284 285 //lookahead control286 m_counter = 0;287 m_lookahead = lookahead;288 289 //initialize the local time290 m_local_time = 0 * UNIT_TIME;291 292 // initialize the activity variable293 setActivity(true);294 295 // register thread process296 SC_THREAD(execLoop);297 }298 299 //////////////////////300 // Access Functions301 //////////////////////302 bool my_initiator::getActivity() { return m_activity; }303 my_initiator::setActivity(bool t) { m_activity = t; }304 sc_core::sc_time my_initiator::getLocalTime() { return m_local_time; }305 my_initiator::setLocalTime(sc_core::sc_time t) { m_local_time = t; }306 my_initiator::addLocalTime(sc_core::sc_time t) { m_local_time += t; }307 308 ///////////////////////309 // thread310 ///////////////////////311 my_initiator::execLoop(void)312 {313 uint32_t address = 0x10000000;314 uint32_t data_int = 0xAABBCCDD;315 unsigned char data[4];316 unsigned char byte_enable[4];317 int nbytes = 4;318 319 for(int i=0; i<nbytes; i++) byte_enable[i] = tlm::TLM_BYTE_ENABLED;320 321 while ( true ) {322 // increase local time323 addLocalTime(10 * UNIT_TIME);324 // prepare payload (including int to char translation)325 m_payload.itoa(data_int, data, 0);326 m_payload.set_write();327 m_payload.set_address(address);328 m_payload.set_byte_enable_ptr(byte_enable);329 m_payload.set_data_ptr(data);330 m_payload.set_data_length(nbytes);331 m_payload.set_srcid(m_srcid);332 m_payload.set_trdid(0);333 m_payload.set_pktid(0);334 // set the phase335 m_phase= soclib::tlmt::TLMT_CMD;336 // send the VCI command packet...337 p_vci_initiator->nb_transport_fw(m_payload, m_phase, m_local_time);338 // thread is descheduled, waiting for the response339 wait(m_rsp_event);340 // lookahead management341 m_counter++ ;342 if (m_counter >= m_lookahead) {343 m_counter = 0 ;344 wait(sc_core::SC_ZERO_TIME) ;345 }346 } // end while347 348 } // end execLoop()349 350 ///////////////////////////////////////////////////////////////351 // Interface Function to receive the response packet352 ///////////////////////////////////////////////////////////////353 tlm::tlm_sync_enum my_initiator::vci_rsp_received354 ( soclib_vci_types::tlm_payload_type &payload, // payload355 soclib_vci_types::tlm_phase_type &phase, // phase356 sc_core::sc_time &time // time357 )358 {359 switch(phase){360 case soclib::tlmt::TLMT_RSP :361 setLocalTime(time);362 m_rsp_event.notify(0 * UNIT_TIME);363 break;364 case soclib::tlmt::TLMT_INFO :365 payload.set_local_time_ptr(&m_localTime);366 payload.set_activity_ptr(&m_activity);367 break;368 }369 return tlm::TLM_COMPLETED;370 } // end vci_rsp_received()371 372 268 }}} 373 269 … … 379 275 380 276 The class '''my_target''' inherits from the class '''sc_core::sc_module'''. The class '''my_target''' contains a member 381 variable '''p_vci_target''' of type '''tlm t_simple_target_socket''', representing the VCI target port.277 variable '''p_vci_target''' of type '''tlm_utils::simple_target_socket''', representing the VCI target port. 382 278 It contains an interface function to handle the received VCI command packets, as described below. 383 279 … … 385 281 386 282 To receive a VCI command packet, an interface function must be defined as a member function of the class '''my_target'''. 387 This function (named ''' vci_cmd_received()''' in the example), is executed each time a VCI command packet is received on283 This function (named '''nb_transport_fw()''' in the example), is executed each time a VCI command packet is received on 388 284 the '''p_vci_target''' port. The function name is not constrained, but the arguments must respect the following prototype: 389 285 {{{ 390 tlm::tlm_sync_enum vci_cmd_received391 ( soclib_vci_types::tlm_payload_type&payload, // payload392 soclib_vci_types::tlm_phase_type &phase, // phase (TLMT_CMD)286 tlm::tlm_sync_enum nb_transport_fw 287 ( tlm::tlm_generic_payload &payload, // payload 288 tlm::tlm_phase &phase, // phase (TLM::BEGIN_REQ) 393 289 sc_core::sc_time &time); // time 394 290 }}} … … 397 293 == E.3) Sending a VCI response packet == 398 294 399 To send a VCI response packet the call-back function '''vci_cmd_received()''' uses the '''nb_transport_bw()''' method, defined by TLM2.0, that is a member function of 400 the class '''tlmt_simple_target_socket''', and has the same arguments as the '''nb_transport_fw()''' function. 401 Respecting the general TLM2.0 policy, the payload argument refers to the same '''tlmt_vci_payload''' object for both the '''nb_transport_fw()''' and '''nb_transport_bw()''' functions, 295 To send a VCI response packet the call-back function uses the '''nb_transport_bw()''' and has the same arguments as the '''nb_transport_fw()''' function. 296 Respecting the general TLM2.0 policy, the payload argument refers to the same '''tlm_generic_payload''' object for both the '''nb_transport_fw()''' and '''nb_transport_bw()''' functions, 402 297 and the associated interface functions. Only two values are used for the '''response_status''' field in this TLM-T implementation: 403 298 * TLM_OK_RESPONSE … … 406 301 407 302 {{{ 408 tlm::tlm_sync_enum vci_cmd_received(409 soclib_vci_types::tlm_payload_type&payload,410 soclib_vci_types::tlm_phase_type &phase,303 tlm::tlm_sync_enum nb_transport_bw ( 304 tlm::tlm_generic_payload &payload, 305 tlm::tlm_phase &phase, 411 306 sc_core::sc_time &time) 412 307 { 413 308 ... 414 payload.set_response_status( soclib::tlmt::TLM_OK_RESPONSE);415 phase = soclib::tlmt::TLMT_RSP;309 payload.set_response_status(tlm::TLM_OK_RESPONSE); 310 phase = tlm::BEGIN_RESP; 416 311 time = time + (nwords * UNIT_TIME); 417 312 p_vci_target->nb_transport_bw(payload, phase, time); … … 421 316 422 317 The constructor of the class '''my_target''' must initialize all the member variables, including 423 the '''p_vci_target''' port. The ''' vci_cmd_received()''' function being executed in the context of the thread sending318 the '''p_vci_target''' port. The '''nb_transport_fw()''' function being executed in the context of the thread sending 424 319 the command packet, a link between the '''p_vci_target''' port and the call-back function must be established. 425 320 The '''my_target''' constructor must be called with the following arguments: 426 321 {{{ 427 p_vci_target.register_nb_transport_fw(this, &my_target:: vci_cmd_received);322 p_vci_target.register_nb_transport_fw(this, &my_target::nb_transport_fw); 428 323 }}} 429 324 430 325 == E.5) VCI target example == 431 {{{ 432 433 ////////////////////////// my_target.h //////////////////////////////// 434 435 #include "tlm.h" // TLM headers 436 #include "tlmt_transactions.h" // TLM-T headers 437 #include "tlmt_simple_target_socket.h" // TLM-T SOCKET 438 #include "mapping_table.h" 439 #include "soclib_endian.h" 440 441 class my_target 442 : public sc_core::sc_module 443 { 444 private: 445 typedef soclib::tlmt::VciParams<uint32_t,uint32_t,4> vci_param; 446 447 /////////////////////// 448 // Member variables 449 /////////////////////// 450 uint32_t m_targetid; 451 soclib::common::MappingTable m_mt; 452 453 ////////////////////// 454 // Interface Function 455 ////////////////////// 456 tlm::tlm_sync_enum vci_cmd_received 457 ( soclib_vci_types::tlm_payload_type &payload, // payload 458 soclib_vci_types::tlm_phase_type &phase, // phase 459 sc_core::sc_time &time); // time 460 461 protected: 462 SC_HAS_PROCESS(my_target); 463 464 ////////////////////// 465 // ports 466 ////////////////////// 467 public: 468 tlmt_simple_target_socket<my_target,32,soclib_vci_types> p_vci_target; 469 470 ///////////////////// 471 // constructor 472 ///////////////////// 473 my_target(sc_core::sc_module_name name, 474 const soclib::common::IntTab &index, 475 const soclib::common::MappingTable &mt); 476 }; 477 478 ////////////////////////// my_target.cpp //////////////////////////////// 479 480 ///////////////////// 481 // constructor 482 ///////////////////// 483 my_target::my_target 484 ( sc_core::sc_module_name name, 485 const soclib::common::IntTab &index, 486 const soclib::common::MappingTable &mt) 487 : sc_module(name), 488 m_mt(mt), 489 p_vci_target("p_vci_target") 490 { 491 // link the interface function to the VCI port 492 p_vci_target.register_nb_transport_fw(this, &my_target::vci_cmd_received); 493 494 m_targetid = m_mt.indexForId(index); 495 } 496 497 ////////////////////// 498 // Interface function 499 ////////////////////// 500 tlm::tlm_sync_enum my_target::vci_cmd_received 501 ( soclib_vci_types::tlm_payload_type &payload, // payload 502 soclib_vci_types::tlm_phase_type &phase, // phase 503 sc_core::sc_time &time) // time 504 { 505 int nwords = payload.get_data_length() / vci_param::nbytes; 506 switch(payload.get_command()){ 507 case soclib::tlmt::VCI_READ_COMMAND: 508 case soclib::tlmt::VCI_WRITE_COMMAND: 509 case soclib::tlmt::VCI_LOCKED_READ_COMMAND: 510 case soclib::tlmt::VCI_STORE_COND_COMMAND: 511 payload.set_response_status(tlm::TLM_OK_RESPONSE); 512 break; 513 default: 514 payload.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE); 515 break; 516 } 517 phase = soclib::tlmt::TLMT_RSP 518 time = time + (nwords * UNIT_TIME); 519 p_vci_target->nb_transport_bw(payload, phase, time); 520 return tlm::TLM_COMPLETED; 521 } 326 {{{ 327 522 328 523 329 }}}