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