Deleted Added
sdiff udiff text old ( 6151:bc6b84108443 ) new ( 6152:705b277e1141 )
full compact
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
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]);
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 }
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) ||
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) ||
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) ||
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) ||
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) ||
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
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
817 thread, // SMT thread
818 0, // TM specific - timestamp of memory request
819 false // TM specific - whether request is part of escape action
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) ||
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
894 thread, // SMT thread
895 0, // TM specific - timestamp of memory request
896 false // TM specific - whether request is part of escape action
897 );
898 makeRequest(request);
899}
900
901void
902Sequencer::makeRequest(const CacheMsg& request)
903{
904 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 ---