| | 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 | |