Sequencer.cc (6151:bc6b84108443) | Sequencer.cc (6152:705b277e1141) |
---|---|
1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 33 unchanged lines hidden (view full) --- 42//#include "Tracer.hh" 43#include "AbstractChip.hh" 44#include "Chip.hh" 45#include "Tester.hh" 46#include "SubBlock.hh" 47#include "Protocol.hh" 48#include "Map.hh" 49#include "interface.hh" | 1 2/* 3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright --- 33 unchanged lines hidden (view full) --- 42//#include "Tracer.hh" 43#include "AbstractChip.hh" 44#include "Chip.hh" 45#include "Tester.hh" 46#include "SubBlock.hh" 47#include "Protocol.hh" 48#include "Map.hh" 49#include "interface.hh" |
50//#include "XactCommitArbiter.hh" 51// #include "TransactionInterfaceManager.hh" 52//#include "TransactionVersionManager.hh" 53//#include "LazyTransactionVersionManager.hh" | |
54 | 50 |
55//#define XACT_MGR g_system_ptr->getChip(m_chip_ptr->getID())->getTransactionInterfaceManager(m_version) 56 | |
57Sequencer::Sequencer(AbstractChip* chip_ptr, int version) { 58 m_chip_ptr = chip_ptr; 59 m_version = version; 60 61 m_deadlock_check_scheduled = false; 62 m_outstanding_count = 0; 63 64 int smt_threads = RubyConfig::numberofSMTThreads(); --- 88 unchanged lines hidden (view full) --- 153// returns the total number of demand requests 154int Sequencer::getNumberOutstandingDemand(){ 155 int smt_threads = RubyConfig::numberofSMTThreads(); 156 int total_demand = 0; 157 for(int p=0; p < smt_threads; ++p){ 158 Vector<Address> keys = m_readRequestTable_ptr[p]->keys(); 159 for (int i=0; i< keys.size(); i++) { 160 CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]); | 51Sequencer::Sequencer(AbstractChip* chip_ptr, int version) { 52 m_chip_ptr = chip_ptr; 53 m_version = version; 54 55 m_deadlock_check_scheduled = false; 56 m_outstanding_count = 0; 57 58 int smt_threads = RubyConfig::numberofSMTThreads(); --- 88 unchanged lines hidden (view full) --- 147// returns the total number of demand requests 148int Sequencer::getNumberOutstandingDemand(){ 149 int smt_threads = RubyConfig::numberofSMTThreads(); 150 int total_demand = 0; 151 for(int p=0; p < smt_threads; ++p){ 152 Vector<Address> keys = m_readRequestTable_ptr[p]->keys(); 153 for (int i=0; i< keys.size(); i++) { 154 CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]); |
161 // don't count transactional begin/commit requests 162 if(request.getType() != CacheRequestType_BEGIN_XACT && request.getType() != CacheRequestType_COMMIT_XACT){ 163 if(request.getPrefetch() == PrefetchBit_No){ 164 total_demand++; 165 } | 155 if(request.getPrefetch() == PrefetchBit_No){ 156 total_demand++; |
166 } 167 } 168 169 keys = m_writeRequestTable_ptr[p]->keys(); 170 for (int i=0; i< keys.size(); i++) { 171 CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]); 172 if(request.getPrefetch() == PrefetchBit_No){ 173 total_demand++; --- 215 unchanged lines hidden (view full) --- 389 390 // See if we should schedule a deadlock check 391 if (m_deadlock_check_scheduled == false) { 392 g_eventQueue_ptr->scheduleEvent(this, g_DEADLOCK_THRESHOLD); 393 m_deadlock_check_scheduled = true; 394 } 395 396 if ((request.getType() == CacheRequestType_ST) || | 157 } 158 } 159 160 keys = m_writeRequestTable_ptr[p]->keys(); 161 for (int i=0; i< keys.size(); i++) { 162 CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]); 163 if(request.getPrefetch() == PrefetchBit_No){ 164 total_demand++; --- 215 unchanged lines hidden (view full) --- 380 381 // See if we should schedule a deadlock check 382 if (m_deadlock_check_scheduled == false) { 383 g_eventQueue_ptr->scheduleEvent(this, g_DEADLOCK_THRESHOLD); 384 m_deadlock_check_scheduled = true; 385 } 386 387 if ((request.getType() == CacheRequestType_ST) || |
397 (request.getType() == CacheRequestType_ST_XACT) || 398 (request.getType() == CacheRequestType_LDX_XACT) || | |
399 (request.getType() == CacheRequestType_ATOMIC)) { 400 if (m_writeRequestTable_ptr[thread]->exist(line_address(request.getAddress()))) { 401 m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request; 402 return true; 403 } 404 m_writeRequestTable_ptr[thread]->allocate(line_address(request.getAddress())); 405 m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request; 406 m_outstanding_count++; --- 24 unchanged lines hidden (view full) --- 431 int total_outstanding = 0; 432 int smt_threads = RubyConfig::numberofSMTThreads(); 433 for(int p=0; p < smt_threads; ++p){ 434 total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size(); 435 } 436 assert(m_outstanding_count == total_outstanding); 437 438 if ((request.getType() == CacheRequestType_ST) || | 388 (request.getType() == CacheRequestType_ATOMIC)) { 389 if (m_writeRequestTable_ptr[thread]->exist(line_address(request.getAddress()))) { 390 m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request; 391 return true; 392 } 393 m_writeRequestTable_ptr[thread]->allocate(line_address(request.getAddress())); 394 m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request; 395 m_outstanding_count++; --- 24 unchanged lines hidden (view full) --- 420 int total_outstanding = 0; 421 int smt_threads = RubyConfig::numberofSMTThreads(); 422 for(int p=0; p < smt_threads; ++p){ 423 total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size(); 424 } 425 assert(m_outstanding_count == total_outstanding); 426 427 if ((request.getType() == CacheRequestType_ST) || |
439 (request.getType() == CacheRequestType_ST_XACT) || 440 (request.getType() == CacheRequestType_LDX_XACT) || | |
441 (request.getType() == CacheRequestType_ATOMIC)) { 442 m_writeRequestTable_ptr[thread]->deallocate(line_address(request.getAddress())); 443 } else { 444 m_readRequestTable_ptr[thread]->deallocate(line_address(request.getAddress())); 445 } 446 m_outstanding_count--; 447 448 total_outstanding = 0; --- 43 unchanged lines hidden (view full) --- 492void Sequencer::writeCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, int thread) { 493 assert(address == line_address(address)); 494 assert(m_writeRequestTable_ptr[thread]->exist(line_address(address))); 495 CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address); 496 assert( request.getThreadID() == thread); 497 removeRequest(request); 498 499 assert((request.getType() == CacheRequestType_ST) || | 428 (request.getType() == CacheRequestType_ATOMIC)) { 429 m_writeRequestTable_ptr[thread]->deallocate(line_address(request.getAddress())); 430 } else { 431 m_readRequestTable_ptr[thread]->deallocate(line_address(request.getAddress())); 432 } 433 m_outstanding_count--; 434 435 total_outstanding = 0; --- 43 unchanged lines hidden (view full) --- 479void Sequencer::writeCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, int thread) { 480 assert(address == line_address(address)); 481 assert(m_writeRequestTable_ptr[thread]->exist(line_address(address))); 482 CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address); 483 assert( request.getThreadID() == thread); 484 removeRequest(request); 485 486 assert((request.getType() == CacheRequestType_ST) || |
500 (request.getType() == CacheRequestType_ST_XACT) || 501 (request.getType() == CacheRequestType_LDX_XACT) || | |
502 (request.getType() == CacheRequestType_ATOMIC)); 503 504 hitCallback(request, data, respondingMach, thread); 505 506} 507 508void Sequencer::readCallback(const Address& address) { 509 DataBlock data; --- 34 unchanged lines hidden (view full) --- 544 assert(address == line_address(address)); 545 assert(m_readRequestTable_ptr[thread]->exist(line_address(address))); 546 547 CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address); 548 assert( request.getThreadID() == thread ); 549 removeRequest(request); 550 551 assert((request.getType() == CacheRequestType_LD) || | 487 (request.getType() == CacheRequestType_ATOMIC)); 488 489 hitCallback(request, data, respondingMach, thread); 490 491} 492 493void Sequencer::readCallback(const Address& address) { 494 DataBlock data; --- 34 unchanged lines hidden (view full) --- 529 assert(address == line_address(address)); 530 assert(m_readRequestTable_ptr[thread]->exist(line_address(address))); 531 532 CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address); 533 assert( request.getThreadID() == thread ); 534 removeRequest(request); 535 536 assert((request.getType() == CacheRequestType_LD) || |
552 (request.getType() == CacheRequestType_LD_XACT) || | |
553 (request.getType() == CacheRequestType_IFETCH) 554 ); 555 556 hitCallback(request, data, respondingMach, thread); 557} 558 559void Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMachineType respondingMach, int thread) { 560 int size = request.getSize(); --- 59 unchanged lines hidden (view full) --- 620 uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 621 cout << "END PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl; 622#endif 623 624 } 625 626 bool write = 627 (type == CacheRequestType_ST) || | 537 (request.getType() == CacheRequestType_IFETCH) 538 ); 539 540 hitCallback(request, data, respondingMach, thread); 541} 542 543void Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMachineType respondingMach, int thread) { 544 int size = request.getSize(); --- 59 unchanged lines hidden (view full) --- 604 uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 605 cout << "END PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl; 606#endif 607 608 } 609 610 bool write = 611 (type == CacheRequestType_ST) || |
628 (type == CacheRequestType_ST_XACT) || 629 (type == CacheRequestType_LDX_XACT) || | |
630 (type == CacheRequestType_ATOMIC); 631 632 if (TSO && write) { 633 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->callBack(line_address(request.getAddress()), data); 634 } else { 635 636 // Copy the correct bytes out of the cache line into the subblock 637 SubBlock subblock(request_address, request_logical_address, size); --- 11 unchanged lines hidden (view full) --- 649 // (This is only triggered for the non-TSO case) 650 if (write) { 651 assert(!TSO); 652 subblock.mergeTo(data); // copy the correct bytes from SubBlock into the DataBlock 653 } 654 } 655} 656 | 612 (type == CacheRequestType_ATOMIC); 613 614 if (TSO && write) { 615 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->callBack(line_address(request.getAddress()), data); 616 } else { 617 618 // Copy the correct bytes out of the cache line into the subblock 619 SubBlock subblock(request_address, request_logical_address, size); --- 11 unchanged lines hidden (view full) --- 631 // (This is only triggered for the non-TSO case) 632 if (write) { 633 assert(!TSO); 634 subblock.mergeTo(data); // copy the correct bytes from SubBlock into the DataBlock 635 } 636 } 637} 638 |
657void Sequencer::readConflictCallback(const Address& address) { 658 // process oldest thread first 659 int thread = -1; 660 Time oldest_time = 0; 661 int smt_threads = RubyConfig::numberofSMTThreads(); 662 for(int t=0; t < smt_threads; ++t){ 663 if(m_readRequestTable_ptr[t]->exist(address)){ 664 CacheMsg & request = m_readRequestTable_ptr[t]->lookup(address); 665 if(thread == -1 || (request.getTime() < oldest_time) ){ 666 thread = t; 667 oldest_time = request.getTime(); 668 } 669 } 670 } 671 // make sure we found an oldest thread 672 ASSERT(thread != -1); 673 674 CacheMsg & request = m_readRequestTable_ptr[thread]->lookup(address); 675 676 readConflictCallback(address, GenericMachineType_NULL, thread); 677} 678 679void Sequencer::readConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) { 680 assert(address == line_address(address)); 681 assert(m_readRequestTable_ptr[thread]->exist(line_address(address))); 682 683 CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address); 684 assert( request.getThreadID() == thread ); 685 removeRequest(request); 686 687 assert((request.getType() == CacheRequestType_LD) || 688 (request.getType() == CacheRequestType_LD_XACT) || 689 (request.getType() == CacheRequestType_IFETCH) 690 ); 691 692 conflictCallback(request, respondingMach, thread); 693} 694 695void Sequencer::writeConflictCallback(const Address& address) { 696 // process oldest thread first 697 int thread = -1; 698 Time oldest_time = 0; 699 int smt_threads = RubyConfig::numberofSMTThreads(); 700 for(int t=0; t < smt_threads; ++t){ 701 if(m_writeRequestTable_ptr[t]->exist(address)){ 702 CacheMsg & request = m_writeRequestTable_ptr[t]->lookup(address); 703 if(thread == -1 || (request.getTime() < oldest_time) ){ 704 thread = t; 705 oldest_time = request.getTime(); 706 } 707 } 708 } 709 // make sure we found an oldest thread 710 ASSERT(thread != -1); 711 712 CacheMsg & request = m_writeRequestTable_ptr[thread]->lookup(address); 713 714 writeConflictCallback(address, GenericMachineType_NULL, thread); 715} 716 717void Sequencer::writeConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) { 718 assert(address == line_address(address)); 719 assert(m_writeRequestTable_ptr[thread]->exist(line_address(address))); 720 CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address); 721 assert( request.getThreadID() == thread); 722 removeRequest(request); 723 724 assert((request.getType() == CacheRequestType_ST) || 725 (request.getType() == CacheRequestType_ST_XACT) || 726 (request.getType() == CacheRequestType_LDX_XACT) || 727 (request.getType() == CacheRequestType_ATOMIC)); 728 729 conflictCallback(request, respondingMach, thread); 730 731} 732 733void Sequencer::conflictCallback(const CacheMsg& request, GenericMachineType respondingMach, int thread) { 734 assert(XACT_MEMORY); 735 int size = request.getSize(); 736 Address request_address = request.getAddress(); 737 Address request_logical_address = request.getLogicalAddress(); 738 Address request_line_address = line_address(request_address); 739 CacheRequestType type = request.getType(); 740 int threadID = request.getThreadID(); 741 Time issued_time = request.getTime(); 742 int logical_proc_no = ((m_chip_ptr->getID() * RubyConfig::numberOfProcsPerChip()) + m_version) * RubyConfig::numberofSMTThreads() + threadID; 743 744 DEBUG_MSG(SEQUENCER_COMP, MedPrio, size); 745 746 assert(g_eventQueue_ptr->getTime() >= issued_time); 747 Time miss_latency = g_eventQueue_ptr->getTime() - issued_time; 748 749 if (PROTOCOL_DEBUG_TRACE) { 750 g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), -1, request.getAddress(), "", "Conflict", "", 751 int_to_string(miss_latency)+" cycles "+GenericMachineType_to_string(respondingMach)+" "+CacheRequestType_to_string(request.getType())+" "+PrefetchBit_to_string(request.getPrefetch())); 752 } 753 754 DEBUG_MSG(SEQUENCER_COMP, MedPrio, request_address); 755 DEBUG_MSG(SEQUENCER_COMP, MedPrio, request.getPrefetch()); 756 if (request.getPrefetch() == PrefetchBit_Yes) { 757 DEBUG_MSG(SEQUENCER_COMP, MedPrio, "return"); 758 g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach); 759 return; // Ignore the software prefetch, don't callback the driver 760 } 761 762 bool write = 763 (type == CacheRequestType_ST) || 764 (type == CacheRequestType_ST_XACT) || 765 (type == CacheRequestType_LDX_XACT) || 766 (type == CacheRequestType_ATOMIC); 767 768 // Copy the correct bytes out of the cache line into the subblock 769 SubBlock subblock(request_address, request_logical_address, size); 770 771 // Call into the Driver (Tester or Simics) 772 g_system_ptr->getDriver()->conflictCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID); 773 774 // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock 775 // (This is only triggered for the non-TSO case) 776 if (write) { 777 assert(!TSO); 778 } 779} 780 | |
781void Sequencer::printDebug(){ 782 //notify driver of debug 783 g_system_ptr->getDriver()->printDebug(); 784} 785 786// Returns true if the sequencer already has a load or store outstanding 787bool 788Sequencer::isReady(const Packet* pkt) const --- 20 unchanged lines hidden (view full) --- 809 Address( physical_addr ), 810 type_of_request, 811 Address(0), 812 AccessModeType_UserMode, // User/supervisor mode 813 0, // Size in bytes of request 814 PrefetchBit_No, // Not a prefetch 815 0, // Version number 816 Address(logical_addr), // Virtual Address | 639void Sequencer::printDebug(){ 640 //notify driver of debug 641 g_system_ptr->getDriver()->printDebug(); 642} 643 644// Returns true if the sequencer already has a load or store outstanding 645bool 646Sequencer::isReady(const Packet* pkt) const --- 20 unchanged lines hidden (view full) --- 667 Address( physical_addr ), 668 type_of_request, 669 Address(0), 670 AccessModeType_UserMode, // User/supervisor mode 671 0, // Size in bytes of request 672 PrefetchBit_No, // Not a prefetch 673 0, // Version number 674 Address(logical_addr), // Virtual Address |
817 thread, // SMT thread 818 0, // TM specific - timestamp of memory request 819 false // TM specific - whether request is part of escape action | 675 thread // SMT thread |
820 ); 821 isReady(request); 822} 823 824bool 825Sequencer::isReady(const CacheMsg& request) const 826{ 827 if (m_outstanding_count >= g_SEQUENCER_OUTSTANDING_REQUESTS) { 828 //cout << "TOO MANY OUTSTANDING: " << m_outstanding_count << " " << g_SEQUENCER_OUTSTANDING_REQUESTS << " VER " << m_version << endl; 829 //printProgress(cout); 830 return false; 831 } 832 833 // This code allows reads to be performed even when we have a write 834 // request outstanding for the line 835 bool write = 836 (request.getType() == CacheRequestType_ST) || | 676 ); 677 isReady(request); 678} 679 680bool 681Sequencer::isReady(const CacheMsg& request) const 682{ 683 if (m_outstanding_count >= g_SEQUENCER_OUTSTANDING_REQUESTS) { 684 //cout << "TOO MANY OUTSTANDING: " << m_outstanding_count << " " << g_SEQUENCER_OUTSTANDING_REQUESTS << " VER " << m_version << endl; 685 //printProgress(cout); 686 return false; 687 } 688 689 // This code allows reads to be performed even when we have a write 690 // request outstanding for the line 691 bool write = 692 (request.getType() == CacheRequestType_ST) || |
837 (request.getType() == CacheRequestType_ST_XACT) || 838 (request.getType() == CacheRequestType_LDX_XACT) || | |
839 (request.getType() == CacheRequestType_ATOMIC); 840 841 // LUKE - disallow more than one request type per address 842 // INVARIANT: at most one request type per address, per processor 843 int smt_threads = RubyConfig::numberofSMTThreads(); 844 for(int p=0; p < smt_threads; ++p){ 845 if( m_writeRequestTable_ptr[p]->exist(line_address(request.getAddress())) || 846 m_readRequestTable_ptr[p]->exist(line_address(request.getAddress())) ){ --- 39 unchanged lines hidden (view full) --- 886 Address( physical_addr ), 887 type_of_request, 888 Address(virtual_pc), 889 access_mode, // User/supervisor mode 890 request_size, // Size in bytes of request 891 PrefetchBit_No, // Not a prefetch 892 0, // Version number 893 Address(logical_addr), // Virtual Address | 693 (request.getType() == CacheRequestType_ATOMIC); 694 695 // LUKE - disallow more than one request type per address 696 // INVARIANT: at most one request type per address, per processor 697 int smt_threads = RubyConfig::numberofSMTThreads(); 698 for(int p=0; p < smt_threads; ++p){ 699 if( m_writeRequestTable_ptr[p]->exist(line_address(request.getAddress())) || 700 m_readRequestTable_ptr[p]->exist(line_address(request.getAddress())) ){ --- 39 unchanged lines hidden (view full) --- 740 Address( physical_addr ), 741 type_of_request, 742 Address(virtual_pc), 743 access_mode, // User/supervisor mode 744 request_size, // Size in bytes of request 745 PrefetchBit_No, // Not a prefetch 746 0, // Version number 747 Address(logical_addr), // Virtual Address |
894 thread, // SMT thread 895 0, // TM specific - timestamp of memory request 896 false // TM specific - whether request is part of escape action | 748 thread // SMT thread |
897 ); 898 makeRequest(request); 899} 900 901void 902Sequencer::makeRequest(const CacheMsg& request) 903{ 904 bool write = (request.getType() == CacheRequestType_ST) || | 749 ); 750 makeRequest(request); 751} 752 753void 754Sequencer::makeRequest(const CacheMsg& request) 755{ 756 bool write = (request.getType() == CacheRequestType_ST) || |
905 (request.getType() == CacheRequestType_ST_XACT) || 906 (request.getType() == CacheRequestType_LDX_XACT) || | |
907 (request.getType() == CacheRequestType_ATOMIC); 908 909 if (TSO && (request.getPrefetch() == PrefetchBit_No) && write) { 910 assert(m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady()); 911 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->insertStore(request); 912 return; 913 } 914 --- 326 unchanged lines hidden --- | 757 (request.getType() == CacheRequestType_ATOMIC); 758 759 if (TSO && (request.getPrefetch() == PrefetchBit_No) && write) { 760 assert(m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady()); 761 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->insertStore(request); 762 return; 763 } 764 --- 326 unchanged lines hidden --- |