| 258 | #include "my_initiator.h" // Our header |
| 259 | |
| 260 | my_initiator::my_initiator |
| 261 | ( sc_core::sc_module_name name, // module name |
| 262 | const soclib::common::IntTab &index, // index of mapping table |
| 263 | const soclib::common::MappingTable &mt, // mapping table |
| 264 | uint32_t time_quantum) // time quantum |
| 265 | : sc_module(name), // init module name |
| 266 | m_mt(mt), // mapping table |
| 267 | p_vci_initiator("socket") // vci initiator socket name |
| 268 | { |
| 269 | //register callback function VCI INITIATOR SOCKET |
| 270 | p_vci_initiator.register_nb_transport_bw(this, &my_initiator::my_nb_transport_bw); |
| 271 | |
| 272 | //initiator identification |
| 273 | m_srcid = mt.indexForId(index); |
| 274 | |
| 275 | //Quantum keeper |
| 276 | tlm_utils::tlm_quantumkeeper::set_global_quantum(time_quantum * UNIT_TIME); |
| 277 | m_QuantumKeeper.reset(); |
| 278 | |
| 279 | //initialize the local time |
| 280 | m_local_time= 0 * UNIT_TIME; |
| 281 | |
| 282 | //initialize the activity variable |
| 283 | setActivity(true); |
| 284 | |
| 285 | // register thread process |
| 286 | SC_THREAD(behavior); |
| 287 | } |
| 288 | |
| 289 | ///////////////////////////////////////////////////////////////////////////////////// |
| 290 | // Fuctions |
| 291 | ///////////////////////////////////////////////////////////////////////////////////// |
| 292 | bool my_initiator::getActivity() |
| 293 | { |
| 294 | return m_activity_status; |
| 295 | } |
| 296 | |
| 297 | void my_initiator::setActivity(bool t) |
| 298 | { |
| 299 | m_activity_status =t; |
| 300 | } |
| 301 | |
| 302 | //send a message to network to inform the current activity status |
| 303 | void my_initiator::sendActivity() |
| 304 | { |
| 305 | tlm::tlm_generic_payload *payload_ptr = new tlm::tlm_generic_payload(); |
| 306 | tlm::tlm_phase phase; |
| 307 | sc_core::sc_time send_time; |
| 308 | soclib_payload_extension *extension_ptr = new soclib_payload_extension(); |
| 309 | |
| 310 | // set the active or inactive command |
| 311 | if(m_activity_status) extension_ptr->set_active(); |
| 312 | else extension_ptr->set_inactive(); |
| 313 | // set the extension to tlm payload |
| 314 | payload_ptr->set_extension (extension_ptr); |
| 315 | //set the tlm phase |
| 316 | phase = tlm::BEGIN_REQ; |
| 317 | //set the local time to transaction time |
| 318 | send_time = m_local_time; |
| 319 | //send the message |
| 320 | p_vci_initiator->nb_transport_fw(*payload_ptr, phase, send_time); |
| 321 | //wait a response |
| 322 | wait(m_rspEvent); |
| 323 | } |
| 324 | |
| 325 | sc_core::sc_time my_initiator::getLocalTime() |
| 326 | { |
| 327 | return m_local_time; |
| 328 | } |
| 329 | |
| 330 | void my_initiator::setLocalTime(sc_core::sc_time &t) |
| 331 | { |
| 332 | m_local_time=t; |
| 333 | } |
| 334 | |
| 335 | void my_initiator::addTime(sc_core::sc_time t) |
| 336 | { |
| 337 | m_local_time= m_local_time + t; |
| 338 | } |
| 339 | |
| 340 | //send a null message to network to inform the current local time |
| 341 | void my_initiator::sendNullMessage() |
| 342 | { |
| 343 | tlm::tlm_generic_payload *payload_ptr = new tlm::tlm_generic_payload(); |
| 344 | tlm::tlm_phase phase; |
| 345 | sc_core::sc_time send_time; |
| 346 | soclib_payload_extension *extension_ptr = new soclib_payload_extension(); |
| 347 | |
| 348 | // set the null message command |
| 349 | extension_ptr->set_null_message(); |
| 350 | // set the extension to tlm payload |
| 351 | payload_ptr->set_extension(extension_ptr); |
| 352 | //set the tlm phase |
| 353 | phase = tlm::BEGIN_REQ; |
| 354 | //set the local time to transaction time |
| 355 | send_time = m_local_time; |
| 356 | //send the null message |
| 357 | p_vci_initiator->nb_transport_fw(*payload_ptr, phase, send_time); |
| 358 | //deschedule |
| 359 | wait(sc_core::SC_ZERO_TIME); |
| 360 | } |
| 361 | // initiator thread |
| 362 | void my_initiator::behavior(void) |
| 363 | { |
| 364 | tlm::tlm_generic_payload *payload_ptr = new tlm::tlm_generic_payload(); |
| 365 | tlm::tlm_phase phase; |
| 366 | sc_core::sc_time send_time; |
| 367 | soclib_payload_extension *extension_ptr = new soclib_payload_extension(); |
| 368 | |
| 369 | uint32_t nwords = 1; |
| 370 | uint32_t nbytes= nwords * vci_param::nbytes; |
| 371 | unsigned char data[nbytes]; |
| 372 | unsigned char byte_enable[nbytes]; |
| 373 | unsigned int byte_enable_enabled = 0xffffffff; |
| 374 | unsigned int pktid = 0; |
| 375 | |
| 376 | while (true){ |
| 377 | |
| 378 | addTime(1000 * UNIT_TIME); |
| 379 | m_QuantumKeeper.inc(1000 * UNIT_TIME); |
| 380 | |
| 381 | for(unsigned int i=0, j=0; i<nwords; i++, j+=4){ |
| 382 | utoa(byte_enable_enabled, byte_enable, j); |
| 383 | utoa(data_int[i], data, j); |
| 384 | data_int[i]++; |
| 385 | } |
| 386 | |
| 387 | // set the values in tlm payload |
| 388 | payload_ptr->set_command(tlm::TLM_IGNORE_COMMAND); |
| 389 | payload_ptr->set_address(address[idx]); |
| 390 | payload_ptr->set_byte_enable_ptr(byte_enable); |
| 391 | payload_ptr->set_byte_enable_length(nbytes); |
| 392 | payload_ptr->set_data_ptr(data); |
| 393 | payload_ptr->set_data_length(nbytes); |
| 394 | // set the values in payload extension |
| 395 | extension_ptr->set_write(); |
| 396 | extension_ptr->set_src_id(m_srcid); |
| 397 | extension_ptr->set_trd_id(0); |
| 398 | extension_ptr->set_pkt_id(pktid); |
| 399 | // set the extension to tlm payload |
| 400 | payload_ptr->set_extension (extension_ptr ); |
| 401 | // set the tlm phase |
| 402 | phase = tlm::BEGIN_REQ; |
| 403 | // set the local time to transaction time |
| 404 | m_send_time = m_local_time; |
| 405 | |
| 406 | #if MY_INITIATOR_DEBUG |
| 407 | std::cout << "[INITIATOR " << m_srcid << "] send cmd packet id = " << pktid << " time = " << m_local_time.value() << std::endl; |
| 408 | #endif |
| 409 | |
| 410 | // send the transaction |
| 411 | p_vci_initiator->nb_transport_fw(*payload_ptr, phase, m_send_time); |
| 412 | wait(m_rspEvent); |
| 413 | |
| 414 | #if MY_INITIATOR_DEBUG |
| 415 | payload_ptr->get_extension( extension_ptr ); |
| 416 | std::cout << "[INITIATOR " << m_srcid << "] receive rsp packet id = " << extension_ptr->get_pkt_id() << " time = " << m_local_time.value() << std::endl; |
| 417 | #endif |
| 418 | |
| 419 | pktid++; |
| 420 | |
| 421 | addTime(1000 * UNIT_TIME); |
| 422 | m_QuantumKeeper.inc(1000 * UNIT_TIME); |
| 423 | |
| 424 | // set the values in tlm payload |
| 425 | payload_ptr->set_command(tlm::TLM_IGNORE_COMMAND); |
| 426 | payload_ptr->set_address(address[idx]); |
| 427 | payload_ptr->set_byte_enable_ptr(byte_enable); |
| 428 | payload_ptr->set_byte_enable_length(nbytes); |
| 429 | payload_ptr->set_data_ptr(data); |
| 430 | payload_ptr->set_data_length(nbytes); |
| 431 | // set the values in payload extension |
| 432 | extension_ptr->set_read(); |
| 433 | extension_ptr->set_src_id(m_srcid); |
| 434 | extension_ptr->set_trd_id(0); |
| 435 | extension_ptr->set_pkt_id(pktid); |
| 436 | // set the extension to tlm payload |
| 437 | payload_ptr->set_extension (extension_ptr ); |
| 438 | // set the tlm phase |
| 439 | phase = tlm::BEGIN_REQ; |
| 440 | // set the local time to transaction time |
| 441 | m_send_time = m_local_time; |
| 442 | |
| 443 | #if MY_INITIATOR_DEBUG |
| 444 | std::cout << "[INITIATOR " << m_srcid << "] send cmd packet id = " << pktid << " time = " << m_local_time.value() << std::endl; |
| 445 | #endif |
| 446 | |
| 447 | p_vci_initiator->nb_transport_fw(*payload_ptr, phase, m_send_time); |
| 448 | wait(m_rspEvent); |
| 449 | |
| 450 | #if MY_INITIATOR_DEBUG |
| 451 | payload_ptr->get_extension( extension_ptr ); |
| 452 | std::cout << "[INITIATOR " << m_srcid << "] receive rsp packet id = " << extension_ptr->get_pkt_id() << " time = " << m_local_time.value() << std::endl; |
| 453 | |
| 454 | for(unsigned int i=0, j=0; i<nwords; i++, j+=4){ |
| 455 | std::cout << "[" << std::hex << (payload_ptr->get_address() + j) << "] = " << atou(payload_ptr->get_data_ptr(),j) << std::dec; |
| 456 | if(payload_ptr->is_response_error()) |
| 457 | std::cout << " ERROR"; |
| 458 | std::cout << std::endl; |
| 459 | } |
| 460 | #endif |
| 461 | |
| 462 | pktid++; |
| 463 | idx++; |
| 464 | if(idx==6) idx=0; |
| 465 | |
| 466 | // if initiator needs synchronize then it sends a null message and resets the quantum keeper |
| 467 | if (m_QuantumKeeper.need_sync()) { |
| 468 | sendNullMessage(); |
| 469 | m_QuantumKeeper.reset(); |
| 470 | } |
| 471 | |
| 472 | } // end while true |
| 473 | setActivity(false); |
| 474 | sendActivity(); |
| 475 | } // end initiator_thread |
| 476 | |
| 477 | |
| 478 | ///////////////////////////////////////////////////////////////////////////////////// |
| 479 | // Virtual Fuctions tlm::tlm_bw_transport_if (VCI SOCKET) |
| 480 | ///////////////////////////////////////////////////////////////////////////////////// |
| 481 | |
| 482 | /// receive the response packet from target socket |
| 483 | tlm::tlm_sync_enum my_initiator::my_nb_transport_bw // inbound nb_transport_bw |
| 484 | ( tlm::tlm_base_protocol_types::tlm_payload_type &payload, // payload |
| 485 | tlm::tlm_base_protocol_types::tlm_phase_type &phase, // phase |
| 486 | sc_core::sc_time &time // time |
| 487 | ) |
| 488 | |
| 489 | { |
| 490 | setLocalTime(time); |
| 491 | m_QuantumKeeper.inc(time - m_send_time); |
| 492 | m_rspEvent.notify(0 * UNIT_TIME); |
| 493 | return tlm::TLM_COMPLETED; |
| 494 | } // end backward nb transport |
| 495 | |