Sequencer.cc (6152:705b277e1141) | Sequencer.cc (6153:0011560d49b0) |
---|---|
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 --- 32 unchanged lines hidden (view full) --- 41#include "RubyConfig.hh" 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" | 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 --- 32 unchanged lines hidden (view full) --- 41#include "RubyConfig.hh" 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 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 --- 534 unchanged lines hidden (view full) --- 592 g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach); 593 return; // Ignore the software prefetch, don't callback the driver 594 } 595 596 // Profile the miss latency for all non-zero demand misses 597 if (miss_latency != 0) { 598 g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach); 599 | 49 50Sequencer::Sequencer(AbstractChip* chip_ptr, int version) { 51 m_chip_ptr = chip_ptr; 52 m_version = version; 53 54 m_deadlock_check_scheduled = false; 55 m_outstanding_count = 0; 56 --- 534 unchanged lines hidden (view full) --- 591 g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach); 592 return; // Ignore the software prefetch, don't callback the driver 593 } 594 595 // Profile the miss latency for all non-zero demand misses 596 if (miss_latency != 0) { 597 g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach); 598 |
600#if 0 601 uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 602 uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 603 uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 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) || 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); 620 subblock.mergeFrom(data); // copy the correct bytes from DataBlock in the SubBlock 621 622 // Scan the store buffer to see if there are any outstanding stores we need to collect 623 if (TSO) { 624 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->updateSubBlock(subblock); 625 } 626 | 599 } 600 601 bool write = 602 (type == CacheRequestType_ST) || 603 (type == CacheRequestType_ATOMIC); 604 605 if (TSO && write) { 606 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->callBack(line_address(request.getAddress()), data); 607 } else { 608 609 // Copy the correct bytes out of the cache line into the subblock 610 SubBlock subblock(request_address, request_logical_address, size); 611 subblock.mergeFrom(data); // copy the correct bytes from DataBlock in the SubBlock 612 613 // Scan the store buffer to see if there are any outstanding stores we need to collect 614 if (TSO) { 615 m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->updateSubBlock(subblock); 616 } 617 |
627 // Call into the Driver (Tester or Simics) and let it read and/or modify the sub-block | 618 // Call into the Driver and let it read and/or modify the sub-block |
628 g_system_ptr->getDriver()->hitCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID); 629 630 // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock 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 | 619 g_system_ptr->getDriver()->hitCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID); 620 621 // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock 622 // (This is only triggered for the non-TSO case) 623 if (write) { 624 assert(!TSO); 625 subblock.mergeTo(data); // copy the correct bytes from SubBlock into the DataBlock 626 } 627 } 628} 629 |
630void Sequencer::readConflictCallback(const Address& address) { 631 // process oldest thread first 632 int thread = -1; 633 Time oldest_time = 0; 634 int smt_threads = RubyConfig::numberofSMTThreads(); 635 for(int t=0; t < smt_threads; ++t){ 636 if(m_readRequestTable_ptr[t]->exist(address)){ 637 CacheMsg & request = m_readRequestTable_ptr[t]->lookup(address); 638 if(thread == -1 || (request.getTime() < oldest_time) ){ 639 thread = t; 640 oldest_time = request.getTime(); 641 } 642 } 643 } 644 // make sure we found an oldest thread 645 ASSERT(thread != -1); 646 647 CacheMsg & request = m_readRequestTable_ptr[thread]->lookup(address); 648 649 readConflictCallback(address, GenericMachineType_NULL, thread); 650} 651 652void Sequencer::readConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) { 653 assert(address == line_address(address)); 654 assert(m_readRequestTable_ptr[thread]->exist(line_address(address))); 655 656 CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address); 657 assert( request.getThreadID() == thread ); 658 removeRequest(request); 659 660 assert((request.getType() == CacheRequestType_LD) || 661 (request.getType() == CacheRequestType_LD_XACT) || 662 (request.getType() == CacheRequestType_IFETCH) 663 ); 664 665 conflictCallback(request, respondingMach, thread); 666} 667 668void Sequencer::writeConflictCallback(const Address& address) { 669 // process oldest thread first 670 int thread = -1; 671 Time oldest_time = 0; 672 int smt_threads = RubyConfig::numberofSMTThreads(); 673 for(int t=0; t < smt_threads; ++t){ 674 if(m_writeRequestTable_ptr[t]->exist(address)){ 675 CacheMsg & request = m_writeRequestTable_ptr[t]->lookup(address); 676 if(thread == -1 || (request.getTime() < oldest_time) ){ 677 thread = t; 678 oldest_time = request.getTime(); 679 } 680 } 681 } 682 // make sure we found an oldest thread 683 ASSERT(thread != -1); 684 685 CacheMsg & request = m_writeRequestTable_ptr[thread]->lookup(address); 686 687 writeConflictCallback(address, GenericMachineType_NULL, thread); 688} 689 690void Sequencer::writeConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) { 691 assert(address == line_address(address)); 692 assert(m_writeRequestTable_ptr[thread]->exist(line_address(address))); 693 CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address); 694 assert( request.getThreadID() == thread); 695 removeRequest(request); 696 697 assert((request.getType() == CacheRequestType_ST) || 698 (request.getType() == CacheRequestType_ST_XACT) || 699 (request.getType() == CacheRequestType_LDX_XACT) || 700 (request.getType() == CacheRequestType_ATOMIC)); 701 702 conflictCallback(request, respondingMach, thread); 703 704} 705 706void Sequencer::conflictCallback(const CacheMsg& request, GenericMachineType respondingMach, int thread) { 707 assert(XACT_MEMORY); 708 int size = request.getSize(); 709 Address request_address = request.getAddress(); 710 Address request_logical_address = request.getLogicalAddress(); 711 Address request_line_address = line_address(request_address); 712 CacheRequestType type = request.getType(); 713 int threadID = request.getThreadID(); 714 Time issued_time = request.getTime(); 715 int logical_proc_no = ((m_chip_ptr->getID() * RubyConfig::numberOfProcsPerChip()) + m_version) * RubyConfig::numberofSMTThreads() + threadID; 716 717 DEBUG_MSG(SEQUENCER_COMP, MedPrio, size); 718 719 assert(g_eventQueue_ptr->getTime() >= issued_time); 720 Time miss_latency = g_eventQueue_ptr->getTime() - issued_time; 721 722 if (PROTOCOL_DEBUG_TRACE) { 723 g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), -1, request.getAddress(), "", "Conflict", "", 724 int_to_string(miss_latency)+" cycles "+GenericMachineType_to_string(respondingMach)+" "+CacheRequestType_to_string(request.getType())+" "+PrefetchBit_to_string(request.getPrefetch())); 725 } 726 727 DEBUG_MSG(SEQUENCER_COMP, MedPrio, request_address); 728 DEBUG_MSG(SEQUENCER_COMP, MedPrio, request.getPrefetch()); 729 if (request.getPrefetch() == PrefetchBit_Yes) { 730 DEBUG_MSG(SEQUENCER_COMP, MedPrio, "return"); 731 g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach); 732 return; // Ignore the software prefetch, don't callback the driver 733 } 734 735 bool write = 736 (type == CacheRequestType_ST) || 737 (type == CacheRequestType_ST_XACT) || 738 (type == CacheRequestType_LDX_XACT) || 739 (type == CacheRequestType_ATOMIC); 740 741 // Copy the correct bytes out of the cache line into the subblock 742 SubBlock subblock(request_address, request_logical_address, size); 743 744 // Call into the Driver 745 g_system_ptr->getDriver()->conflictCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID); 746 747 // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock 748 // (This is only triggered for the non-TSO case) 749 if (write) { 750 assert(!TSO); 751 } 752} 753 |
|
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 --- 58 unchanged lines hidden (view full) --- 705 } 706 707 if (TSO) { 708 return m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady(); 709 } 710 return true; 711} 712 | 754void Sequencer::printDebug(){ 755 //notify driver of debug 756 g_system_ptr->getDriver()->printDebug(); 757} 758 759// Returns true if the sequencer already has a load or store outstanding 760bool 761Sequencer::isReady(const Packet* pkt) const --- 58 unchanged lines hidden (view full) --- 820 } 821 822 if (TSO) { 823 return m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady(); 824 } 825 return true; 826} 827 |
713// Called by Driver (Simics or Tester). | 828// Called by Driver |
714void 715Sequencer::makeRequest(const Packet* pkt, void* data) 716{ 717 int cpu_number = pkt->req->contextId(); 718 la_t logical_addr = pkt->req->getVaddr(); 719 pa_t physical_addr = pkt->req->getPaddr(); 720 int request_size = pkt->getSize(); 721 CacheRequestType type_of_request; --- 59 unchanged lines hidden (view full) --- 781 data_ptr); 782 783 if (hit && (request.getType() == CacheRequestType_IFETCH || !REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) ) { 784 DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path hit"); 785 hitCallback(request, *data_ptr, GenericMachineType_L1Cache, thread); 786 return true; 787 } 788 | 829void 830Sequencer::makeRequest(const Packet* pkt, void* data) 831{ 832 int cpu_number = pkt->req->contextId(); 833 la_t logical_addr = pkt->req->getVaddr(); 834 pa_t physical_addr = pkt->req->getPaddr(); 835 int request_size = pkt->getSize(); 836 CacheRequestType type_of_request; --- 59 unchanged lines hidden (view full) --- 896 data_ptr); 897 898 if (hit && (request.getType() == CacheRequestType_IFETCH || !REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) ) { 899 DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path hit"); 900 hitCallback(request, *data_ptr, GenericMachineType_L1Cache, thread); 901 return true; 902 } 903 |
789#if 0 790 uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 791 uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 792 uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 793 uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 794 cout << "START PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl;; 795#endif 796 | |
797 if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) { 798 799 // See if we can satisfy the load entirely from the store buffer 800 SubBlock subblock(line_address(request.getAddress()), request.getSize()); 801 if (m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->trySubBlock(subblock)) { 802 DataBlock dummy; 803 hitCallback(request, dummy, GenericMachineType_NULL, thread); // Call with an 'empty' datablock, since the data is in the store buffer 804 return true; --- 126 unchanged lines hidden (view full) --- 931void Sequencer::checkCoherence(const Address& addr) { 932#ifdef CHECK_COHERENCE 933 g_system_ptr->checkGlobalCoherenceInvariant(addr); 934#endif 935} 936 937bool Sequencer::getRubyMemoryValue(const Address& addr, char* value, 938 unsigned int size_in_bytes ) { | 904 if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) { 905 906 // See if we can satisfy the load entirely from the store buffer 907 SubBlock subblock(line_address(request.getAddress()), request.getSize()); 908 if (m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->trySubBlock(subblock)) { 909 DataBlock dummy; 910 hitCallback(request, dummy, GenericMachineType_NULL, thread); // Call with an 'empty' datablock, since the data is in the store buffer 911 return true; --- 126 unchanged lines hidden (view full) --- 1038void Sequencer::checkCoherence(const Address& addr) { 1039#ifdef CHECK_COHERENCE 1040 g_system_ptr->checkGlobalCoherenceInvariant(addr); 1041#endif 1042} 1043 1044bool Sequencer::getRubyMemoryValue(const Address& addr, char* value, 1045 unsigned int size_in_bytes ) { |
939 if(g_SIMICS){ | 1046 if(g_SIMULATING){ |
940 for(unsigned int i=0; i < size_in_bytes; i++) { | 1047 for(unsigned int i=0; i < size_in_bytes; i++) { |
941 value[i] = SIMICS_read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, 942 addr.getAddress() + i, 1 ); | 1048 std::cerr << __FILE__ << "(" << __LINE__ << "): Not implemented. " << std::endl; 1049 value[i] = 0; // _read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, 1050 // addr.getAddress() + i, 1 ); |
943 } 944 return false; // Do nothing? 945 } else { 946 bool found = false; 947 const Address lineAddr = line_address(addr); 948 DataBlock data; 949 PhysAddress paddr(addr); 950 DataBlock* dataPtr = &data; --- 50 unchanged lines hidden (view full) --- 1001 return true; 1002 } 1003} 1004 1005bool Sequencer::setRubyMemoryValue(const Address& addr, char *value, 1006 unsigned int size_in_bytes) { 1007 char test_buffer[64]; 1008 | 1051 } 1052 return false; // Do nothing? 1053 } else { 1054 bool found = false; 1055 const Address lineAddr = line_address(addr); 1056 DataBlock data; 1057 PhysAddress paddr(addr); 1058 DataBlock* dataPtr = &data; --- 50 unchanged lines hidden (view full) --- 1109 return true; 1110 } 1111} 1112 1113bool Sequencer::setRubyMemoryValue(const Address& addr, char *value, 1114 unsigned int size_in_bytes) { 1115 char test_buffer[64]; 1116 |
1009 if(g_SIMICS){ | 1117 if(g_SIMULATING){ |
1010 return false; // Do nothing? 1011 } else { 1012 // idea here is that coherent cache should find the 1013 // latest data, the update it 1014 bool found = false; 1015 const Address lineAddr = line_address(addr); 1016 PhysAddress paddr(addr); 1017 DataBlock data; --- 65 unchanged lines hidden (view full) --- 1083 WARN_EXPR((int) test_buffer[0]); 1084 ERROR_MSG("setRubyMemoryValue failed to set value."); 1085 } 1086 } 1087 1088 return true; 1089 } 1090} | 1118 return false; // Do nothing? 1119 } else { 1120 // idea here is that coherent cache should find the 1121 // latest data, the update it 1122 bool found = false; 1123 const Address lineAddr = line_address(addr); 1124 PhysAddress paddr(addr); 1125 DataBlock data; --- 65 unchanged lines hidden (view full) --- 1191 WARN_EXPR((int) test_buffer[0]); 1192 ERROR_MSG("setRubyMemoryValue failed to set value."); 1193 } 1194 } 1195 1196 return true; 1197 } 1198} |
1199 |
|