├── core ├── aux_ │ ├── layout │ │ ├── empty.hpp │ │ ├── begin_component_implementation.hpp │ │ ├── end_component_implementation.hpp │ │ ├── end_comp_configuration_sec.hpp │ │ ├── end_component_declaration.hpp │ │ ├── end_comp_instantiation_sec.hpp │ │ ├── end_comp_wiring_sec.hpp │ │ ├── end_drive_section.hpp │ │ ├── end_declaration_section.hpp │ │ ├── begin_comp_instantiation_sec.hpp │ │ ├── begin_drive_section.hpp │ │ ├── begin_comp_configuration_sec.hpp │ │ ├── begin_declaration_section.hpp │ │ ├── begin_component_declaration.hpp │ │ └── begin_comp_wiring_sec.hpp │ └── stats │ │ └── stats_aux_.hpp ├── debug │ ├── aux_ │ │ ├── default_ops.hpp │ │ ├── reset.hpp │ │ ├── clear_macros.hpp │ │ ├── runtime_sev.hpp │ │ ├── dev_macros.hpp │ │ ├── inv_macros.hpp │ │ ├── tmp_macros.hpp │ │ ├── crit_macros.hpp │ │ ├── verb_macros.hpp │ │ ├── iface_macros.hpp │ │ ├── trace_macros.hpp │ │ ├── vverb_macros.hpp │ │ ├── new_categories.hpp │ │ ├── declare_new_categories.hpp │ │ └── assert_macros.hpp │ ├── parser.hpp │ ├── severity.hpp │ ├── target.hpp │ ├── entry.hpp │ ├── field.hpp │ ├── target.cpp │ ├── field.cpp │ ├── format.hpp │ └── control.hpp ├── qemu │ ├── api_wrappers.cpp │ ├── api_wrappers.hpp │ ├── bitUtilities.hpp │ ├── configuration_api.cpp │ ├── qemu.h │ ├── bitUtilities.cpp │ ├── attribute_value.hpp │ ├── mai_api.cpp │ ├── aux_ │ │ ├── qemu_command_manager.hpp │ │ └── qemu_command_manager.cpp │ └── api.cpp ├── simulator_name.hpp ├── drive_reference.hpp ├── boost_extensions │ ├── padded_string_cast.hpp │ └── intrusive_ptr.hpp ├── targets │ ├── AARCH64.hpp │ └── RISCV.hpp ├── target.hpp ├── flexus.hpp ├── types.cpp └── component_interface.hpp ├── .clang-format-ignore ├── target ├── _profile │ ├── debug │ ├── release │ ├── relwithdebinfo │ ├── custom-gcc │ └── linux_x86_64-common ├── knottykraken │ ├── knottykraken.cmake │ ├── 1x3-mesh.topology │ └── 2x3-mesh.topology ├── nocout-knottykraken │ └── knottykraken.cmake ├── semikraken │ └── semikraken.cmake └── nocout-semikraken │ └── nocout-semikraken.cmake ├── components ├── MultiNic │ ├── MultiNic1.hpp │ ├── MultiNic2.hpp │ ├── MultiNic3.hpp │ ├── MultiNic4.hpp │ ├── MultiNic2Impl.cpp │ ├── MultiNic3Impl.cpp │ ├── MultiNic4Impl.cpp │ ├── MultiNic1Impl.cpp │ └── MultiNicX.hpp ├── CommonQEMU │ ├── MessageQueues.cpp │ ├── TypeSafeEnum.hpp │ ├── Slices │ │ ├── Mux.hpp │ │ ├── ExecuteState.hpp │ │ ├── FillType.cpp │ │ ├── FillType.hpp │ │ ├── PerfectPlacementSlice.cpp │ │ ├── ReuseDistanceSlice.cpp │ │ ├── FillLevel.hpp │ │ ├── FillLevel.cpp │ │ ├── PredictorMessage.cpp │ │ ├── MRCMessage.cpp │ │ ├── ArchitecturalInstruction.cpp │ │ ├── AbstractInstruction.cpp │ │ ├── NetworkMessage.hpp │ │ ├── RegionScoutMessage.cpp │ │ ├── PrefetchMessage.cpp │ │ ├── PrefetchCommand.cpp │ │ ├── PredictorMessage.hpp │ │ ├── IndexMessage.hpp │ │ ├── CMOBMessage.hpp │ │ ├── MRCMessage.hpp │ │ ├── DirectoryEntry.cpp │ │ ├── PrefetchCommand.hpp │ │ ├── DirectoryMessage.hpp │ │ └── AbstractInstruction.hpp │ ├── CachePlacementPolicyDefn.hpp │ ├── OneWayMux.hpp │ ├── Util.hpp │ ├── StandardDeviation.hpp │ ├── Transports │ │ ├── PredictorTransport.hpp │ │ ├── TranslationTransport.hpp │ │ ├── InstructionTransport.hpp │ │ ├── DirectoryTransport.hpp │ │ ├── PrefetchTransport.hpp │ │ └── NetworkTransport.hpp │ ├── DoubleWord.cpp │ ├── OneWayMuxImpl.cpp │ ├── MemoryMap.hpp │ └── GlobalHasher.hpp ├── uArch │ ├── ValueTracker.cpp │ ├── CoreModel │ │ ├── bbv.hpp │ │ ├── actions.cpp │ │ └── FPStatRegisters.hpp │ ├── MapTable.cpp │ └── RegisterType.hpp ├── uFetch │ ├── PortCombiner.hpp │ └── PortCombinerImpl.cpp ├── TLBControllers │ ├── TLBController.cpp │ └── TLBController.hpp ├── TraceTrackerQEMU │ ├── TraceTrackerComponent.hpp │ └── TraceTrackerComponentImpl.cpp ├── Cache │ └── BasicCacheState.cpp ├── BranchPredictor │ ├── BTBEntry.hpp │ ├── RAS.hpp │ ├── RAS.cpp │ ├── BTBSet.hpp │ ├── BTB.hpp │ ├── ITTAGE.h │ └── BTBSet.cpp ├── MMU │ ├── TranslationState.hpp │ ├── MMU.hpp │ ├── TranslationGranules.hpp │ ├── pageWalk.hpp │ └── TTResolvers.hpp ├── MTManager │ ├── MTManager.hpp │ └── MTManagerComponent.hpp ├── Decoder │ ├── encodings │ │ ├── Unallocated.hpp │ │ ├── DataProcImm.hpp │ │ ├── DataProcReg.hpp │ │ ├── Encodings.cpp │ │ ├── Branch.hpp │ │ └── LoadStore.hpp │ ├── SemanticActions │ │ ├── RegisterValueExtractor.hpp │ │ ├── ExceptionAction.cpp │ │ ├── PredicatedSemanticAction.hpp │ │ ├── MapDestInOrderAction.cpp │ │ ├── ReadConstantAction.cpp │ │ ├── ReadPCAction.cpp │ │ ├── ReadNZCVAction.cpp │ │ ├── InvertAction.cpp │ │ └── IncrementAction.cpp │ ├── Conditions.hpp │ ├── Interactions.hpp │ ├── Constraints.hpp │ ├── Decoder.hpp │ ├── InstructionComponentBuffer.hpp │ ├── Validations.hpp │ └── OperandMap.hpp ├── MemoryMap │ └── MemoryMap.hpp ├── CMPCache │ ├── CacheState.cpp │ └── AbstractRegionDirectory.hpp ├── NetShim │ ├── NetShim.hpp │ ├── MemoryNetwork.hpp │ ├── netnode.cpp │ └── netnode.hpp ├── MemoryLoopback │ └── MemoryLoopback.hpp ├── PhantomCPU │ ├── PhantomCPU.hpp │ └── PhantomCPU.cpp └── FetchAddressGenerate │ └── FetchAddressGenerate.hpp ├── README.md ├── .clang-format ├── .github └── workflows │ └── 00-build.yaml ├── CMakeLists.txt └── .vscode └── settings.json /core/aux_/layout/empty.hpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.clang-format-ignore: -------------------------------------------------------------------------------- 1 | core/checkpoint/* 2 | core/doxygen.config 3 | core/debug.cfg 4 | -------------------------------------------------------------------------------- /target/_profile/debug: -------------------------------------------------------------------------------- 1 | include(linux_x86_64-common) 2 | 3 | [settings] 4 | build_type=Debug -------------------------------------------------------------------------------- /target/_profile/release: -------------------------------------------------------------------------------- 1 | include(linux_x86_64-common) 2 | 3 | [settings] 4 | build_type=Release -------------------------------------------------------------------------------- /components/MultiNic/MultiNic1.hpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 1 3 | #include "MultiNicX.hpp" 4 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 2 3 | #include "MultiNicX.hpp" 4 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic3.hpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 3 3 | #include "MultiNicX.hpp" 4 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic4.hpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 4 3 | #include "MultiNicX.hpp" 4 | -------------------------------------------------------------------------------- /target/_profile/relwithdebinfo: -------------------------------------------------------------------------------- 1 | include(linux_x86_64-common) 2 | 3 | [settings] 4 | build_type=RelWithDebInfo 5 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic2Impl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 2 3 | #include "MultiNicXImpl.hpp" 4 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic3Impl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 3 3 | #include "MultiNicXImpl.hpp" 4 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic4Impl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 4 3 | #include "MultiNicXImpl.hpp" 4 | -------------------------------------------------------------------------------- /target/_profile/custom-gcc: -------------------------------------------------------------------------------- 1 | [conf] 2 | tools.build:compiler_executables={'c':'/opt/qflex/bin/gcc','cpp':'/opt/qflex/bin/g++'} -------------------------------------------------------------------------------- /core/debug/aux_/default_ops.hpp: -------------------------------------------------------------------------------- 1 | #undef DBG__internal_DEFAULT_OPS 2 | #define DBG__internal_DEFAULT_OPS DBG_SetDefaultOps 3 | -------------------------------------------------------------------------------- /core/debug/aux_/reset.hpp: -------------------------------------------------------------------------------- 1 | #undef DBG_SetDefaultOps 2 | #undef DBG__internal_DEFAULT_OPS 3 | #define DBG__internal_DEFAULT_OPS 4 | -------------------------------------------------------------------------------- /components/CommonQEMU/MessageQueues.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DBG_DefineCategories CommonQueues 4 | #include DBG_Control() 5 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNic1Impl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define FLEXUS_MULTI_NIC_NUMPORTS 1 3 | #include "MultiNicXImpl.hpp" 4 | 5 | #define DBG_DefineCategories MultiNic 6 | #include DBG_Control() 7 | -------------------------------------------------------------------------------- /components/uArch/ValueTracker.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ValueTracker.hpp" 3 | 4 | namespace nuArch { 5 | 6 | ValueTracker** ValueTracker::theGlobalTracker = nullptr; 7 | int ValueTracker::theNumTrackers = 0; 8 | 9 | } // namespace nuArchARM -------------------------------------------------------------------------------- /core/aux_/layout/begin_component_implementation.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_BEGIN_COMPONENT 2 | #error "This component never declared the FLEXUS_BEGIN_COMPONENT macro" 3 | #endif // FLEXUS_COMPONENT 4 | 5 | #define FLEXUS__LAYOUT_IN_COMPONENT_IMPLEMENTATION 6 | 7 | #define FLEXUS_internal_COMP_DEBUG_SEV DBG_internal_Sev_to_int(VVerb) 8 | -------------------------------------------------------------------------------- /core/debug/aux_/clear_macros.hpp: -------------------------------------------------------------------------------- 1 | #undef DBG__internal_MinimumSeverity 2 | 3 | #undef DBG__internal_Tmp 4 | #undef DBG__internal_Crit 5 | #undef DBG__internal_Dev 6 | #undef DBG__internal_Trace 7 | #undef DBG__internal_Iface 8 | #undef DBG__internal_Verb 9 | #undef DBG__internal_VVerb 10 | #undef DBG__internal_Inv 11 | -------------------------------------------------------------------------------- /core/debug/aux_/runtime_sev.hpp: -------------------------------------------------------------------------------- 1 | struct DBG__SetRuntimeMinSev 2 | { 3 | DBG__SetRuntimeMinSev() 4 | { 5 | Flexus::Dbg::Debugger::debugger().setMinSev( 6 | Flexus::Dbg::tSeverity::Severity(DBG_internal_Sev_to_int(DBG_SetInitialRuntimeMinSev))); 7 | } 8 | 9 | } DBG__theSetRuntimeMinSev; 10 | -------------------------------------------------------------------------------- /target/_profile/linux_x86_64-common: -------------------------------------------------------------------------------- 1 | [settings] 2 | arch=x86_64 3 | compiler=gcc 4 | compiler.cppstd=14 5 | compiler.libcxx=libstdc++11 6 | compiler.version=13 7 | compiler.threads=posix 8 | os=Linux 9 | 10 | [conf] 11 | tools.build:verbosity=verbose 12 | tools.compilation:verbosity=verbose 13 | tools.cmake.cmake_layout:build_folder_vars=['self.name'] -------------------------------------------------------------------------------- /target/knottykraken/knottykraken.cmake: -------------------------------------------------------------------------------- 1 | set(REQUIRED_COMPONENTS 2 | CommonQEMU 3 | uFetch 4 | Decoder 5 | uArch 6 | FetchAddressGenerate 7 | BranchPredictor 8 | Cache 9 | MemoryLoopback 10 | MemoryMap 11 | CMPCache 12 | MultiNic 13 | NetShim 14 | TraceTrackerQEMU 15 | MTManager 16 | SplitDestinationMapper 17 | MMU 18 | ) -------------------------------------------------------------------------------- /target/nocout-knottykraken/knottykraken.cmake: -------------------------------------------------------------------------------- 1 | set(REQUIRED_COMPONENTS 2 | CommonQEMU 3 | uFetch 4 | Decoder 5 | uArch 6 | FetchAddressGenerate 7 | BranchPredictor 8 | Cache 9 | MemoryLoopback 10 | MemoryMap 11 | CMPCache 12 | MultiNic 13 | NetShim 14 | TraceTrackerQEMU 15 | MTManager 16 | SplitDestinationMapper 17 | MMU 18 | ) -------------------------------------------------------------------------------- /core/aux_/layout/end_component_implementation.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__LAYOUT_IN_COMPONENT_IMPLEMENTATION 2 | #error "Found end of component implementation without a corresponding begin" 3 | #endif // FLEXUS__LAYOUT_IN_COMPONENT_IMPLEMENTATION 4 | 5 | #undef FLEXUS__LAYOUT_IN_COMPONENT_IMPLEMENTATION 6 | 7 | #undef FLEXUS_BEGIN_COMPONENT 8 | #undef FLEXUS_END_COMPONENT 9 | -------------------------------------------------------------------------------- /target/semikraken/semikraken.cmake: -------------------------------------------------------------------------------- 1 | set(REQUIRED_COMPONENTS 2 | CommonQEMU 3 | uFetch 4 | Decoder 5 | uArch 6 | FetchAddressGenerate 7 | BranchPredictor 8 | Cache 9 | MemoryLoopback 10 | MemoryMap 11 | CMPCache 12 | MultiNic 13 | NetShim 14 | TraceTrackerQEMU 15 | MTManager 16 | SplitDestinationMapper 17 | MMU 18 | PhantomCPU 19 | ) -------------------------------------------------------------------------------- /target/nocout-semikraken/nocout-semikraken.cmake: -------------------------------------------------------------------------------- 1 | set(REQUIRED_COMPONENTS 2 | CommonQEMU 3 | uFetch 4 | Decoder 5 | uArch 6 | FetchAddressGenerate 7 | BranchPredictor 8 | Cache 9 | MemoryLoopback 10 | MemoryMap 11 | CMPCache 12 | MultiNic 13 | NetShim 14 | TraceTrackerQEMU 15 | MTManager 16 | SplitDestinationMapper 17 | MMU 18 | PhantomCPU 19 | ) -------------------------------------------------------------------------------- /core/qemu/api_wrappers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Flexus { 5 | namespace Qemu { 6 | namespace API { 7 | void 8 | QEMU_write_configuration_to_file(const char* aFilename) 9 | { 10 | /*Qemu::API::SIM_write_configuration_to_file(aFilename);*/ 11 | // XXX: Does nothing. 12 | } 13 | 14 | } // namespace API 15 | } // namespace Qemu 16 | } // namespace Flexus 17 | -------------------------------------------------------------------------------- /components/CommonQEMU/TypeSafeEnum.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TYPESAFEENUM_HPP 2 | #define TYPESAFEENUM_HPP 3 | 4 | template 5 | class enumerator 6 | { 7 | protected: 8 | enumerator(const _ValType n) 9 | : val(n) 10 | { 11 | } 12 | const _ValType val; 13 | 14 | public: 15 | const _ValType value() const { return val; } 16 | 17 | const bool operator==(const _ValType& a) const { return (val == a.val); } 18 | }; 19 | 20 | #endif // TYPESAFEENUM_HPP 21 | -------------------------------------------------------------------------------- /core/aux_/layout/end_comp_configuration_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__LAYOUT_COMPONENT_CONFIGURATION_SECTION 2 | #error "End of component configuration section without preceding begin." 3 | #endif // FLEXUS__LAYOUT_COMPONENT_CONFIGURATION_SECTION 4 | 5 | #undef FLEXUS__LAYOUT_COMPONENT_CONFIGURATION_SECTION 6 | #undef FLEXUS__LAYOUT_IN_SECTION 7 | 8 | #define FLEXUS__LAYOUT_COMPONENTS_CONFIGURED 9 | 10 | #undef CREATE_CONFIGURATION 11 | 12 | } // End namespace Wiring 13 | } // End namespace Flexus 14 | -------------------------------------------------------------------------------- /core/qemu/api_wrappers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_QEMU_API_WRAPPERS_HPP__INCLUDED 2 | #define FLEXUS_CORE_QEMU_API_WRAPPERS_HPP__INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace Qemu { 9 | namespace API { 10 | #include 11 | 12 | void 13 | QEMU_write_configuration_to_file(const char* aFilename); 14 | } // namespace API 15 | } // namespace Qemu 16 | } // namespace Flexus 17 | 18 | #endif // FLEXUS_CORE_QEMU_API_WRAPPERS_HPP__INCLUDED 19 | -------------------------------------------------------------------------------- /core/debug/parser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_PARSER_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_PARSER_HPP_INCLUDED 3 | 4 | #include 5 | 6 | namespace Flexus { 7 | namespace Dbg { 8 | 9 | class ParserImpl; 10 | 11 | struct Parser 12 | { 13 | static Parser& parser(); 14 | 15 | virtual ~Parser() {}; 16 | virtual void parse(std::string const& aConfigFile) = 0; 17 | }; 18 | 19 | } // namespace Dbg 20 | } // namespace Flexus 21 | 22 | #endif // FLEXUS_CORE_DEBUG_PARSER_HPP_INCLUDED 23 | -------------------------------------------------------------------------------- /core/aux_/layout/end_component_declaration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__LAYOUT_IN_COMPONENT_DECLARATION 2 | #error "Found end of component declaration without a corresponding begin" 3 | #endif // FLEXUS__LAYOUT_IN_COMPONENT_DECLARATION 4 | 5 | #undef FLEXUS__LAYOUT_IN_COMPONENT_DECLARATION 6 | 7 | #undef COMPONENT_NO_PARAMETERS 8 | #undef COMPONENT_PARAMETERS 9 | #undef PARAMETER 10 | 11 | #undef COMPONENT_INTERFACE 12 | #undef PORT 13 | #undef DRIVE 14 | 15 | #undef FLEXUS_BEGIN_COMPONENT 16 | #undef FLEXUS_END_COMPONENT 17 | -------------------------------------------------------------------------------- /core/qemu/bitUtilities.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _BIT_UTILITIES_HPP_DEFINED 2 | #define _BIT_UTILITIES_HPP_DEFINED 3 | // Helper for shifting and extracting values from bit-ranges 4 | unsigned long long 5 | extractBitsWithBounds(unsigned long long input, unsigned upperBitBound, unsigned lowerBitBound); 6 | unsigned long long 7 | extractBitsWithRange(unsigned long long input, unsigned lowerBound, unsigned numBits); 8 | bool 9 | extractSingleBitAsBool(unsigned long long input, unsigned bitNum); 10 | #endif // _BIT_UTILITIES_HPP_DEFINED_ 11 | -------------------------------------------------------------------------------- /core/aux_/stats/stats_aux_.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_AUX__STATS_STATS_AUX__HPP__INCLUDED 2 | #define FLEXUS_CORE_AUX__STATS_STATS_AUX__HPP__INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #endif // FLEXUS_CORE_AUX__STATS_STATS_AUX__HPP__INCLUDED 13 | -------------------------------------------------------------------------------- /core/aux_/layout/end_comp_instantiation_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__LAYOUT_COMPONENT_INSTATIATION_SECTION 2 | #error "End of component instantiation section without preceding begin." 3 | #endif // FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 4 | 5 | #undef FLEXUS__LAYOUT_COMPONENT_INSTATIATION_SECTION 6 | #undef FLEXUS__LAYOUT_IN_SECTION 7 | 8 | #define FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 9 | 10 | #undef SCALE_WITH_SYSTEM_WIDTH 11 | #undef FIXED 12 | #undef MULTIPLY 13 | #undef DIVIDE 14 | 15 | } // End Wiring namespace 16 | } // End Flexus namespace 17 | -------------------------------------------------------------------------------- /core/debug/severity.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_SEVERITY_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_SEVERITY_HPP_INCLUDED 3 | 4 | namespace Flexus { 5 | namespace Dbg { 6 | 7 | enum Severity 8 | { 9 | SevInv = 0, 10 | SevVVerb, 11 | SevVerb, 12 | SevIface, 13 | SevTrace, 14 | SevDev, 15 | SevCrit, 16 | SevTmp, 17 | NumSev 18 | }; 19 | 20 | std::string const& 21 | toString(Severity aSeverity); 22 | 23 | } // namespace Dbg 24 | } // namespace Flexus 25 | 26 | #endif // FLEXUS_CORE_DEBUG_SEVERITY_HPP_INCLUDED 27 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/Mux.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__Mux_HPP_INCLUDED 2 | #define FLEXUS_SLICES__Mux_HPP_INCLUDED 3 | 4 | #include 5 | 6 | #define FLEXUS_Mux_TYPE_PROVIDED 7 | 8 | namespace Flexus { 9 | namespace SharedTypes { 10 | struct Mux : public boost::counted_base 11 | { 12 | explicit Mux(int32_t a) 13 | : source(a) 14 | { 15 | } 16 | int32_t source; 17 | }; 18 | 19 | } // namespace SharedTypes 20 | } // namespace Flexus 21 | 22 | #endif // FLEXUS_SLICES__Mux_HPP_INCLUDED 23 | -------------------------------------------------------------------------------- /components/uArch/CoreModel/bbv.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_uARCH_COREMODEL_BBV__INCLUDED 3 | #define FLEXUS_uARCH_COREMODEL_BBV__INCLUDED 4 | 5 | #include "core/types.hpp" 6 | 7 | namespace nuArch { 8 | using Flexus::SharedTypes::PhysicalMemoryAddress; 9 | 10 | struct BBVTracker 11 | { 12 | static BBVTracker* createBBVTracker(int32_t aCPUIndex); 13 | virtual void commitInsn(PhysicalMemoryAddress aPC, bool isBranch) = 0; 14 | virtual ~BBVTracker() {} 15 | }; 16 | 17 | } // namespace nuArch 18 | 19 | #endif // FLEXUS_uARCH_COREMODEL_BBV__INCLUDED 20 | -------------------------------------------------------------------------------- /components/CommonQEMU/CachePlacementPolicyDefn.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _CACHEPLACEMENTPOLICYDEFN_HPP 2 | #define _CACHEPLACEMENTPOLICYDEFN_HPP 3 | 4 | // Cache placement policy 5 | enum tPlacement 6 | { 7 | kRNUCACache, 8 | kPrivateCache, 9 | kSharedCache, 10 | kASRCache 11 | }; 12 | 13 | // Page classes 14 | enum tPageState 15 | { 16 | kPageStateInvalid = 0x0, 17 | kPageStatePrivate = 0x1, 18 | kPageStateShared = 0x2, 19 | kPageStateCustomerService = 0x3 20 | }; 21 | 22 | #endif // _CACHEPLACEMENTPOLICYDEFN_HPP 23 | -------------------------------------------------------------------------------- /core/aux_/layout/end_comp_wiring_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__CORE_TEST 2 | 3 | #ifndef FLEXUS__LAYOUT_COMPONENT_WIRING_SECTION 4 | #error "End of component wiring section without preceding begin." 5 | #endif // FLEXUS__LAYOUT_COMPONENT_WIRING_SECTION 6 | 7 | #undef FLEXUS__LAYOUT_COMPONENT_WIRING_SECTION 8 | #undef FLEXUS__LAYOUT_IN_SECTION 9 | 10 | #define FLEXUS__LAYOUT_COMPONENTS_WIRED 11 | 12 | #endif // FLEXUS__CORE_TEST 13 | 14 | } // end connectWiring 15 | 16 | #undef WIRE 17 | 18 | } // End Wiring namespace 19 | } // End nFlexus namespace 20 | 21 | #undef nFLEXUS 22 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/ExecuteState.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__ExecuteState_HPP_INCLUDED 2 | #define FLEXUS_SLICES__ExecuteState_HPP_INCLUDED 3 | 4 | #include 5 | 6 | #define FLEXUS_ExecuteState_TYPE_PROVIDED 7 | 8 | namespace Flexus { 9 | namespace SharedTypes { 10 | 11 | struct ExecuteState : public boost::counted_base 12 | { 13 | protected: 14 | // Only may be created by Execute component 15 | ExecuteState() {} 16 | }; 17 | 18 | } // namespace SharedTypes 19 | } // namespace Flexus 20 | 21 | #endif // FLEXUS_SLICES__ExecuteState_HPP_INCLUDED 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Flexus

2 |

3 |
4 | Documentation | GitHub | Website 5 |

6 |

7 | 8 | ## [🏆 Contributors](#contributors) 9 | 10 |

11 | 12 | 13 | 14 |

15 | 16 | Made with [contrib.rocks](https://contrib.rocks). 17 | -------------------------------------------------------------------------------- /components/uFetch/PortCombiner.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | // clang-format off 6 | #define FLEXUS_BEGIN_COMPONENT PortCombiner 7 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 8 | 9 | COMPONENT_NO_PARAMETERS ; 10 | 11 | COMPONENT_INTERFACE( 12 | PORT( PushOutput, MemoryTransport, FetchMissOut ) 13 | PORT( PushInput, MemoryTransport, SnoopIn ) 14 | PORT( PushInput, MemoryTransport, ReplyIn ) 15 | ); 16 | 17 | #include FLEXUS_END_COMPONENT_DECLARATION() 18 | #define FLEXUS_END_COMPONENT PortCombiner 19 | // clang-format on 20 | -------------------------------------------------------------------------------- /components/TLBControllers/TLBController.cpp: -------------------------------------------------------------------------------- 1 | // 2 | 3 | /* Basic goals: 4 | * - sub-class the CacheController with TLB specific functionality 5 | * - adds a large interface to the MMU component in core/qemu 6 | * - improve readability and usability 7 | */ 8 | #include "TLBController.hpp" 9 | 10 | using namespace Flexus; 11 | 12 | #define DBG_DeclareCategories TLBCtrl 13 | #define DBG_SetDefaultOps AddCat(TLBCtrl) Set((CompName) << theName) Set((CompIdx) << theNodeId) 14 | #include DBG_Control() 15 | 16 | namespace nTLB { 17 | } // end namespace nTLB 18 | 19 | #define DBG_Reset 20 | #include DBG_Control() 21 | // EOF 22 | -------------------------------------------------------------------------------- /core/simulator_name.hpp: -------------------------------------------------------------------------------- 1 | /*! \file simulator_name.hpp 2 | \brief Forward declaration of theSimulatorName 3 | 4 | extern declaration of theSimulatorName. Used in the Standalone and 5 | Simics cores to be able to print out the name of the simulator. 6 | 7 | Revision History: 8 | - twenisch 12Jul02 Initial Revision 9 | */ 10 | 11 | #ifndef FLEXUS_SIMULATOR_NAME_HPP_INCLUDED 12 | #define FLEXUS_SIMULATOR_NAME_HPP_INCLUDED 13 | 14 | #include 15 | 16 | namespace Flexus { 17 | 18 | extern std::string theSimulatorName; 19 | 20 | } // namespace Flexus 21 | 22 | #endif // FLEXUS_SIMULATOR_NAME_HPP_INCLUDED 23 | -------------------------------------------------------------------------------- /core/drive_reference.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_DRIVE_REFERENCE_HPP_INCLUDED 2 | #define FLEXUS_DRIVE_REFERENCE_HPP_INCLUDED 3 | 4 | #include 5 | namespace Flexus { 6 | namespace Core { 7 | 8 | struct DriveBase 9 | { 10 | // This method is called every cycle. 11 | virtual ~DriveBase() {}; 12 | virtual index_t doCycle(index_t iter_idx) = 0; 13 | }; 14 | 15 | typedef DriveBase& DriveReference; 16 | 17 | } // End namespace Core 18 | namespace Wiring { 19 | 20 | extern Flexus::Core::DriveReference theDrive; 21 | 22 | } // End Namespace Wiring 23 | } // namespace Flexus 24 | 25 | #endif // FLEXUS_DRIVE_REFERENCE_HPP_INCLUDED 26 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/FillType.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Flexus { 7 | namespace SharedTypes { 8 | 9 | std::ostream& 10 | operator<<(std::ostream& anOstream, tFillType aType) 11 | { 12 | const char* const name[] = { "eCold", "eReplacement", "eCoherence", "eDGP", "eDMA", "ePrefetch", 13 | "eFetch", "eNAW", "eDataPrivate", "eDataSharedRO", "eDataSharedRW" }; 14 | anOstream << name[aType]; 15 | return anOstream; 16 | } 17 | 18 | } // namespace SharedTypes 19 | } // namespace Flexus -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/FillType.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__FillType_HPP_INCLUDED 2 | #define FLEXUS_SLICES__FillType_HPP_INCLUDED 3 | 4 | #include 5 | 6 | namespace Flexus { 7 | namespace SharedTypes { 8 | 9 | enum tFillType 10 | { 11 | eCold, 12 | eReplacement, 13 | eCoherence, 14 | eDGP, 15 | eDMA, 16 | ePrefetch, 17 | eFetch, 18 | eNAW, 19 | eDataPrivate, 20 | eDataSharedRO, 21 | eDataSharedRW, 22 | }; 23 | 24 | std::ostream& 25 | operator<<(std::ostream& anOstream, tFillType aType); 26 | 27 | } // namespace SharedTypes 28 | } // namespace Flexus 29 | 30 | #endif // FLEXUS_SLICES__FillType_HPP_INCLUDED -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PerfectPlacementSlice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | std::ostream& 7 | operator<<(std::ostream& s, PerfectPlacementSlice& aPerfectPlacementSlice) 8 | { 9 | char const* perfPlcSlice_types[] = { "Process Msg", "Make Block Writable" }; 10 | 11 | return s << "PerfectPlacementSlice[" << perfPlcSlice_types[aPerfectPlacementSlice.type()] << "]: Addr:0x" 12 | << std::hex << aPerfectPlacementSlice.address() << " Msg: " << aPerfectPlacementSlice.memMsg(); 13 | } 14 | 15 | } // namespace SharedTypes 16 | } // namespace Flexus 17 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/ReuseDistanceSlice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | std::ostream& 7 | operator<<(std::ostream& s, ReuseDistanceSlice& aReuseDistanceSlice) 8 | { 9 | char const* reuseDistSlice_types[] = { "Process Memory Message", "Get Mean Reuse Distance [Data]" }; 10 | 11 | return s << "ReuseDistanceSlice[" << reuseDistSlice_types[aReuseDistanceSlice.type()] << "]: Addr:0x" << std::hex 12 | << aReuseDistanceSlice.address() << " Msg: " << aReuseDistanceSlice.memMsg(); 13 | } 14 | 15 | } // namespace SharedTypes 16 | } // namespace Flexus 17 | -------------------------------------------------------------------------------- /core/qemu/configuration_api.cpp: -------------------------------------------------------------------------------- 1 | #include "core/qemu/configuration_api.hpp" 2 | 3 | #include "core/qemu/api_wrappers.hpp" 4 | #include "core/target.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Flexus { 11 | namespace Qemu { 12 | 13 | namespace aux_ { 14 | API::conf_class_t* 15 | RegisterClass_stub(std::string const& name, API::class_data_t* class_data) 16 | { 17 | return new API::conf_class_t; 18 | } 19 | 20 | API::conf_object_t* 21 | NewObject_stub(API::conf_class_t* aClass, std::string const& aName) 22 | { 23 | return new API::conf_object_t; 24 | } 25 | 26 | } // namespace aux_ 27 | 28 | } // namespace Qemu 29 | } // namespace Flexus -------------------------------------------------------------------------------- /target/knottykraken/1x3-mesh.topology: -------------------------------------------------------------------------------- 1 | # Boilerplate stuff 2 | ChannelLatency 1 3 | ChannelLatencyData 4 4 | ChannelLatencyControl 1 5 | LocalChannelLatencyDivider 4 6 | SwitchInputBuffers 1 7 | SwitchOutputBuffers 1 8 | SwitchInternalBuffersPerVC 1 9 | 10 | # Basic Switch/Node connections 11 | NumNodes 3 12 | NumSwitches 1 13 | SwitchPorts 7 14 | SwitchBandwidth 4 15 | 16 | Top Node 0 -> Switch 0:0 17 | Top Node 1 -> Switch 0:1 18 | Top Node 2 -> Switch 0:2 19 | 20 | # Topology for a 3 node MESH with 3 nodes per router 21 | 22 | # Deadlock-free routing tables 23 | 24 | # Switch 0 -> * 25 | Route Switch 0 -> 0 { 0:0 } 26 | Route Switch 0 -> 1 { 1:0 } 27 | Route Switch 0 -> 2 { 2:0 } 28 | -------------------------------------------------------------------------------- /components/TraceTrackerQEMU/TraceTrackerComponent.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // clang-format off 4 | #define FLEXUS_BEGIN_COMPONENT TraceTrackerComponent 5 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 6 | 7 | #include "components/CommonQEMU/TraceTracker.hpp" 8 | 9 | COMPONENT_PARAMETERS( 10 | PARAMETER(Enable, bool, "Enable Trace Tracker", "enable", false ) 11 | PARAMETER(NumNodes, int, "Number of nodes", "num-nodes", 16) 12 | PARAMETER(BlockSize, long, "Cache block size", "bsize", 64 ) 13 | ); 14 | 15 | COMPONENT_EMPTY_INTERFACE ; 16 | 17 | #include FLEXUS_END_COMPONENT_DECLARATION() 18 | #define FLEXUS_END_COMPONENT TraceTrackerComponent 19 | // clang-format on 20 | -------------------------------------------------------------------------------- /components/Cache/BasicCacheState.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | namespace nCache { 5 | 6 | const BasicCacheState BasicCacheState::Modified("Modified"); 7 | const BasicCacheState BasicCacheState::Owned("Owned"); 8 | const BasicCacheState BasicCacheState::Exclusive("Exclusive"); 9 | const BasicCacheState BasicCacheState::Shared("Shared"); 10 | const BasicCacheState BasicCacheState::Invalid("Invalid"); 11 | 12 | std::ostream& 13 | operator<<(std::ostream& os, const BasicCacheState& state) 14 | { 15 | os << state.name(); 16 | if (state.isProtected()) { os << "_X"; } 17 | if (state.prefetched()) { os << "_P"; } 18 | return os; 19 | } 20 | 21 | }; // namespace nCache 22 | -------------------------------------------------------------------------------- /components/uArch/CoreModel/actions.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "coreModelImpl.hpp" 3 | 4 | namespace nuArch { 5 | 6 | void 7 | CoreImpl::create(boost::intrusive_ptr anAction) 8 | { 9 | CORE_DBG(*anAction); 10 | theRescheduledActions.push(anAction); 11 | } 12 | void 13 | CoreImpl::reschedule(boost::intrusive_ptr anAction) 14 | { 15 | CORE_DBG(*anAction); 16 | theRescheduledActions.push(anAction); 17 | } 18 | 19 | bool 20 | ActionOrder::operator()(boost::intrusive_ptr const& l, 21 | boost::intrusive_ptr const& r) const 22 | { 23 | return l->instructionNo() > r->instructionNo(); 24 | } 25 | 26 | } // namespace nuArch 27 | -------------------------------------------------------------------------------- /core/boost_extensions/padded_string_cast.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_BOOST_EXTENSIONS_PADDED_STRING_CAST_INCLUDED 2 | #define FLEXUS_CORE_BOOST_EXTENSIONS_PADDED_STRING_CAST_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #if __cplusplus > 199711L 8 | #include 9 | #else 10 | #include 11 | #endif 12 | 13 | namespace boost { 14 | 15 | template 16 | std::string 17 | padded_string_cast(Source s) 18 | { 19 | std::ostringstream ss; 20 | ss << std::setfill(c) << std::setw(w) << s; 21 | return ss.str(); 22 | } 23 | 24 | } // namespace boost 25 | 26 | #endif // FLEXUS_CORE_BOOST_EXTENSIONS_PADDED_STRING_CAST_INCLUDED 27 | -------------------------------------------------------------------------------- /core/aux_/layout/end_drive_section.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__CORE_TEST 2 | 3 | #ifndef FLEXUS__LAYOUT_DRIVE_SECTION 4 | #error "End of component drive section without preceding begin." 5 | #endif // FLEXUS__LAYOUT_COMPONENT_WIRING_SECTION 6 | 7 | #undef FLEXUS__LAYOUT_DRIVE_SECTION 8 | #undef FLEXUS__LAYOUT_IN_SECTION 9 | 10 | #define FLEXUS__LAYOUT_DRIVES_ORDERED 11 | 12 | #endif // FLEXUS__CORE_TEST 13 | 14 | > drive_list; 15 | 16 | #undef DRIVE 17 | 18 | using Flexus::Core::Drive; 19 | using Flexus::Core::DriveReference; 20 | 21 | // Create the core Drive component which takes care of everything else 22 | Drive drive; 23 | DriveReference theDrive = drive; 24 | 25 | } // End namespace Flexus 26 | } // End namespace Wiring 27 | -------------------------------------------------------------------------------- /core/targets/AARCH64.hpp: -------------------------------------------------------------------------------- 1 | #if defined(FLEXUS_TARGET) && (FLEXUS_TARGET == 0) 2 | #error "Only a single target may be defined in a simulator" 3 | #endif // FLEXUS_TARGET 4 | 5 | #define FLEXUS_LITTLE_ENDIAN 1 6 | #define FLEXUS_BIG_ENDIAN 0 7 | 8 | #define FLEXUS_TARGET_ARM 1 9 | 10 | #define FLEXUS_TARGET FLEXUS_TARGET_ARM 11 | #define FLEXUS_TARGET_WORD_BITS 64 12 | #define FLEXUS_TARGET_VA_BITS 64 13 | #define FLEXUS_TARGET_PA_BITS 64 14 | #define FLEXUS_TARGET_ENDIAN FLEXUS_LITTLE_ENDIAN 15 | 16 | #define FLEXUS_TARGET_IS(target) (FLEXUS_TARGET == FLEXUS_TARGET_##target) 17 | 18 | #define TARGET_VA_BITS 64 19 | #define TARGET_PA_BITS 64 20 | #define TARGET_ARM 21 | 22 | #define TARGET_MEM_TRANS memory_transaction_t -------------------------------------------------------------------------------- /components/BranchPredictor/BTBEntry.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_BTB_ENTRY 2 | #define FLEXUS_BTB_ENTRY 3 | 4 | #include "components/uFetch/uFetchTypes.hpp" 5 | #include "core/types.hpp" 6 | 7 | using namespace Flexus::SharedTypes; 8 | 9 | class BTBEntry 10 | { 11 | public: 12 | bool valid; 13 | VirtualMemoryAddress thePC; 14 | mutable eBranchType theBranchType; 15 | mutable VirtualMemoryAddress theTarget; 16 | 17 | BTBEntry(VirtualMemoryAddress aPC, eBranchType aType, VirtualMemoryAddress aTarget) 18 | : valid(true) 19 | , thePC(aPC) 20 | , theBranchType(aType) 21 | , theTarget(aTarget) 22 | { 23 | } 24 | 25 | BTBEntry() 26 | : valid(false) 27 | { 28 | } 29 | }; 30 | 31 | #endif -------------------------------------------------------------------------------- /components/BranchPredictor/RAS.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_RAS 2 | #define FLEXUS_RAS 3 | 4 | #include "components/uFetch/uFetchTypes.hpp" 5 | #include "core/types.hpp" 6 | 7 | #include 8 | 9 | using namespace Flexus::SharedTypes; 10 | 11 | class ReturnAddressStack 12 | { 13 | private: 14 | std::vector stack; 15 | uint64_t size; 16 | 17 | public: 18 | ReturnAddressStack(): 19 | size(64) { 20 | stack.resize(size); 21 | } 22 | 23 | void push(uint64_t target); 24 | 25 | uint64_t pop(); 26 | 27 | void recover(BPredState& bpred); 28 | 29 | bool valid() const { 30 | return stack.size() != 0; 31 | } 32 | 33 | void get(std::vector &vec); 34 | }; 35 | 36 | #endif -------------------------------------------------------------------------------- /core/targets/RISCV.hpp: -------------------------------------------------------------------------------- 1 | #if defined(FLEXUS_TARGET) && (FLEXUS_TARGET == 0) 2 | #error "Only a single target may be defined in a simulator" 3 | #endif // FLEXUS_TARGET 4 | 5 | #define FLEXUS_LITTLE_ENDIAN 1 6 | #define FLEXUS_BIG_ENDIAN 0 7 | 8 | #define FLEXUS_TARGET_RISCV 1 9 | 10 | #define FLEXUS_TARGET FLEXUS_TARGET_RISCV 11 | #define FLEXUS_TARGET_WORD_BITS 64 12 | #define FLEXUS_TARGET_VA_BITS 64 13 | #define FLEXUS_TARGET_PA_BITS 64 14 | #define FLEXUS_TARGET_ENDIAN FLEXUS_LITTLE_ENDIAN 15 | 16 | #define FLEXUS_TARGET_IS(target) (FLEXUS_TARGET == FLEXUS_TARGET_##target) 17 | 18 | #define TARGET_VA_BITS 64 19 | #define TARGET_PA_BITS 64 20 | #define TARGET_RISCV 21 | 22 | #define TARGET_MEM_TRANS memory_transaction_t 23 | -------------------------------------------------------------------------------- /core/qemu/qemu.h: -------------------------------------------------------------------------------- 1 | #ifndef QEMU_H 2 | #define QEMU_H 3 | // not defined in api.c, defined in external binaries (exec.o, libqemuutil.a) 4 | struct CPUState; 5 | typedef struct CPUState CPUState; 6 | 7 | struct QemuOptsList; 8 | struct QemuOpts; 9 | typedef struct QemuOptsList QemuOptsList; 10 | typedef struct QemuOpts QemuOpts; 11 | 12 | typedef uint64_t hwaddr; 13 | 14 | void 15 | cpu_physical_memory_rw(hwaddr addr, uint8_t* buf, int len, int is_write); 16 | 17 | CPUState* 18 | qemu_get_cpu(int index); 19 | QemuOpts* 20 | qemu_opts_find(QemuOptsList* list, const char* id); 21 | QemuOptsList* 22 | qemu_find_opts(const char* group); 23 | uint64_t 24 | qemu_opt_get_number(QemuOpts* opts, const char* name, uint64_t defval); 25 | 26 | extern int smp_cpus; 27 | #endif 28 | -------------------------------------------------------------------------------- /components/CommonQEMU/OneWayMux.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT OneWayMux 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | COMPONENT_PARAMETERS( 9 | PARAMETER( InIWidth, int, "Number of InI input ports", "i_width", 1 ) 10 | PARAMETER( InDWidth, int, "Number of InD input ports", "d_width", 1 ) 11 | ); 12 | 13 | COMPONENT_INTERFACE( 14 | PORT( PushOutput, MemoryMessage, Out ) 15 | DYNAMIC_PORT_ARRAY( PushInput, MemoryMessage, InI ) 16 | DYNAMIC_PORT_ARRAY( PushInput, MemoryMessage, InD ) 17 | ); 18 | 19 | #include FLEXUS_END_COMPONENT_DECLARATION() 20 | #define FLEXUS_END_COMPONENT OneWayMux 21 | // clang-format on 22 | -------------------------------------------------------------------------------- /components/MMU/TranslationState.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__TRANS_STATE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__TRANS_STATE_HPP_INCLUDED 3 | #include "TTResolvers.hpp" 4 | 5 | #include 6 | #include // for shared_ptr 7 | 8 | namespace nMMU { 9 | 10 | class TTResolver; 11 | 12 | struct TranslationState : public boost::counted_base 13 | { 14 | // Stuff that carries MMU-internal state. 15 | uint8_t ELRegime; 16 | uint8_t requiredTableLookups; 17 | uint8_t currentLookupLevel; 18 | bool isBR0; 19 | uint32_t granuleSize; 20 | std::shared_ptr TTAddressResolver; 21 | uint64_t BlockSizeFromTTs; 22 | }; 23 | 24 | } // namespace nMMU 25 | #endif // FLEXUS_SLICES__TRANS_STATE_HPP_INCLUDED 26 | -------------------------------------------------------------------------------- /components/MTManager/MTManager.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_MTManager_MTManager_HPP_INCLUDED 3 | #define FLEXUS_MTManager_MTManager_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include DBG_Control() 10 | 11 | namespace nMTManager { 12 | 13 | struct MTManager 14 | { 15 | static MTManager* get(); 16 | 17 | virtual ~MTManager() {}; 18 | virtual uint32_t scheduleFAGThread(uint32_t aCoreIndex) = 0; 19 | virtual uint32_t scheduleFThread(uint32_t aCoreIndex) = 0; 20 | virtual bool runThisEX(uint32_t anIndex) = 0; 21 | virtual bool runThisD(uint32_t anIndex) = 0; 22 | }; 23 | 24 | } // namespace nMTManager 25 | 26 | #endif // FLEXUS_MTManager_MTManager_HPP_INCLUDED 27 | -------------------------------------------------------------------------------- /core/aux_/layout/end_declaration_section.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__LAYOUT_DECLARATION_SECTION 2 | #error "End of declaration section without preceding begin." 3 | #endif // FLEXUS_LAYOUT_COMPONENT_DECLARATION_SECTION 4 | 5 | #ifndef FLEXUS__COMPONENT_CHAIN_PREVIOUS 6 | #error "Last component forget to set the FLEXUS_COMPONENT_CHAIN_PREVIOUS macro" 7 | #endif // FLEXUS__COMPONENT_CHAIN_PREVIOUS 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #undef FLEXUS__LAYOUT_DECLARATION_SECTION 14 | #undef FLEXUS__LAYOUT_IN_SECTION 15 | 16 | #define FLEXUS__LAYOUT_COMPONENTS_DECLARED 17 | 18 | #undef FLEXUS__PREVIOUS_COMP_DECL 19 | #undef FLEXUS__COMP_DECL 20 | 21 | #undef FLEXUS_END_COMPONENT 22 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/FillLevel.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__FillLevel_HPP_INCLUDED 2 | #define FLEXUS_SLICES__FillLevel_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace SharedTypes { 9 | 10 | enum tFillLevel 11 | { 12 | eUnknown, 13 | eL1, 14 | eL2, 15 | eL3, 16 | eLocalMem, 17 | eRemoteMem, 18 | ePrefetchBuffer, 19 | ePeerL1Cache, 20 | eL2Prefetcher, 21 | eL1I, 22 | eCore, 23 | ePeerL2, 24 | eDirectory, 25 | NumFillLevels 26 | }; 27 | 28 | std::ostream& 29 | operator<<(std::ostream& anOstream, tFillLevel aType); 30 | 31 | std::string 32 | fillLevelName(tFillLevel aType); 33 | 34 | } // namespace SharedTypes 35 | } // namespace Flexus 36 | 37 | #endif // FLEXUS_SLICES__FillLevel_HPP_INCLUDED -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/FillLevel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Flexus { 6 | namespace SharedTypes { 7 | 8 | std::string 9 | fillLevelName(tFillLevel aType) 10 | { 11 | const char* const name[] = { "eUnknown", "eL1", "eL2", "eL3", "eLocalMem", "eRemoteMem", 12 | "ePrefetchBuffer", "ePeerL1Cache", "eL2Prefetcher", "eL1I", "eCore", "ePeerL2", 13 | "eDirectory" }; 14 | return name[aType]; 15 | } 16 | 17 | std::ostream& 18 | operator<<(std::ostream& anOstream, tFillLevel aType) 19 | { 20 | anOstream << fillLevelName(aType); 21 | return anOstream; 22 | } 23 | 24 | } // namespace SharedTypes 25 | } // namespace Flexus 26 | -------------------------------------------------------------------------------- /core/target.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_TARGET_HPP_INCLUDED 2 | #define FLEXUS_CORE_TARGET_HPP_INCLUDED 3 | 4 | #define CAT(x, y) CAT_D(x, y) 5 | #define CAT_D(x, y) x##y 6 | 7 | #ifdef TARGET_PLATFORM 8 | 9 | #define TARGET_PLATFORM_aarch64 0 10 | #define TARGET_PLATFORM_riscv 1 11 | #define DETECTED_TARGET_PLATFORM CAT(TARGET_PLATFORM_, TARGET_PLATFORM) 12 | 13 | #if DETECTED_TARGET_PLATFORM == TARGET_PLATFORM_aarch64 14 | #include 15 | #elif DETECTED_TARGET_PLATFORM == TARGET_PLATFORM_riscv 16 | #include 17 | #else 18 | #error "No correct platform specified" 19 | #endif 20 | 21 | #else 22 | #error "TARGET_PLATFORM was not passed in from the make command line" 23 | #endif 24 | 25 | #undef CAT 26 | #undef CAT_D 27 | 28 | #endif // FLEXUS_CORE_TARGET_HPP_INCLUDED 29 | -------------------------------------------------------------------------------- /core/qemu/bitUtilities.cpp: -------------------------------------------------------------------------------- 1 | #include "bitUtilities.hpp" 2 | 3 | typedef unsigned long long address_t; 4 | 5 | address_t 6 | extractBitsWithBounds(address_t input, unsigned upperBitBound, unsigned lowerBitBound) 7 | { 8 | address_t result = input >> lowerBitBound; 9 | address_t upperMask = (1ULL << (upperBitBound - lowerBitBound + 1)) - 1; 10 | return result & upperMask; 11 | } 12 | 13 | address_t 14 | extractBitsWithRange(address_t input, unsigned lbound, unsigned numBits) 15 | { 16 | address_t result = input >> lbound; 17 | address_t upperMask = (1ULL << numBits) - 1; 18 | return result & upperMask; 19 | } 20 | 21 | bool 22 | extractSingleBitAsBool(address_t input, unsigned bitshift) 23 | { 24 | address_t rawbit = ((input >> bitshift) & 0x1); 25 | return rawbit ? true : false; 26 | } 27 | -------------------------------------------------------------------------------- /core/qemu/attribute_value.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_QEMU_ATTRIBUTE_VALUE_HPP_INCLUDED 2 | #define FLEXUS_QEMU_ATTRIBUTE_VALUE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace mpl = boost::mpl; 9 | 10 | #include 11 | #include 12 | 13 | namespace Flexus { 14 | namespace Qemu { 15 | 16 | namespace aux_ { 17 | // Forward declare AttributeFriend for the friend declaration in AttributeValue 18 | class AttributeFriend; 19 | struct Object 20 | {}; 21 | struct BuiltIn 22 | {}; 23 | struct construct_tag 24 | {}; 25 | } // namespace aux_ 26 | 27 | struct Nil 28 | {}; 29 | 30 | } // namespace Qemu 31 | } // namespace Flexus 32 | 33 | #endif // FLEXUS_SIMICS_ATTRIBUTE_VALUE_HPP_INCLUDED 34 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Mozilla 3 | AlignConsecutiveMacros: 'true' 4 | AlignConsecutiveAssignments: 'true' 5 | AlignEscapedNewlines: Right 6 | AlignTrailingComments: 'true' 7 | AllowAllArgumentsOnNextLine: 'false' 8 | AllowAllParametersOfDeclarationOnNextLine: 'false' 9 | AllowShortBlocksOnASingleLine: 'true' 10 | AllowShortCaseLabelsOnASingleLine: 'true' 11 | AllowShortFunctionsOnASingleLine: Inline 12 | AllowShortIfStatementsOnASingleLine: WithoutElse 13 | AllowShortLambdasOnASingleLine: Inline 14 | AlwaysBreakTemplateDeclarations: 'Yes' 15 | BinPackArguments: 'false' 16 | BinPackParameters: 'false' 17 | ColumnLimit: '120' 18 | IncludeBlocks: Regroup 19 | IndentWidth: '4' 20 | Language: Cpp 21 | PointerAlignment: Left 22 | SortIncludes: 'true' 23 | SortUsingDeclarations: 'true' 24 | Standard: Cpp11 25 | TabWidth: '4' 26 | 27 | ... 28 | -------------------------------------------------------------------------------- /core/aux_/layout/begin_comp_instantiation_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifdef FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 2 | #error "Wiring.cpp may contain only one component instantiation section" 3 | #endif // FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 4 | 5 | #ifdef FLEXUS__LAYOUT_IN_SECTION 6 | #error "Previous wiring.cpp section is missing the end of section #include" 7 | #endif // FLEXUS__LAYOUT_IN_SECTION 8 | 9 | #define FLEXUS__LAYOUT_IN_SECTION 10 | #define FLEXUS__LAYOUT_COMPONENT_INSTATIATION_SECTION 11 | 12 | #ifdef FLEXUS__CORE_TEST 13 | namespace FLEXUS__CORE_TEST { 14 | #else // FLEXUS__CORE_TEST 15 | namespace Flexus { 16 | #endif // FLEXUS__CORE_TEST 17 | namespace Wiring { 18 | 19 | using Flexus::Core::ComponentHandle; 20 | using Flexus::Core::ComponentInstance; 21 | 22 | #define SCALE_WITH_SYSTEM_WIDTH true 23 | #define FIXED false 24 | -------------------------------------------------------------------------------- /components/Decoder/encodings/Unallocated.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_armDECODER_armUNALLOCATED_HPP_INCLUDED 3 | #define FLEXUS_armDECODER_armUNALLOCATED_HPP_INCLUDED 4 | 5 | #include "SharedFunctions.hpp" 6 | 7 | namespace nDecoder { 8 | 9 | archinst 10 | blackBox(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 11 | archinst 12 | grayBox(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo, eInstructionCode aCode); 13 | archinst 14 | nop(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 15 | 16 | archinst 17 | unallocated_encoding(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 18 | archinst 19 | unsupported_encoding(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 20 | 21 | } // namespace nDecoder 22 | 23 | #endif // FLEXUS_armDECODER_armUNALLOCATED_HPP_INCLUDED -------------------------------------------------------------------------------- /components/MemoryMap/MemoryMap.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT MemoryMap 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | COMPONENT_PARAMETERS( 9 | PARAMETER( PageSize, uint32_t, "Page size in bytes (used by statistics only)", "pagesize", 8192 ) 10 | PARAMETER( NumNodes, unsigned, "Number of Nodes", "nodes", 16) 11 | PARAMETER( RoundRobin, bool, "Use static round-robin page allocation", "round_robin", false) 12 | PARAMETER( CreatePageMap, bool, "Write page map as pages are created", "write_page_map", false) 13 | PARAMETER( ReadPageMap, bool, "Load Page Map on start", "page_map", false) 14 | ); 15 | 16 | COMPONENT_EMPTY_INTERFACE ; 17 | 18 | #include FLEXUS_END_COMPONENT_DECLARATION() 19 | #define FLEXUS_END_COMPONENT MemoryMap 20 | // clang-format on 21 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PredictorMessage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Flexus { 6 | namespace SharedTypes { 7 | 8 | std::ostream& 9 | operator<<(std::ostream& anOstream, PredictorMessage::tPredictorMessageType aType) 10 | { 11 | const char* const name[4] = { "eFlush", "eWrite", "eReadPredicted", "eReadNonPredicted" }; 12 | anOstream << name[aType]; 13 | return anOstream; 14 | } 15 | 16 | std::ostream& 17 | operator<<(std::ostream& aStream, PredictorMessage const& anEntry) 18 | { 19 | aStream << "PredictorMessage: type=" << anEntry.type() << " addr=" << &std::hex << anEntry.address() << &std::dec 20 | << " node=" << anEntry.node(); 21 | 22 | return aStream; 23 | } 24 | 25 | } // namespace SharedTypes 26 | } // namespace Flexus 27 | -------------------------------------------------------------------------------- /components/uArch/MapTable.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Implementation file for map table class 3 | * Author: @msutherl 4 | */ 5 | 6 | #include "MapTable.hpp" 7 | 8 | namespace nuArch { 9 | 10 | std::ostream& 11 | operator<<(std::ostream& anOstream, PhysicalMap& aMap) 12 | { 13 | anOstream << "\n\tMappings\n\t"; 14 | for (uint32_t i = 0; i < aMap.theMappings.size(); ++i) { 15 | anOstream << "r" << i << ": p" << aMap.theMappings[i] << "\t"; 16 | if ((i & 7) == 7) anOstream << "\n\t"; 17 | } 18 | anOstream << "\n\tFree List\n\t"; 19 | // for(const auto& aFree: theFreeList) 20 | // anOstream << 'p' << aFree << ' '; 21 | std::for_each(aMap.theFreeList.begin(), aMap.theFreeList.end(), ll::var(anOstream) << 'p' << ll::_1 << ' '); 22 | anOstream << std::endl; 23 | return anOstream; 24 | } 25 | 26 | } /* end namespace nuArch */ 27 | -------------------------------------------------------------------------------- /components/CMPCache/CacheState.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | namespace nCMPCache { 6 | 7 | const CacheState CacheState::Modified("Modified"); 8 | const CacheState CacheState::Owned("Owned"); 9 | const CacheState CacheState::Exclusive("Exclusive"); 10 | const CacheState CacheState::Shared("Shared"); 11 | const CacheState CacheState::Invalid("Invalid"); 12 | const CacheState CacheState::InvalidPresent("InvalidPresent"); 13 | const CacheState CacheState::Forward("Forward"); 14 | 15 | std::ostream& 16 | operator<<(std::ostream& os, const CacheState& state) 17 | { 18 | os << state.name(); 19 | if (state.isProtected()) { os << "_X"; } 20 | if (state.prefetched()) { os << "_P"; } 21 | if (state.isLocked()) { os << "_LOCKED"; } 22 | return os; 23 | } 24 | 25 | }; // namespace nCMPCache 26 | -------------------------------------------------------------------------------- /components/CommonQEMU/Util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __COMMON_UTIL_HPP__ 2 | #define __COMMON_UTIL_HPP__ 3 | 4 | #include 5 | #include 6 | 7 | namespace nCommonUtil { 8 | 9 | template 10 | int32_t 11 | log_base2(_Type val) 12 | { 13 | int32_t ret = 0; 14 | for (val >>= 1; val > 0; val >>= 1, ret++) 15 | ; 16 | return ret; 17 | } 18 | 19 | class AddressHash 20 | { 21 | public: 22 | std::size_t operator()(Flexus::SharedTypes::PhysicalMemoryAddress addr) const 23 | { 24 | boost::hash my_hash; 25 | return my_hash((int)(addr >> 6)); 26 | } 27 | }; 28 | 29 | // Find the closest prime number that is less than or equal to 'num' 30 | // Works for numbers up to 7919 31 | int32_t 32 | get_closest_prime(int32_t num); 33 | }; // namespace nCommonUtil 34 | 35 | #endif // ! __COMMON_UTIL_HPP__ 36 | -------------------------------------------------------------------------------- /components/NetShim/NetShim.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT NetShim 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | #include 9 | 10 | COMPONENT_PARAMETERS( 11 | FLEXUS_PARAMETER( NetworkTopologyFile, std::string, "Network topology file", "topology-file", "" ) 12 | FLEXUS_PARAMETER( NumNodes, int, "Number of Nodes", "nodes", 2) 13 | FLEXUS_PARAMETER( VChannels, int, "Number of virtual channels", "virtual-channels", 3) 14 | ); 15 | 16 | COMPONENT_INTERFACE( 17 | DYNAMIC_PORT_ARRAY( PushOutput, NetworkTransport, ToNode ) 18 | DYNAMIC_PORT_ARRAY( PushInput, NetworkTransport, FromNode ) 19 | DRIVE( NetworkDrive ) 20 | ); 21 | 22 | #include FLEXUS_END_COMPONENT_DECLARATION() 23 | #define FLEXUS_END_COMPONENT NetShim 24 | // clang-format on 25 | -------------------------------------------------------------------------------- /components/NetShim/MemoryNetwork.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT MemoryNetwork 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | #include 9 | 10 | COMPONENT_PARAMETERS( 11 | FLEXUS_PARAMETER( NetworkTopologyFile, std::string, "Network topology file", "topology-file", "" ) 12 | FLEXUS_PARAMETER( NumNodes, int, "Number of Nodes", "nodes", 2) 13 | FLEXUS_PARAMETER( VChannels, int, "Number of virtual channels", "virtual-channels", 3) 14 | ); 15 | 16 | COMPONENT_INTERFACE( 17 | DYNAMIC_PORT_ARRAY( PushOutput, MemoryTransport, ToNode ) 18 | DYNAMIC_PORT_ARRAY( PushInput, MemoryTransport, FromNode ) 19 | DRIVE( NetworkDrive ) 20 | ); 21 | 22 | #include FLEXUS_END_COMPONENT_DECLARATION() 23 | #define FLEXUS_END_COMPONENT MemoryNetwork 24 | // clang-format on 25 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/RegisterValueExtractor.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../SemanticActions.hpp" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace nDecoder { 9 | 10 | using namespace nuArch; 11 | 12 | struct register_value_extractor : boost::static_visitor 13 | { 14 | register_value operator()(uint64_t v) const { return v; } 15 | 16 | register_value operator()(bits v) const { return v; } 17 | 18 | register_value operator()(int64_t v) const { return v; } 19 | 20 | template 21 | register_value operator()(T aT) const 22 | { 23 | DBG_Assert(false, 24 | (<< "Attempting to store a non-register value operand " 25 | "into a register")); 26 | return uint64_t(0ULL); 27 | } 28 | }; 29 | 30 | } // namespace nDecoder 31 | -------------------------------------------------------------------------------- /components/MemoryLoopback/MemoryLoopback.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT MemoryLoopback 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | #include 9 | 10 | COMPONENT_PARAMETERS( 11 | PARAMETER( Delay, int, "Access time", "time", 1 ) 12 | PARAMETER( MaxRequests, int, "Maximum requests queued in loopback", "max_requests", 64 ) 13 | PARAMETER( UseFetchReply, bool, "Send FetchReply in response to FetchReq (instead of MissReply)", "UseFetchReply", false ) 14 | ); 15 | 16 | COMPONENT_INTERFACE( 17 | PORT( PushOutput, MemoryTransport, LoopbackOut ) 18 | PORT( PushInput, MemoryTransport, LoopbackIn ) 19 | DRIVE( LoopbackDrive ) 20 | ); 21 | 22 | #include FLEXUS_END_COMPONENT_DECLARATION() 23 | #define FLEXUS_END_COMPONENT MemoryLoopback 24 | // clang-format on 25 | -------------------------------------------------------------------------------- /core/qemu/mai_api.cpp: -------------------------------------------------------------------------------- 1 | // ALEX: THIS FILE IS CURRENTLY A DUMMY. 2 | // Copied this file from SimFlex. Will gradually populate it properly. 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace Flexus::Core; 25 | 26 | namespace Flexus { 27 | namespace Qemu { 28 | 29 | } // end Namespace Qemu 30 | } // end namespace Flexus 31 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/MRCMessage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Flexus { 7 | namespace SharedTypes { 8 | 9 | std::ostream& 10 | operator<<(std::ostream& s, MRCMessage const& aMsg) 11 | { 12 | char const* types[] = { "Append", "RequestStream" }; 13 | if (aMsg.tag() == -1) { 14 | s << "MRC " << types[aMsg.type()] << "#*"; 15 | } else { 16 | s << "MRC " << types[aMsg.type()] << "#" << aMsg.tag() / 32 << "[" << (aMsg.tag() & 15) << "]" 17 | << ((aMsg.tag() & 16) ? "b" : "a"); 18 | } 19 | s << " @" << aMsg.address() << "<" << aMsg.location() << ">"; 20 | s << " by [" << boost::padded_string_cast<2, '0'>(aMsg.node()) << "]"; 21 | return s; 22 | } 23 | 24 | } // namespace SharedTypes 25 | } // namespace Flexus 26 | -------------------------------------------------------------------------------- /components/TLBControllers/TLBController.hpp: -------------------------------------------------------------------------------- 1 | // 2 | 3 | /* Basic goals: 4 | * - sub-class the CacheController with TLB specific functionality 5 | * - adds a large interface to the MMU component in core/qemu 6 | * - improve readability and usability 7 | */ 8 | 9 | #ifndef FLEXUS_TLB_CONTROLLER_HPP_INCLUDED 10 | #define FLEXUS_TLB_CONTROLLER_HPP_INCLUDED 11 | 12 | #include 13 | 14 | #define DBG_DeclareCategories TLBCtrl 15 | #define DBG_SetDefaultOps AddCat(TLBCtrl) 16 | #include DBG_Control() 17 | 18 | namespace nTLB { 19 | 20 | using namespace nMessageQueues; 21 | using namespace nCache; 22 | typedef Flexus::SharedTypes::MemoryTransport Transport; 23 | typedef Flexus::SharedTypes::PhysicalMemoryAddress MemoryAddress; 24 | 25 | } // end namespace nTLB 26 | 27 | #define DBG_Reset 28 | #include DBG_Control() 29 | 30 | #endif // FLEXUS_TLB_CONTROLLER_HPP_INCLUDED 31 | -------------------------------------------------------------------------------- /components/Decoder/Conditions.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_ARMDECODER_CONDITIONS_HPP_INCLUDED 3 | #define FLEXUS_ARMDECODER_CONDITIONS_HPP_INCLUDED 4 | 5 | #include "OperandMap.hpp" 6 | #include "SemanticInstruction.hpp" 7 | 8 | namespace nDecoder { 9 | using namespace nuArch; 10 | 11 | enum eCondCode 12 | { 13 | kCBZ_, 14 | kCBNZ_, 15 | kTBZ_, 16 | kTBNZ_, 17 | kBCOND_, 18 | }; 19 | 20 | struct Condition 21 | { 22 | virtual ~Condition() {} 23 | virtual bool operator()(std::vector const& operands) = 0; 24 | virtual char const* describe() const = 0; 25 | void setInstruction(SemanticInstruction* anInstruction) { theInstruction = anInstruction; } 26 | 27 | protected: 28 | SemanticInstruction* theInstruction; 29 | }; 30 | 31 | std::unique_ptr 32 | condition(eCondCode aCond); 33 | 34 | } // namespace narmDecoder 35 | 36 | #endif // FLEXUS_ARMDECODER_CONDITIONS_HPP_INCLUDED -------------------------------------------------------------------------------- /core/debug/aux_/dev_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Dev)) 2 | // Dev debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Dev)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Dev) 5 | #endif 6 | 7 | #define DBG__internal_Dev(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Dev debugging disabled 11 | 12 | #define DBG__internal_Dev(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/inv_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Inv)) 2 | // Inv debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Inv)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Inv) 5 | #endif 6 | 7 | #define DBG__internal_Inv(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Inv debugging disabled 11 | 12 | #define DBG__internal_Inv(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/tmp_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Tmp)) 2 | // Tmp debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Tmp)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Tmp) 5 | #endif 6 | 7 | #define DBG__internal_Tmp(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Tmp debugging disabled 11 | 12 | #define DBG__internal_Tmp(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /components/PhantomCPU/PhantomCPU.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_PhantomCPU_HPP 2 | #define FLEXUS_PhantomCPU_HPP 3 | 4 | #include 5 | #include 6 | #include /* CMU-ONLY */ 7 | #include 8 | #include 9 | #include 10 | 11 | // clang-format off 12 | 13 | #define FLEXUS_BEGIN_COMPONENT PhantomCPU 14 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 15 | 16 | COMPONENT_PARAMETERS( 17 | PARAMETER( IndexOffSet, uint32_t, "Index Offset", "index_offset", 0) 18 | PARAMETER( EstimatedIPC, uint32_t, "Estimated IPC", "estimated_ipc", 5) 19 | ); 20 | 21 | COMPONENT_INTERFACE( 22 | DRIVE(PhantomDrive) 23 | ); 24 | 25 | #include FLEXUS_END_COMPONENT_DECLARATION() 26 | #define FLEXUS_END_COMPONENT PhantomCPU 27 | 28 | // clang-format on 29 | #endif -------------------------------------------------------------------------------- /core/debug/aux_/crit_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Crit)) 2 | // Crit debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Crit)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Crit) 5 | #endif 6 | 7 | #define DBG__internal_Crit(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Crit debugging disabled 11 | 12 | #define DBG__internal_Crit(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/verb_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Verb)) 2 | // Verb debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Verb)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Verb) 5 | #endif 6 | 7 | #define DBG__internal_Verb(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Verb debugging disabled 11 | 12 | #define DBG__internal_Verb(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/iface_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Iface)) 2 | // Iface debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Iface)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Iface) 5 | #endif 6 | 7 | #define DBG__internal_Iface(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Iface debugging disabled 11 | 12 | #define DBG__internal_Iface(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging message is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/trace_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(Trace)) 2 | // Trace debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(Trace)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(Trace) 5 | #endif 6 | 7 | #define DBG__internal_Trace(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Trace debugging disabled 11 | 12 | #define DBG__internal_Trace(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/vverb_macros.hpp: -------------------------------------------------------------------------------- 1 | #if BOOST_PP_LESS_EQUAL(DBG__internal_tmp_MinimumSeverity, DBG_internal_Sev_to_int(VVerb)) 2 | // Vverb debugging enabled 3 | #if (DBG__internal_tmp_MinimumSeverity == DBG_internal_Sev_to_int(VVerb)) 4 | #define DBG__internal_MinimumSeverity DBG_internal_Sev_to_int(VVerb) 5 | #endif 6 | 7 | #define DBG__internal_VVerb(Sev, operations) DBG__internal_PROCESS_DBG(Sev, operations) /**/ 8 | 9 | #else 10 | // Vverb debugging disabled 11 | 12 | #define DBG__internal_VVerb(Sev, operations) \ 13 | do { \ 14 | /* Prevent unused variable warnings if debugging operation is below threshold */ \ 15 | if (false) { DBG__internal_PROCESS_DBG(Sev, operations); } \ 16 | } while (0) 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /core/debug/aux_/new_categories.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_AUX__NEW_CATEGORIES_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_AUX__NEW_CATEGORIES_HPP_INCLUDED 3 | // These macros are only defined the first time this file is included 4 | 5 | #define DBG__internal_PROCESS_NEW_CATEGORIES(...) BOOST_PP_VA_FOR_EACH(DBG__internal_NEW_CATEGORY, __VA_ARGS__) /**/ 6 | 7 | #define DBG__internal_NEW_CATEGORY(cat) \ 8 | namespace DBG_Cats { \ 9 | bool BOOST_PP_CAT(cat, _debug_enabled) = true; \ 10 | Flexus::Dbg::Category cat(#cat, &BOOST_PP_CAT(cat, _debug_enabled)); \ 11 | } /**/ 12 | 13 | #endif // FLEXUS_CORE_DEBUG_AUX__NEW_CATEGORIES_HPP_INCLUDED 14 | 15 | DBG__internal_PROCESS_NEW_CATEGORIES(DBG_DefineCategories) 16 | -------------------------------------------------------------------------------- /core/debug/target.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_TARGET_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_TARGET_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Flexus { 11 | namespace Dbg { 12 | 13 | class Target 14 | { 15 | std::string theName; 16 | std::unique_ptr theFilter; 17 | std::unique_ptr theAction; 18 | 19 | public: 20 | Target(std::string const& aName, Filter* aFilter, Action* anAction); 21 | void process(Entry const& anEntry); 22 | Filter& filter(); 23 | void setFilter(std::unique_ptr aFilter); 24 | Action& action(); 25 | void setAction(std::unique_ptr anAction); 26 | void printConfiguration(std::ostream& anOstream, std::string const& anIndent = std::string("")); 27 | }; 28 | 29 | } // namespace Dbg 30 | } // namespace Flexus 31 | 32 | #endif // FLEXUS_CORE_DEBUG_TARGET_HPP_INCLUDED 33 | -------------------------------------------------------------------------------- /core/qemu/aux_/qemu_command_manager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_QEMU_AUX__COMMAND_MANAGER_HPP_INCLUDED 2 | #define FLEXUS_QEMU_AUX__COMMAND_MANAGER_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace Flexus { 10 | namespace Qemu { 11 | 12 | struct BaseClassImpl; 13 | 14 | namespace aux_ { 15 | 16 | // Helper functions 17 | API::conf_class_t* 18 | RegisterClass_stub(std::string const& name); 19 | 20 | class QemuCommandManager 21 | { 22 | public: 23 | API::conf_object_t* theGateway; // Qemu class data structure for gateway 24 | 25 | //"Closure" variables used to pass parameters through the gateway 26 | API::conf_object_t* theObject; 27 | 28 | static QemuCommandManager* get(); 29 | 30 | QemuCommandManager(); 31 | }; 32 | 33 | } // namespace aux_ 34 | } // namespace Qemu 35 | } // namespace Flexus 36 | 37 | #endif // FLEXUS_QEMU_AUX__COMMAND_MANAGER_HPP_INCLUDED 38 | -------------------------------------------------------------------------------- /core/aux_/layout/begin_drive_section.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__CORE_TEST 2 | 3 | #ifdef FLEXUS__LAYOUT_DRIVES_ORDERED 4 | #error "Wiring.cpp may contain only one drive order section" 5 | #endif // FLEXUS__LAYOUT_DRIVES_ORDERED 6 | 7 | #ifndef FLEXUS__LAYOUT_COMPONENTS_WIRED 8 | #error "The drive order section of wiring.cpp must follow the component wiring section" 9 | #endif // FLEXUS__LAYOUT_COMPONENTS_WIRED 10 | 11 | #ifdef FLEXUS__LAYOUT_IN_SECTION 12 | #error "Previous wiring.cpp section is missing the end of section #include" 13 | #endif // FLEXUS__LAYOUT_IN_SECTION 14 | 15 | #define FLEXUS__LAYOUT_IN_SECTION 16 | #define FLEXUS__LAYOUT_DRIVE_SECTION 17 | 18 | #endif // FLEXUS__CORE_TEST 19 | 20 | #include 21 | 22 | #ifdef FLEXUS__CORE_TEST 23 | namespace FLEXUS__CORE_TEST { 24 | #else // FLEXUS__CORE_TEST 25 | namespace Flexus { 26 | #endif // FLEXUS__CORE_TEST 27 | namespace Wiring { 28 | 29 | #define DRIVE(Handle, Drive) Flexus::Core::DriveHandle 30 | 31 | typedef mpl::vector < 32 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/ArchitecturalInstruction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | std::ostream& 7 | operator<<(std::ostream& anOstream, const ArchitecturalInstruction& aMemOp) 8 | { 9 | // anOstream << "SimicsMemoryOp: " << aMemOp.opName() << " [PC=" << &std::hex 10 | // << aMemOp.physicalInstructionAddress() << "] "; 11 | if (aMemOp.isMemory()) { anOstream << "addr=" << aMemOp.physicalMemoryAddress(); } 12 | return anOstream; 13 | } 14 | 15 | bool 16 | operator==(const ArchitecturalInstruction& a, const ArchitecturalInstruction& b) 17 | { 18 | if (a.physicalInstructionAddress() != b.physicalInstructionAddress()) { return false; } 19 | if (a.opName() != b.opName()) { return false; } 20 | if (a.isMemory()) { 21 | if (a.physicalMemoryAddress() != b.physicalMemoryAddress()) { return false; } 22 | } 23 | return true; 24 | } 25 | 26 | } // namespace SharedTypes 27 | } // namespace Flexus 28 | -------------------------------------------------------------------------------- /components/BranchPredictor/RAS.cpp: -------------------------------------------------------------------------------- 1 | #include "RAS.hpp" 2 | 3 | #include "components/uFetch/uFetchTypes.hpp" 4 | 5 | void ReturnAddressStack::push(uint64_t target) { 6 | stack.push_back(target); 7 | 8 | if (stack.size() > size) 9 | stack.erase(stack.begin()); 10 | } 11 | 12 | uint64_t ReturnAddressStack::pop() { 13 | auto top = stack.back(); 14 | 15 | if (stack.size()) 16 | stack.pop_back(); 17 | 18 | return top; 19 | } 20 | 21 | void ReturnAddressStack::get(std::vector &vec) { 22 | vec = stack; 23 | } 24 | 25 | void ReturnAddressStack::recover(BPredState &bpred) { 26 | if (bpred.theRAS.empty()) { 27 | return; 28 | } 29 | 30 | // first revert back to the old state before the speculative push/pop 31 | stack = bpred.theRAS; 32 | 33 | // then adjust according to the actual branch type 34 | if (bpred.theActualType == kCall || 35 | bpred.theActualType == kIndirectCall) 36 | push(bpred.pc + 4); 37 | 38 | if (bpred.theActualType == kReturn) 39 | pop(); 40 | } -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/AbstractInstruction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | std::ostream& 7 | operator<<(std::ostream& anOstream, eSquashCause aCause) 8 | { 9 | const char* causes[] = { "Invalid", "Resynchronize", "BranchMispredict", 10 | "Exception", "Interrupt", "FailedSpeculation" }; 11 | if (aCause > 5) { 12 | anOstream << "Invalid Squash Cause(" << static_cast(aCause) << ")"; 13 | } else { 14 | anOstream << causes[aCause]; 15 | } 16 | return anOstream; 17 | } 18 | 19 | std::ostream& 20 | operator<<(std::ostream& anOstream, AbstractInstruction const& anInstruction) 21 | { 22 | anInstruction.describe(anOstream); 23 | return anOstream; 24 | } 25 | 26 | void 27 | AbstractInstruction::describe(std::ostream& anOstream) const 28 | { 29 | } 30 | bool 31 | AbstractInstruction::haltDispatch() const 32 | { 33 | return false; 34 | } 35 | 36 | } // namespace SharedTypes 37 | } // namespace Flexus 38 | -------------------------------------------------------------------------------- /core/qemu/api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Flexus { 5 | namespace Qemu { 6 | namespace API { 7 | 8 | #include "api.h" 9 | 10 | QEMU_API_t qemu_api; 11 | 12 | void 13 | FLEXUS_get_api(FLEXUS_API_t* api) 14 | { 15 | api->start = FLEXUS_start; 16 | api->stop = FLEXUS_stop; 17 | api->qmp = FLEXUS_qmp; 18 | api->trace_mem = FLEXUS_trace_mem; 19 | } 20 | 21 | using namespace Flexus::Core; 22 | 23 | void 24 | FLEXUS_start(uint64_t cycle) 25 | { 26 | theFlexus->setCycle(cycle); 27 | 28 | while (true) 29 | theFlexus->doCycle(); 30 | } 31 | 32 | void 33 | FLEXUS_stop() 34 | { 35 | theFlexus->terminateSimulation(); 36 | } 37 | 38 | void 39 | FLEXUS_qmp(qmp_flexus_cmd_t aCMD, const char* anArgs) 40 | { 41 | // qmp_api.hpp is bad 42 | flexus_qmp(aCMD, anArgs); 43 | } 44 | 45 | void __attribute__((weak)) 46 | FLEXUS_trace_mem(uint64_t idx, memory_transaction_t* tr) 47 | { 48 | // not exposed in timing 49 | } 50 | 51 | } // namespace API 52 | } // namespace Qemu 53 | } // namespace Flexus -------------------------------------------------------------------------------- /core/aux_/layout/begin_comp_configuration_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifdef FLEXUS__LAYOUT_COMPONENTS_CONFIGURED 2 | #error "Wiring.cpp may contain only one component configuration section" 3 | #endif // FLEXUS__LAYOUT_COMPONENTS_CONFIGURED 4 | 5 | #ifdef FLEXUS__LAYOUT_IN_SECTION 6 | #error "Previous wiring.cpp section is missing the end of section #include" 7 | #endif // FLEXUS__LAYOUT_IN_SECTION 8 | 9 | #define FLEXUS__LAYOUT_IN_SECTION 10 | #define FLEXUS__LAYOUT_COMPONENT_CONFIGURATION_SECTION 11 | 12 | #include 13 | 14 | #ifdef FLEXUS__CORE_TEST 15 | namespace FLEXUS__CORE_TEST { 16 | #else // FLEXUS__CORE_TEST 17 | namespace Flexus { 18 | #endif // FLEXUS__CORE_TEST 19 | namespace Wiring { 20 | 21 | // Bring in the tools we need from the Configuration component 22 | using namespace Flexus::Core; 23 | 24 | #define CREATE_CONFIGURATION(Component, String, Name) BOOST_PP_CAT(Component, Configuration) Name(String); 25 | 26 | Flexus::Core::index_t 27 | getSystemWidth() 28 | { 29 | return ComponentManager::getComponentManager().systemWidth(); 30 | } 31 | 32 | using Flexus::Core::theFlexus; 33 | -------------------------------------------------------------------------------- /core/debug/aux_/declare_new_categories.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_AUX__DECLARE_CATEGORIES_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_AUX__DECLARE_CATEGORIES_HPP_INCLUDED 3 | // These macros are only defined the first time this file is included 4 | 5 | #define DBG__internal_PROCESS_DECLARE_CATEGORIES(...) \ 6 | BOOST_PP_VA_FOR_EACH(DBG__internal_DECLARE_CATEGORY, __VA_ARGS__) /**/ 7 | 8 | #define DBG__internal_DECLARE_CATEGORY(cat) \ 9 | namespace DBG_Cats { \ 10 | extern bool BOOST_PP_CAT(cat, _debug_enabled); \ 11 | extern Flexus::Dbg::Category cat; \ 12 | } /**/ 13 | 14 | #endif // FLEXUS_CORE_DEBUG_AUX__DECLARE_CATEGORIES_HPP_INCLUDED 15 | 16 | DBG__internal_PROCESS_DECLARE_CATEGORIES(DBG_DeclareCategories) 17 | -------------------------------------------------------------------------------- /core/qemu/aux_/qemu_command_manager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | namespace Flexus { 8 | namespace Qemu { 9 | namespace aux_ { 10 | 11 | API::conf_object_t* 12 | QemuCommandManager_constructor() 13 | { 14 | DBG_(Verb, (<< "QemuCommandManager constructor.")); 15 | API::conf_object* object = new API::conf_object; 16 | return object; 17 | } 18 | 19 | int 20 | QemuCommandManager_destructor(API::conf_object_t* anInstance) 21 | { 22 | delete anInstance; 23 | return 0; 24 | } 25 | 26 | QemuCommandManager* 27 | QemuCommandManager::get() 28 | { 29 | static QemuCommandManager theManager; 30 | return &theManager; 31 | } 32 | 33 | QemuCommandManager::QemuCommandManager() 34 | { 35 | // Set up all the "closure" variables used for passing parameters 36 | // through the gateway (just one!) 37 | theObject = 0; 38 | } 39 | 40 | } // namespace aux_ 41 | } // namespace Qemu 42 | } // namespace Flexus 43 | -------------------------------------------------------------------------------- /target/knottykraken/2x3-mesh.topology: -------------------------------------------------------------------------------- 1 | # Boilerplate stuff 2 | ChannelLatency 1 3 | ChannelLatencyData 4 4 | ChannelLatencyControl 1 5 | LocalChannelLatencyDivider 4 6 | SwitchInputBuffers 1 7 | SwitchOutputBuffers 1 8 | SwitchInternalBuffersPerVC 1 9 | 10 | # Basic Switch/Node connections 11 | NumNodes 6 12 | NumSwitches 2 13 | SwitchPorts 7 14 | SwitchBandwidth 4 15 | 16 | Top Node 0 -> Switch 0:0 17 | Top Node 1 -> Switch 1:0 18 | Top Node 2 -> Switch 0:1 19 | Top Node 3 -> Switch 1:1 20 | Top Node 4 -> Switch 0:2 21 | Top Node 5 -> Switch 1:2 22 | 23 | # Topology for a 6 node MESH with 3 nodes per router 24 | Top Switch 0:5 -> Switch 1:3 25 | 26 | # Deadlock-free routing tables 27 | 28 | # Switch 0 -> * 29 | Route Switch 0 -> 0 { 0:0 } 30 | Route Switch 0 -> 1 { 5:0 } 31 | Route Switch 0 -> 2 { 1:0 } 32 | Route Switch 0 -> 3 { 5:0 } 33 | Route Switch 0 -> 4 { 2:0 } 34 | Route Switch 0 -> 5 { 5:0 } 35 | 36 | # Switch 1 -> * 37 | Route Switch 1 -> 0 { 3:0 } 38 | Route Switch 1 -> 1 { 0:0 } 39 | Route Switch 1 -> 2 { 3:0 } 40 | Route Switch 1 -> 3 { 1:0 } 41 | Route Switch 1 -> 4 { 3:0 } 42 | Route Switch 1 -> 5 { 2:0 } 43 | -------------------------------------------------------------------------------- /components/Decoder/Interactions.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_armDECODER_INTERACTIONS_HPP_INCLUDED 3 | #define FLEXUS_armDECODER_INTERACTIONS_HPP_INCLUDED 4 | 5 | #include "components/uArch/uArchInterfaces.hpp" 6 | #include "core/types.hpp" 7 | 8 | namespace nDecoder { 9 | 10 | using Flexus::SharedTypes::VirtualMemoryAddress; 11 | 12 | struct BranchInteraction : public nuArch::Interaction 13 | { 14 | boost::intrusive_ptr theIssuer; 15 | 16 | BranchInteraction(boost::intrusive_ptr anIssuer); 17 | void operator()(boost::intrusive_ptr anInstruction, nuArch::uArch& aCore); 18 | void describe(std::ostream& anOstream) const; 19 | // boost::optional< uint64_t> npc() { 20 | // return boost::optional(theTarget); 21 | // } 22 | }; 23 | 24 | nuArch::Interaction* 25 | reinstateInstructionInteraction(); 26 | nuArch::Interaction* 27 | annulInstructionInteraction(); 28 | nuArch::Interaction* 29 | branchInteraction(boost::intrusive_ptr anIssuer); 30 | 31 | } // namespace nDecoder 32 | 33 | #endif // FLEXUS_armDECODER_INTERACTIONS_HPP_INCLUDED -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/NetworkMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__NETWORKMESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__NETWORKMESSAGE_HPP_INCLUDED 3 | 4 | #define FLEXUS_NetworkMessage_TYPE_PROVIDED 5 | 6 | #include 7 | 8 | namespace Flexus { 9 | namespace SharedTypes { 10 | 11 | struct NetworkMessage : public boost::counted_base 12 | { 13 | int32_t src; // source node 14 | int32_t dest; // destination node 15 | int32_t vc; // virtual channel 16 | int32_t size; // message (i.e. payload) size 17 | int32_t src_port; 18 | int32_t dst_port; 19 | 20 | NetworkMessage() 21 | : src(-1) 22 | , dest(-1) 23 | , vc(-1) 24 | , size(-1) 25 | , src_port(-1) 26 | , dst_port(-1) 27 | { 28 | } 29 | }; 30 | 31 | inline std::ostream& 32 | operator<<(std::ostream& os, const NetworkMessage& msg) 33 | { 34 | os << "Src: " << msg.src << ", Dest: " << msg.dest << ", VC: " << msg.vc << ", Size: " << msg.size; 35 | return os; 36 | } 37 | 38 | } // namespace SharedTypes 39 | } // namespace Flexus 40 | 41 | #endif // FLEXUS_SLICES__NETWORKMESSAGE_HPP_INCLUDED 42 | -------------------------------------------------------------------------------- /core/debug/aux_/assert_macros.hpp: -------------------------------------------------------------------------------- 1 | #if DBG_SetAssertions 2 | // Assertions enabled 3 | #undef DBG__internal_ASSERTIONS_ENABLED 4 | #define DBG__internal_ASSERTIONS_ENABLED 1 5 | 6 | #undef DBG__internal_Assert 7 | #define DBG__internal_Assert(sev, condition, operations) \ 8 | DBG__internal_PROCESS_DBG(sev, Assert() Condition(!(condition)) operations) /**/ 9 | 10 | #else // DBG_SetAssertions 11 | 12 | // Assertions disabled 13 | 14 | #undef DBG__internal_ASSERTIONS_ENABLED 15 | #define DBG__internal_ASSERTIONS_ENABLED 0 16 | 17 | #undef DBG__internal_Assert 18 | #define DBG__internal_Assert(...) \ 19 | do { \ 20 | /* Prevent unused variable warnings if assertions are disabled */ \ 21 | if (false) { DBG__internal_PROCESS_DBG(sev, Assert() Condition(!(condition)) operations); } \ 22 | } while (0) 23 | 24 | #endif // DBG_SetAssertions 25 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/RegionScoutMessage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Flexus { 6 | namespace SharedTypes { 7 | 8 | std::ostream& 9 | operator<<(std::ostream& s, RegionScoutMessage::RegionScoutMessageType const& aType) 10 | { 11 | char const* message_types[] = { 12 | "Region Probe", "Region State Probe", "Region Miss Reply", "Region Hit Reply", "Region Is Shared", 13 | "Region Not Shared", "Region Global Miss", "Region Partial Miss", "Region Probe Owner", "Region Owner Reply", 14 | "Region Set Owner", "Region Evict", "Block Probe", "BlockScout Probe", "Block Miss Reply", 15 | "Block Hit Reply", "Set Tag Probe", "RVA Set Tag Probe", "Set Tag Reply", "RVA Set Tag Reply" 16 | }; 17 | s << message_types[aType]; 18 | return s; 19 | } 20 | 21 | std::ostream& 22 | operator<<(std::ostream& s, RegionScoutMessage const& aMsg) 23 | { 24 | s << aMsg.type() << " for Region " << std::hex << aMsg.region() << std::dec; 25 | return s; 26 | } 27 | 28 | } // namespace SharedTypes 29 | } // namespace Flexus 30 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PrefetchMessage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Flexus { 7 | namespace SharedTypes { 8 | 9 | std::ostream& 10 | operator<<(std::ostream& s, PrefetchMessage const& aMsg) 11 | { 12 | char const* prefetch_types[] = { "Prefetch Request", "Discard Request", "Watch Request", "Prefetch Complete", 13 | "Prefetch Redundant", "Line Hit", "Line Hit - Partial", "Line Replaced", 14 | "Line Removed", "Watch Present", "Watch Redundant", "Watch Requested", 15 | "Watch Removed", "Watch Replaced" }; 16 | DBG_Assert(aMsg.type() < static_cast(sizeof(prefetch_types) / sizeof(prefetch_types[0]))); 17 | 18 | s << "PrefetchMessage[" << prefetch_types[aMsg.type()] << "]: "; 19 | if (aMsg.streamID() > 0) { s << " Stream[" << aMsg.streamID() << "] "; } 20 | s << " Addr:0x" << std::hex << aMsg.address() << std::dec; 21 | return s; 22 | } 23 | 24 | } // namespace SharedTypes 25 | } // namespace Flexus 26 | -------------------------------------------------------------------------------- /components/Decoder/encodings/DataProcImm.hpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * The instruction disassembly implemented here matches 4 | * the instruction encoding classifications documented in 5 | * the 00bet3.1 release of the A64 ISA XML for ARMv8.2. 6 | * classification names and decode diagrams here should generally 7 | * match up with those in the manual. 8 | */ 9 | 10 | #ifndef FLEXUS_armDECODER_armDATAPROCIMM_HPP_INCLUDED 11 | #define FLEXUS_armDECODER_armDATAPROCIMM_HPP_INCLUDED 12 | 13 | #include "SharedFunctions.hpp" 14 | 15 | namespace nDecoder { 16 | 17 | // TODO 18 | archinst 19 | ADR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 20 | archinst 21 | EXTR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 22 | archinst 23 | BFM(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 24 | archinst 25 | MOVE(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 26 | 27 | archinst 28 | LOGICALIMM(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 29 | archinst 30 | ALUIMM(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 31 | 32 | } // namespace nDecoder 33 | #endif // FLEXUS_armDECODER_armDATAPROCIMM_HPP_INCLUDED -------------------------------------------------------------------------------- /components/CommonQEMU/StandardDeviation.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class StandardDeviation 4 | { 5 | private: 6 | uint64_t k; 7 | double Sum; 8 | double SumSq; 9 | double SigmaSqSum; 10 | 11 | public: 12 | StandardDeviation(void) 13 | { 14 | k = 0UL; 15 | Sum = 0.0; 16 | SumSq = 0.0; 17 | SigmaSqSum = 0.0; 18 | 19 | return; 20 | } 21 | 22 | void Reset(void) 23 | { 24 | k = 0UL; 25 | Sum = 0.0; 26 | SumSq = 0.0; 27 | SigmaSqSum = 0.0; 28 | 29 | return; 30 | } 31 | 32 | void NewSample(const double X) 33 | { 34 | const double Xsq = X * X; 35 | 36 | SigmaSqSum += SumSq + k * Xsq - 2 * X * Sum; 37 | 38 | k++; 39 | Sum += X; 40 | SumSq += Xsq; 41 | 42 | return; 43 | } 44 | 45 | double GetStandardDeviation(void) const 46 | { 47 | if (k == 0) return 0.0; 48 | 49 | DBG_Assert(SigmaSqSum >= 0.0); 50 | return std::sqrt(SigmaSqSum) / (double)k; 51 | } 52 | }; 53 | 54 | inline double 55 | safe_div(const uint64_t a, const uint64_t b) 56 | { 57 | return (b == 0 ? 0.0 : (double)a / b); 58 | } 59 | -------------------------------------------------------------------------------- /components/Decoder/Constraints.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_DECODER_CONSTRAINTS_HPP_INCLUDED 3 | #define FLEXUS_DECODER_CONSTRAINTS_HPP_INCLUDED 4 | 5 | #include 6 | 7 | namespace nDecoder { 8 | 9 | struct SemanticInstruction; 10 | 11 | std::function 12 | membarStoreLoadConstraint(SemanticInstruction* anInstruction); 13 | std::function 14 | membarStoreStoreConstraint(SemanticInstruction* anInstruction); 15 | std::function 16 | membarSyncConstraint(SemanticInstruction* anInstruction); 17 | std::function 18 | loadMemoryConstraint(SemanticInstruction* anInstruction); 19 | std::function 20 | storeQueueAvailableConstraint(SemanticInstruction* anInstruction); 21 | std::function 22 | storeQueueEmptyConstraint(SemanticInstruction* anInstruction); 23 | 24 | std::function 25 | saveWillRaiseCondition(SemanticInstruction* anInstruction); 26 | std::function 27 | restoreWillRaiseCondition(SemanticInstruction* anInstruction); 28 | std::function 29 | sideEffectStoreConstraint(SemanticInstruction* anInstruction); 30 | std::function 31 | paddrResolutionConstraint(SemanticInstruction* anInstruction); 32 | 33 | } // namespace nDecoder 34 | 35 | #endif // FLEXUS_DECODER_CONSTRAINTS_HPP_INCLUDED 36 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PrefetchCommand.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Flexus { 6 | namespace SharedTypes { 7 | 8 | std::ostream& 9 | operator<<(std::ostream& s, PrefetchCommand const& aMsg) 10 | { 11 | char const* prefetch_types[] = { "Prefetch Address List", "Prefetch More Addresses" }; 12 | if (aMsg.tag() == -1) { 13 | s << prefetch_types[aMsg.type()] << "#* "; 14 | } else { 15 | s << prefetch_types[aMsg.type()] << "#" << aMsg.tag() / 32 << "[" << (aMsg.tag() & 15) << "]" 16 | << ((aMsg.tag() & 16) ? "b" : "a") << " "; 17 | } 18 | s << "from " << aMsg.source() << " <" << aMsg.location() << "> "; 19 | if (aMsg.queue() != -1) { s << "queue " << aMsg.queue() << " "; } 20 | s << "{" << &std::hex; 21 | std::list::const_iterator iter = aMsg.addressList().begin(); 22 | std::list::const_iterator end = aMsg.addressList().end(); 23 | while (iter != end) { 24 | s << *iter; 25 | ++iter; 26 | if (iter != end) { s << ", "; } 27 | } 28 | s << "}" << &std::dec; 29 | return s; 30 | } 31 | 32 | } // namespace SharedTypes 33 | } // namespace Flexus 34 | -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/PredictorTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__PREDICTOR_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__PREDICTOR_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Flexus { 9 | namespace SharedTypes { 10 | 11 | #ifndef FLEXUS_TAG_PredictorMessageTag 12 | #define FLEXUS_TAG_PredictorMessageTag 13 | struct PredictorMessageTag_t 14 | {}; 15 | namespace { 16 | PredictorMessageTag_t PredictorMessageTag; 17 | } 18 | #endif // FLEXUS_TAG_PredictorMessageTag 19 | 20 | #ifndef FLEXUS_TAG_TransactionTrackerTag 21 | #define FLEXUS_TAG_TransactionTrackerTag 22 | struct TransactionTrackerTag_t 23 | {}; 24 | struct TransactionTracker; 25 | namespace { 26 | TransactionTrackerTag_t TransactionTrackerTag; 27 | } 28 | #endif // FLEXUS_TAG_TransactionTrackerTag 29 | 30 | typedef Transport, 31 | transport_entry>> 32 | PredictorTransport; 33 | 34 | } // namespace SharedTypes 35 | } // namespace Flexus 36 | 37 | #endif // FLEXUS_TRANSPORTS__PREDICTOR_TRANSPORT_HPP_INCLUDED 38 | -------------------------------------------------------------------------------- /components/uArch/RegisterType.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_UARCH_REGISTERTYPE_HPP_INCLUDED 3 | #define FLEXUS_UARCH_REGISTERTYPE_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | 8 | namespace nuArch { 9 | 10 | static const uint32_t kGlobalRegCount = 32; 11 | static const uint32_t kGlobalRegSets = 1; 12 | 13 | static const uint32_t kNumWindows = 0; 14 | static const uint32_t kRegistersPerWindow = 0; 15 | static const uint32_t kWindowRegCount = kRegistersPerWindow * kNumWindows; 16 | static const uint32_t kSpecialRegCount = 3; 17 | static const uint32_t kTotalRegs = kGlobalRegSets * kGlobalRegCount + kWindowRegCount + kSpecialRegCount; 18 | static const uint32_t kFirstSpecialReg = kGlobalRegSets * kGlobalRegCount + kWindowRegCount; 19 | static const uint32_t kRegY = kFirstSpecialReg; 20 | static const uint32_t kRegASI = kRegY + 1; 21 | static const uint32_t kRegGSR = kRegASI + 1; 22 | 23 | enum eRegisterType 24 | { 25 | xRegisters, 26 | vRegisters, 27 | ccBits, 28 | kLastMapTableCode 29 | }; 30 | 31 | std::ostream& 32 | operator<<(std::ostream& anOstream, eRegisterType aCode); 33 | 34 | } // namespace nuArch 35 | 36 | #endif // FLEXUS_uARCH_REGISTERTYPE_HPP_INCLUDED -------------------------------------------------------------------------------- /core/aux_/layout/begin_declaration_section.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TARGET 2 | #error "Wiring.cpp must contain a flexus target section before the declaration section" 3 | #endif 4 | 5 | #ifdef FLEXUS__LAYOUT_COMPONENTS_DECLARED 6 | #error "Wiring.cpp may contain only one declaration section" 7 | #endif // FLEXUS__LAYOUT_COMPONENTS_DECLARED 8 | 9 | #ifdef FLEXUS__LAYOUT_IN_SECTION 10 | #error "Previous wiring.cpp section is missing the end of section #include" 11 | #endif // FLEXUS__LAYOUT_IN_SECTION 12 | 13 | #define FLEXUS__LAYOUT_IN_SECTION 14 | #define FLEXUS__LAYOUT_DECLARATION_SECTION 15 | 16 | #define FLEXUS_END_COMPONENT NIL 17 | 18 | #define FLEXUS__COMPONENT_CHAIN_CURRENT FLEXUS_BEGIN_COMPONENT 19 | #define FLEXUS__COMPONENT_CHAIN_PREVIOUS FLEXUS_END_COMPONENT 20 | 21 | #define FLEXUS__PREVIOUS_COMP_DECL() BOOST_PP_CAT(FLEXUS__COMP_DECL_, FLEXUS__COMPONENT_CHAIN_PREVIOUS) 22 | #define FLEXUS__COMP_DECL() BOOST_PP_CAT(FLEXUS__COMP_DECL_, FLEXUS__COMPONENT_CHAIN_CURRENT) 23 | 24 | #define FLEXUS__PREVIOUS_IMPLEMENTATION_LIST() \ 25 | BOOST_PP_CAT(FLEXUS__IMPLEMENTATION_LIST_, FLEXUS__COMPONENT_CHAIN_PREVIOUS) 26 | #define FLEXUS__IMPLEMENTATION_LIST() BOOST_PP_CAT(FLEXUS__IMPLEMENTATION_LIST_, FLEXUS__COMPONENT_CHAIN_CURRENT) 27 | -------------------------------------------------------------------------------- /components/BranchPredictor/BTBSet.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_BTB_SET 2 | #define FLEXUS_BTB_SET 3 | 4 | #include "BTBEntry.hpp" 5 | 6 | #include 7 | 8 | /* [MADHUR] 9 | * replacementQueue implements replacement policy for each set 10 | * Head of the queue (replacementQueue[0]) is supposed to be replaced 11 | * after modification or lookup of the set, the replacement queue needs 12 | * to be updated to update the life time of each entry 13 | */ 14 | class BTBSet 15 | { 16 | public: 17 | std::vector blocks; // Array of blocks make up a set 18 | private: 19 | std::vector replacementQueue; 20 | void updateReplacementQueue(uint32_t index); // [MADHUR] Right now, it is LRU 21 | // 22 | public: 23 | BTBSet(); 24 | 25 | BTBSet(uint32_t associativity); 26 | 27 | // [MADHUR] Whether BTB entry corresponding to anAddress is present 28 | bool isHit(VirtualMemoryAddress anAddress); 29 | 30 | // [MADHUR] Return the Hit BTB entry 31 | BTBEntry* access(VirtualMemoryAddress anAddress); 32 | 33 | // [MADHUR] Insert a new BTB Entry 34 | void insert(BTBEntry btbEntry); 35 | 36 | // [MADHUR] Invalidate entry if present 37 | void invalidate(VirtualMemoryAddress anAddress); 38 | 39 | void invalidateAll(); 40 | }; 41 | 42 | #endif -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/TranslationTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__TRANSLATION_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__TRANSLATION_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma GCC diagnostic ignored "-Wunused-variable" 10 | 11 | namespace Flexus { 12 | namespace SharedTypes { 13 | 14 | #ifndef FLEXUS_TAG_TranslationBasicTag 15 | #define FLEXUS_TAG_TranslationBasicTag 16 | struct TranslationBasicTag_t 17 | {}; 18 | namespace { 19 | TranslationBasicTag_t TranslationBasicTag; 20 | } 21 | #endif // FLEXUS_TAG_TranslationBasicTag 22 | 23 | #ifndef FLEXUS_TAG_TranslationStatefulTag 24 | #define FLEXUS_TAG_TranslationStatefulTag 25 | struct TranslationStatefulTag_t 26 | {}; 27 | namespace { 28 | TranslationStatefulTag_t TranslationStatefulTag; 29 | } 30 | #endif // FLEXUS_TAG_TranslationStatefulTag 31 | 32 | typedef Transport, 33 | transport_entry>> 34 | TranslationTransport; 35 | 36 | } // namespace SharedTypes 37 | } // namespace Flexus 38 | 39 | #endif // FLEXUS_TRANSPORTS__TRANSLATION_TRANSPORT_HPP_INCLUDED 40 | -------------------------------------------------------------------------------- /components/TraceTrackerQEMU/TraceTrackerComponentImpl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DBG_DeclareCategories TraceTrack 4 | #define DBG_SetDefaultOps AddCat(TraceTrack) 5 | #include DBG_Control() 6 | 7 | #include 8 | #include 9 | 10 | #define FLEXUS_BEGIN_COMPONENT TraceTrackerComponent 11 | #include FLEXUS_BEGIN_COMPONENT_IMPLEMENTATION() 12 | 13 | namespace nTraceTrackerComponent { 14 | 15 | using namespace Flexus::Core; 16 | using namespace Flexus::SharedTypes; 17 | namespace Stat = Flexus::Stat; 18 | 19 | class FLEXUS_COMPONENT(TraceTrackerComponent) 20 | { 21 | FLEXUS_COMPONENT_IMPL(TraceTrackerComponent); 22 | 23 | public: 24 | FLEXUS_COMPONENT_CONSTRUCTOR(TraceTrackerComponent) 25 | : base(FLEXUS_PASS_CONSTRUCTOR_ARGS) 26 | { 27 | } 28 | 29 | bool isQuiesced() const { return true; } 30 | 31 | void initialize() { theTraceTracker.initialize(); } 32 | 33 | void finalize() { theTraceTracker.finalize(); } 34 | }; 35 | 36 | } // end namespace nTraceTrackerComponent 37 | 38 | FLEXUS_COMPONENT_INSTANTIATOR(TraceTrackerComponent, nTraceTrackerComponent); 39 | 40 | #include FLEXUS_END_COMPONENT_IMPLEMENTATION() 41 | #define FLEXUS_END_COMPONENT TraceTrackerComponent 42 | 43 | #define DBG_Reset 44 | #include DBG_Control() 45 | -------------------------------------------------------------------------------- /core/debug/entry.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_ENTRY_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_ENTRY_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Flexus { 10 | namespace Dbg { 11 | 12 | class Entry 13 | { 14 | std::set theFields; 15 | std::set theCategories; 16 | Severity theSeverity; 17 | 18 | public: 19 | Entry(Severity aSeverity, 20 | char const* aFile, 21 | int64_t aLine, 22 | char const* aFunction, 23 | int64_t aGlobalCount, 24 | int64_t aCycleCount); 25 | Entry& set(std::string const& aFieldName); 26 | Entry& set(std::string const& aFieldName, std::string const& aFieldValue); 27 | Entry& set(std::string const& aFieldName, int64_t aFieldValue); 28 | Entry& append(std::string const& aFieldName, std::string const& aFieldValue); 29 | Entry& addCategory(Category* aCategory); 30 | Entry& addCategories(CategoryHolder const& aCategoryHolder); 31 | std::string get(std::string aFieldName) const; 32 | int64_t getNumeric(std::string aFieldName) const; 33 | bool exists(std::string aFieldName) const; 34 | bool hasCategory(Category const* aCategory) const; 35 | }; 36 | 37 | } // namespace Dbg 38 | } // namespace Flexus 39 | 40 | #endif // FLEXUS_CORE_DEBUG_ENTRY_HPP_INCLUDED 41 | -------------------------------------------------------------------------------- /components/CommonQEMU/DoubleWord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | bool 7 | operator==(uint64_t compare, DoubleWord const& aDoubleWord) 8 | { 9 | bool ret_val(true); 10 | for (int32_t i = 7; i >= 0 && ret_val; --i) { 11 | if (aDoubleWord.theValidBits & (1 << i)) { 12 | ret_val = ((aDoubleWord.theDoubleWord >> (8 * i)) & 0xFF) == ((compare >> (8 * i)) & 0xFF); 13 | } 14 | } 15 | return ret_val; 16 | }; 17 | 18 | bool 19 | operator==(DoubleWord const& entry, uint64_t compare) 20 | { 21 | return compare == entry; 22 | } 23 | 24 | std::ostream& 25 | operator<<(std::ostream& anOstream, DoubleWord const& aDoubleWord) 26 | { 27 | 28 | anOstream << "DW<<" << &std::hex << (uint32_t)aDoubleWord.theValidBits << ',' << aDoubleWord.theDoubleWord << ">> "; 29 | anOstream << "0x" << &std::hex; 30 | uint64_t value(aDoubleWord.theDoubleWord); 31 | for (int32_t i = 7; i >= 0; --i) { 32 | if (aDoubleWord.theValidBits & (1 << i)) { 33 | anOstream << (uint32_t)((value >> (8 * i + 4)) & 0xF); 34 | anOstream << (uint32_t)((value >> (8 * i)) & 0xF); 35 | } else { 36 | anOstream << "--"; 37 | } 38 | } 39 | anOstream << &std::dec; 40 | return anOstream; 41 | } 42 | 43 | } // namespace SharedTypes 44 | } // namespace Flexus 45 | -------------------------------------------------------------------------------- /components/MTManager/MTManagerComponent.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT MTManagerComponent 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | #include "components/MTManager/MTManager.hpp" 9 | 10 | static const int32_t kFE_StrictRoundRobin = 0; 11 | static const int32_t kFE_ICount = 1; 12 | 13 | static const int32_t kBE_StrictRoundRobin = 0; 14 | static const int32_t kBE_SmartRoundRobin = 1; 15 | 16 | COMPONENT_PARAMETERS( 17 | PARAMETER(Cores, uint32_t, "Number of cores", "cores", 1 ) 18 | PARAMETER(Threads, uint32_t, "Number of threads per core", "threads", 1 ) 19 | PARAMETER(FrontEndPolicy, int, "Scheduling policy for front end", "front_policy", kFE_StrictRoundRobin ) 20 | PARAMETER(BackEndPolicy, int, "Scheduling policy for back end", "back_policy", kBE_StrictRoundRobin ) 21 | ); 22 | 23 | COMPONENT_INTERFACE( 24 | DYNAMIC_PORT_ARRAY( PullInput, bool, EXStalled ) 25 | DYNAMIC_PORT_ARRAY( PullInput, bool, FAGStalled ) 26 | DYNAMIC_PORT_ARRAY( PullInput, bool, FStalled ) 27 | DYNAMIC_PORT_ARRAY( PullInput, bool, DStalled ) 28 | DYNAMIC_PORT_ARRAY( PullInput, int, FAQ_ICount) 29 | DYNAMIC_PORT_ARRAY( PullInput, int, FIQ_ICount) 30 | DYNAMIC_PORT_ARRAY( PullInput, int, ROB_ICount) 31 | ); 32 | 33 | #include FLEXUS_END_COMPONENT_DECLARATION() 34 | #define FLEXUS_END_COMPONENT MTManagerComponent 35 | // clang-format on 36 | -------------------------------------------------------------------------------- /components/Decoder/Decoder.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | // clang-format off 5 | #define FLEXUS_BEGIN_COMPONENT Decoder 6 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 7 | 8 | #include 9 | #include 10 | 11 | typedef std::pair < int32_t /*# of instruction */ , bool /* core synchronized? */ > dispatch_status; 12 | 13 | COMPONENT_PARAMETERS( 14 | PARAMETER( FIQSize, uint32_t, "Fetch instruction queue size", "fiq", 32 ) 15 | PARAMETER( DispatchWidth, uint32_t, "Maximum dispatch per cycle", "dispatch", 8 ) 16 | PARAMETER( Multithread, bool, "Enable multi-threaded execution", "multithread", false ) 17 | ); 18 | 19 | COMPONENT_INTERFACE( 20 | PORT( PushInput, pFetchBundle, FetchBundleIn) 21 | PORT( PullOutput, int32_t, AvailableFIQOut) 22 | PORT( PullInput, dispatch_status, AvailableDispatchIn) 23 | PORT( PushOutput, boost::intrusive_ptr< AbstractInstruction>, DispatchOut) 24 | PORT( PushOutput, eSquashCause, SquashOut) 25 | PORT( PushInput, eSquashCause, SquashIn) 26 | PORT( PullOutput, int32_t, ICount) 27 | PORT( PullOutput, bool, Stalled) 28 | 29 | PORT( PushOutput, int64_t, DispatchedInstructionOut) // Send instruction word to Power Tracker 30 | 31 | DRIVE( DecoderDrive ) 32 | ); 33 | 34 | #include FLEXUS_END_COMPONENT_DECLARATION() 35 | #define FLEXUS_END_COMPONENT Decoder 36 | // clang-format on 37 | -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/InstructionTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__INSTRUCTION_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__INSTRUCTION_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | #pragma GCC diagnostic push 8 | #pragma GCC diagnostic ignored "-Wunused-variable" 9 | 10 | namespace Flexus { 11 | namespace SharedTypes { 12 | 13 | #ifndef FLEXUS_TAG_ArchitecturalInstructionTag 14 | #define FLEXUS_TAG_ArchitecturalInstructionTag 15 | struct ArchitecturalInstructionTag_t 16 | {}; 17 | struct ArchitecturalInstruction; 18 | namespace { 19 | ArchitecturalInstructionTag_t ArchitecturalInstructionTag; 20 | } 21 | #endif // FLEXUS_TAG_ArchitecturalInstructionTag 22 | 23 | #ifndef FLEXUS_TAG_TransactionTrackerTag 24 | #define FLEXUS_TAG_TransactionTrackerTag 25 | struct TransactionTrackerTag_t 26 | {}; 27 | struct TransactionTracker; 28 | namespace { 29 | TransactionTrackerTag_t TransactionTrackerTag; 30 | } 31 | #endif // FLEXUS_TAG_TransactionTrackerTag 32 | 33 | typedef Transport, 34 | transport_entry>> 35 | InstructionTransport; 36 | 37 | } // namespace SharedTypes 38 | } // namespace Flexus 39 | 40 | #pragma GCC diagnostic pop 41 | 42 | #endif // FLEXUS_TRANSPORTS__INSTRUCTION_TRANSPORT_HPP_INCLUDED 43 | -------------------------------------------------------------------------------- /components/FetchAddressGenerate/FetchAddressGenerate.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | // clang-format off 6 | #define FLEXUS_BEGIN_COMPONENT FetchAddressGenerate 7 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 8 | 9 | COMPONENT_PARAMETERS( 10 | PARAMETER( MaxFetchAddress, uint32_t, "Max fetch addresses generated per cycle", "faddrs", 10 ) 11 | PARAMETER( MaxBPred, uint32_t, "Max branches predicted per cycle", "bpreds", 2 ) 12 | PARAMETER( Threads, uint32_t, "Number of threads under control of this FAG", "threads", 1 ) 13 | PARAMETER( BTBSets, uint32_t, "Number of sets in the BTB", "btbsets", 512 ) 14 | PARAMETER( BTBWays, uint32_t, "Number of ways in the BTB", "btbways", 4 ) 15 | PARAMETER( PerfectBPU, bool, "Perfect BPU", "perfect", 0) 16 | ); 17 | 18 | COMPONENT_INTERFACE( 19 | DYNAMIC_PORT_ARRAY( PushInput, boost::intrusive_ptr, RedirectIn ) 20 | DYNAMIC_PORT_ARRAY( PushInput, boost::intrusive_ptr, BranchTrainIn ) 21 | 22 | DYNAMIC_PORT_ARRAY( PushOutput, boost::intrusive_ptr, FetchAddrOut ) 23 | DYNAMIC_PORT_ARRAY( PullInput, int, AvailableFAQ ) 24 | DYNAMIC_PORT_ARRAY( PullOutput, bool, Stalled) 25 | PORT( PullInput, bool, uArchHalted) 26 | 27 | DRIVE( FAGDrive ) 28 | ); 29 | 30 | #include FLEXUS_END_COMPONENT_DECLARATION() 31 | #define FLEXUS_END_COMPONENT FetchAddressGenerate 32 | // clang-format on 33 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PredictorMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__PREDICTORMESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__PREDICTORMESSAGE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace SharedTypes { 9 | 10 | typedef Flexus::SharedTypes::PhysicalMemoryAddress tAddress; 11 | 12 | class PredictorMessage : public boost::counted_base 13 | { 14 | public: 15 | enum tPredictorMessageType 16 | { 17 | eFlush, 18 | eWrite, 19 | eReadPredicted, 20 | eReadNonPredicted, 21 | }; 22 | 23 | private: 24 | tPredictorMessageType theType; 25 | int32_t theNode; 26 | tAddress theAddress; 27 | 28 | public: 29 | PredictorMessage(tPredictorMessageType aType, int32_t aNode, tAddress anAddress) 30 | : theType(aType) 31 | , theNode(aNode) 32 | , theAddress(anAddress) 33 | { 34 | } 35 | const tPredictorMessageType type() const { return theType; } 36 | int32_t node() const { return theNode; } 37 | tAddress address() const { return theAddress; } 38 | }; 39 | 40 | std::ostream& 41 | operator<<(std::ostream& anOstream, PredictorMessage::tPredictorMessageType aType); 42 | std::ostream& 43 | operator<<(std::ostream& aStream, PredictorMessage const& anEntry); 44 | 45 | } // namespace SharedTypes 46 | } // namespace Flexus 47 | 48 | #endif // FLEXUS_SLICES__PREDICTORMESSAGE_HPP_INCLUDED 49 | -------------------------------------------------------------------------------- /core/debug/field.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_FIELD_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_FIELD_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Flexus { 9 | namespace Dbg { 10 | 11 | using namespace std::rel_ops; 12 | 13 | class Field 14 | { 15 | std::string theName; 16 | // These members are declared mutable for 2 reasons: 17 | // 1 - the numeric to string conversion for theTextValue is done 18 | // when value() is called, and value needs to be a const member. 19 | // 2 - Changing these members does not affect the ordering of Fields 20 | mutable boost::optional theTextValue; 21 | mutable boost::optional theNumericValue; 22 | 23 | public: 24 | bool operator==(Field const& aField) const; 25 | bool operator<(Field const& aField) const; 26 | Field(std::string const& aName); 27 | 28 | // This method is declared const because it does not affecgt the ordering 29 | // of Fields 30 | void setValue(std::string const& aString) const; 31 | 32 | // This method is declared const because it does not affecgt the ordering 33 | // of Fields 34 | void setValue(int64_t aValue) const; 35 | bool isNumeric() const; 36 | std::string const& value() const; 37 | int64_t numericValue() const; 38 | }; 39 | 40 | } // namespace Dbg 41 | } // namespace Flexus 42 | 43 | #endif // FLEXUS_CORE_DEBUG_FIELD_HPP_INCLUDED 44 | -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/DirectoryTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__DIRECTORY_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__DIRECTORY_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | 6 | namespace Flexus { 7 | namespace SharedTypes { 8 | 9 | #ifndef FLEXUS_TAG_DirectoryMessageTag 10 | #define FLEXUS_TAG_DirectoryMessageTag 11 | struct DirectoryMessageTag_t 12 | {}; 13 | struct DirectoryMessage; 14 | namespace { 15 | DirectoryMessageTag_t DirectoryMessageTag; 16 | } 17 | #endif // FLEXUS_TAG_DirectoryMessageTag 18 | 19 | #ifndef FLEXUS_TAG_DirectoryEntryTag 20 | #define FLEXUS_TAG_DirectoryEntryTag 21 | struct DirectoryEntryTag_t 22 | {}; 23 | struct DirectoryEntry; 24 | namespace { 25 | DirectoryEntryTag_t DirectoryEntryTag; 26 | } 27 | #endif // FLEXUS_TAG_DirectoryEntryTag 28 | 29 | #ifndef FLEXUS_TAG_DirMux2ArbTag 30 | #define FLEXUS_TAG_DirMux2ArbTag 31 | struct DirMux2ArbTag_t 32 | {}; 33 | struct Mux; 34 | namespace { 35 | DirMux2ArbTag_t DirMux2ArbTag; 36 | } 37 | #endif // FLEXUS_TAG_DirMux2ArbTag 38 | 39 | typedef Transport, 40 | transport_entry, 41 | transport_entry>> 42 | DirectoryTransport; 43 | 44 | } // namespace SharedTypes 45 | } // namespace Flexus 46 | 47 | #endif // FLEXUS_TRANSPORTS__DIRECTORY_TRANSPORT_HPP_INCLUDED 48 | -------------------------------------------------------------------------------- /components/MultiNic/MultiNicX.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_MULTI_NIC_NUMPORTS 3 | #error "FLEXUS_MULTI_NIC_NUMPORTS must be defined" 4 | #endif 5 | 6 | #include 7 | #include 8 | 9 | // clang-format off 10 | #define MultiNicX BOOST_PP_CAT(MultiNic, FLEXUS_MULTI_NIC_NUMPORTS) 11 | 12 | #define FLEXUS_BEGIN_COMPONENT MultiNicX 13 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 14 | 15 | #include 16 | 17 | #define NodeOutputPort(z,N,_) DYNAMIC_PORT_ARRAY( PushOutput, MemoryTransport, BOOST_PP_CAT(ToNode,N) ) 18 | #define NodeInputPort(z,N,_) DYNAMIC_PORT_ARRAY( PushInput, MemoryTransport, BOOST_PP_CAT(FromNode,N) ) 19 | 20 | COMPONENT_PARAMETERS( 21 | FLEXUS_PARAMETER( VChannels, int, "Virtual channels", "vc", 3 ) 22 | FLEXUS_PARAMETER( RecvCapacity, uint32_t, "Recv Queue Capacity", "recv-capacity", 1) 23 | FLEXUS_PARAMETER( SendCapacity, uint32_t, "Send Queue Capacity", "send-capacity", 1) 24 | ); 25 | 26 | COMPONENT_INTERFACE( 27 | DYNAMIC_PORT_ARRAY( PushOutput, MemoryTransport, ToNetwork ) 28 | DYNAMIC_PORT_ARRAY( PushInput, MemoryTransport, FromNetwork ) 29 | BOOST_PP_REPEAT(FLEXUS_MULTI_NIC_NUMPORTS, NodeOutputPort, _ ) 30 | BOOST_PP_REPEAT(FLEXUS_MULTI_NIC_NUMPORTS, NodeInputPort, _ ) 31 | DRIVE( MultiNicDrive ) 32 | ); 33 | 34 | #include FLEXUS_END_COMPONENT_DECLARATION() 35 | #define FLEXUS_END_COMPONENT MultiNicX 36 | // clang-format on 37 | -------------------------------------------------------------------------------- /core/aux_/layout/begin_component_declaration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_IMPLEMENTATION_FILE 2 | 3 | #ifndef FLEXUS__LAYOUT_DECLARATION_SECTION 4 | #error "Component declaration files must be included in the component declaration section of wiring.cpp" 5 | #endif // FLEXUS_LAYOUT_COMPONENT_DECLARATION_SECTION 6 | 7 | #ifndef FLEXUS_BEGIN_COMPONENT 8 | #error "This component never declared the FLEXUS_BEGIN_COMPONENT macro" 9 | #endif // FLEXUS_COMPONENT 10 | 11 | #ifndef FLEXUS_END_COMPONENT 12 | #error "Previous component forget to set the FLEXUS_END_COMPONENT macro" 13 | #endif // FLEXUS_END_COMPONENT 14 | 15 | #endif // FLEXUS_IMPLEMENTATION_FILE 16 | 17 | #define FLEXUS__LAYOUT_IN_COMPONENT_DECLARATION 18 | 19 | using namespace Flexus::SharedTypes; 20 | 21 | #define COMPONENT_NO_PARAMETERS FLEXUS_DECLARE_COMPONENT_NO_PARAMETERS(FLEXUS_BEGIN_COMPONENT) 22 | #define COMPONENT_PARAMETERS(x) FLEXUS_DECLARE_COMPONENT_PARAMETERS(FLEXUS_BEGIN_COMPONENT, x) 23 | #define PARAMETER FLEXUS_PARAMETER 24 | 25 | #define COMPONENT_EMPTY_INTERFACE FLEXUS_COMPONENT_EMPTY_INTERFACE(FLEXUS_BEGIN_COMPONENT) 26 | #define COMPONENT_INTERFACE(x) FLEXUS_COMPONENT_INTERFACE(FLEXUS_BEGIN_COMPONENT, x) 27 | #define PORT(x, y, z) FLEXUS_IFACE_PORT(x, y, z) 28 | #define PORT_ARRAY(x, y, z, w) FLEXUS_IFACE_PORT_ARRAY(x, y, z, w) 29 | #define DYNAMIC_PORT_ARRAY(x, y, z) FLEXUS_IFACE_DYNAMIC_PORT_ARRAY(x, y, z) 30 | #define DRIVE(x) FLEXUS_IFACE_DRIVE(x) 31 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/ExceptionAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace ll = boost::lambda; 10 | 11 | #include "../Effects.hpp" 12 | #include "../SemanticActions.hpp" 13 | #include "../SemanticInstruction.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define DBG_DeclareCategories Decoder 23 | #define DBG_SetDefaultOps AddCat(Decoder) 24 | #include DBG_Control() 25 | 26 | namespace nDecoder { 27 | 28 | using namespace nuArch; 29 | 30 | struct ExceptionAction : public BaseSemanticAction 31 | { 32 | 33 | ExceptionAction(SemanticInstruction* anInstruction) 34 | : BaseSemanticAction(anInstruction, 1) 35 | { 36 | } 37 | 38 | void doEvaluate() {} 39 | 40 | void describe(std::ostream& anOstream) const { anOstream << theInstruction->identify() << " ExceptionAction "; } 41 | }; 42 | 43 | simple_action 44 | exceptionAction(SemanticInstruction* anInstruction) 45 | { 46 | ExceptionAction* act = new ExceptionAction(anInstruction); 47 | anInstruction->addNewComponent(act); 48 | return simple_action(act); 49 | } 50 | 51 | } // namespace nDecoder 52 | -------------------------------------------------------------------------------- /components/BranchPredictor/BTB.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_BTB 2 | #define FLEXUS_BTB 3 | 4 | #include "BTBSet.hpp" 5 | #include "components/uFetch/uFetchTypes.hpp" 6 | #include "core/checkpoint/json.hpp" 7 | #include "core/types.hpp" 8 | 9 | #include 10 | 11 | using json = nlohmann::json; 12 | using namespace Flexus::SharedTypes; 13 | 14 | class BTB 15 | { 16 | private: 17 | std::vector theBTB; // Array of Sets make up a cache 18 | uint64_t theIndexMask; 19 | 20 | public: 21 | uint32_t theBTBSets; 22 | uint32_t theBTBAssoc; 23 | 24 | private: 25 | BTB() = default; 26 | 27 | public: 28 | BTB(int32_t aBTBSets, int32_t aBTBAssoc); 29 | /* The PC is assumed to be word aligned so the index into the Set Associative structure is */ 30 | /* INDEX_MASK anded with the PC >> 2 */ 31 | uint32_t index(VirtualMemoryAddress anAddress); 32 | // Whether the BTB contains target for anAddress 33 | bool contains(VirtualMemoryAddress anAddress); 34 | // The kind of branch corresponding to the address: conditional, direct, indirect, return, etc 35 | eBranchType type(VirtualMemoryAddress anAddress); 36 | // Target address of the branch 37 | boost::optional target(VirtualMemoryAddress anAddress); 38 | // Update or add a new entry to the BTB 39 | bool update(VirtualMemoryAddress aPC, eBranchType aType, VirtualMemoryAddress aTarget); 40 | bool update(const BPredState &aFeedback); 41 | 42 | json saveState() const; 43 | void loadState(json checkpoint); 44 | }; 45 | 46 | #endif -------------------------------------------------------------------------------- /core/debug/target.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Flexus { 7 | namespace Dbg { 8 | 9 | Target::Target(std::string const& aName, Filter* aFilter, Action* anAction) 10 | : theName(aName) 11 | , theFilter(aFilter) 12 | , theAction(anAction) 13 | { 14 | } 15 | 16 | void 17 | Target::process(Entry const& anEntry) 18 | { 19 | if (theFilter->match(anEntry) == Filter::Include) { theAction->process(anEntry); } 20 | } 21 | 22 | Filter& 23 | Target::filter() 24 | { 25 | return *theFilter; 26 | } 27 | void 28 | Target::setFilter(std::unique_ptr aFilter) 29 | { 30 | theFilter = std::move(aFilter); 31 | } 32 | 33 | Action& 34 | Target::action() 35 | { 36 | return *theAction; 37 | } 38 | void 39 | Target::setAction(std::unique_ptr anAction) 40 | { 41 | theAction = std::move(anAction); 42 | } 43 | 44 | void 45 | Target::printConfiguration(std::ostream& anOstream, std::string const& anIndent) 46 | { 47 | anOstream << anIndent << "target \"" << theName << "\" {\n"; 48 | anOstream << anIndent << " filter {\n"; 49 | 50 | theFilter->printConfiguration(anOstream, anIndent + " "); 51 | 52 | anOstream << anIndent << " }\n"; 53 | anOstream << anIndent << " action {\n"; 54 | 55 | theAction->printConfiguration(anOstream, anIndent + " "); 56 | 57 | anOstream << anIndent << " }\n"; 58 | anOstream << anIndent << "}\n"; 59 | } 60 | 61 | } // namespace Dbg 62 | } // namespace Flexus 63 | -------------------------------------------------------------------------------- /components/uFetch/PortCombinerImpl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define FLEXUS_BEGIN_COMPONENT PortCombiner 5 | #include FLEXUS_BEGIN_COMPONENT_IMPLEMENTATION() 6 | 7 | namespace nPortCombiner { 8 | 9 | using namespace Flexus; 10 | using namespace Core; 11 | using namespace SharedTypes; 12 | using boost::intrusive_ptr; 13 | 14 | class FLEXUS_COMPONENT(PortCombiner) 15 | { 16 | FLEXUS_COMPONENT_IMPL(PortCombiner); 17 | 18 | public: 19 | FLEXUS_COMPONENT_CONSTRUCTOR(PortCombiner) 20 | : base(FLEXUS_PASS_CONSTRUCTOR_ARGS) 21 | { 22 | } 23 | 24 | public: 25 | // Initialization 26 | void initialize() {} 27 | 28 | void finalize() {} 29 | 30 | bool isQuiesced() const 31 | { 32 | return true; // Mux is always quiesced 33 | } 34 | 35 | // Ports 36 | bool available(interface::ReplyIn const&) { return FLEXUS_CHANNEL(FetchMissOut).available(); } 37 | void push(interface::ReplyIn const&, MemoryTransport& aMemTransport) 38 | { 39 | FLEXUS_CHANNEL(FetchMissOut) << aMemTransport; 40 | } 41 | 42 | bool available(interface::SnoopIn const&) { return FLEXUS_CHANNEL(FetchMissOut).available(); } 43 | void push(interface::SnoopIn const&, MemoryTransport& aMemTransport) 44 | { 45 | FLEXUS_CHANNEL(FetchMissOut) << aMemTransport; 46 | } 47 | }; 48 | 49 | } // End Namespace nPortCombiner 50 | 51 | FLEXUS_COMPONENT_INSTANTIATOR(PortCombiner, nPortCombiner); 52 | 53 | #include FLEXUS_END_COMPONENT_IMPLEMENTATION() 54 | #define FLEXUS_END_COMPONENT PortCombiner 55 | -------------------------------------------------------------------------------- /core/flexus.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_FLEXUS_HPP__INCLUDED 2 | #define FLEXUS_CORE_FLEXUS_HPP__INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Flexus::Core { 9 | class FlexusInterface 10 | { 11 | public: 12 | // Initialization functions 13 | virtual void initializeComponents() = 0; 14 | 15 | // The main cycle function 16 | virtual void doCycle() = 0; 17 | virtual void setCycle(uint64_t cycle) = 0; 18 | virtual bool quiescing() const = 0; 19 | // fast-forward through cycles 20 | // Note: does not tick stats, check watchdogs, or call drives 21 | 22 | // Simulator state inquiry 23 | virtual uint64_t cycleCount() const = 0; 24 | 25 | // Watchdog Functions 26 | virtual void reset_core_watchdog(uint32_t) = 0; 27 | 28 | virtual void terminateSimulation() = 0; 29 | 30 | virtual void setDebug(std::string const& aDebugSeverity) = 0; 31 | virtual void setDebugOverride() = 0; 32 | virtual void setStatInterval(uint64_t aValue) = 0; 33 | virtual void setStopCycle(uint64_t aValue) = 0; 34 | virtual void set_log_delay(uint64_t aValue) = 0; 35 | 36 | virtual void doLoad(std::string const& aDirName) = 0; 37 | virtual void doSave(std::string const& aDirName) = 0; 38 | virtual void writeMeasurement(std::string const& aMeasurement, std::string const& aFilename) = 0; 39 | }; 40 | 41 | extern FlexusInterface* theFlexus; 42 | 43 | void 44 | flexus_qmp(int cmd, const char* arg); 45 | 46 | } 47 | 48 | #endif // FLEXUS_CORE_FLEXUS_HPP__INCLUDED 49 | -------------------------------------------------------------------------------- /.github/workflows/00-build.yaml: -------------------------------------------------------------------------------- 1 | name: Build Binaries 2 | run-name: '[${{ github.event_name }}] ${{ github.ref_name }} > ${{ github.sha }}' 3 | 4 | # When is the workflow actually triggerd 5 | on: 6 | # Manually triggered 7 | workflow_dispatch: 8 | push: 9 | branches: 10 | - master 11 | - maintainer/bryan # will be deleted at some point 12 | pull_request: 13 | branches: 14 | - master 15 | 16 | # schedule: 17 | # # Every Wednesday at midnight 18 | # - cron: '0 0 * * 3' 19 | # 20 | 21 | concurrency: 22 | group: ${{ github.workflow }}-${{ github.ref }} 23 | cancel-in-progress: true 24 | 25 | jobs: 26 | # Build the Krakens if their files have been modified 27 | build_simulator: 28 | runs-on: ubuntu-24.04 29 | name: Build Simulators 30 | env: 31 | CC: gcc-13 32 | CXX: g++-13 33 | 34 | strategy: 35 | fail-fast: true 36 | matrix: 37 | binaries: 38 | - semikraken 39 | - knottykraken 40 | build_type: 41 | - release 42 | #- relwithdebinfo 43 | - debug 44 | 45 | steps: 46 | - name: Checkout Flexus 47 | uses: actions/checkout@v4 48 | 49 | - uses: actions/setup-python@v5 50 | with: 51 | python-version: '3.11.9' 52 | 53 | - name: Install conan 54 | run: pip install conan 55 | 56 | - name: Detect current environmment profile 57 | run: conan profile detect --force 58 | 59 | - name: Build a Flexus based on matrix 60 | run: conan build . -pr target/_profile/${{ matrix.build_type }} -b missing --name=${{ matrix.binaries }} -of ./build 61 | -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/PrefetchTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__PREFETCH_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__PREFETCH_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Flexus { 10 | namespace SharedTypes { 11 | 12 | #ifndef FLEXUS_TAG_PrefetchMessageTag 13 | #define FLEXUS_TAG_PrefetchMessageTag 14 | struct PrefetchMessageTag_t 15 | {}; 16 | namespace { 17 | PrefetchMessageTag_t PrefetchMessageTag; 18 | } 19 | #endif // FLEXUS_TAG_PredictorMessageTag 20 | 21 | #ifndef FLEXUS_TAG_PrefetchCommandTag 22 | #define FLEXUS_TAG_PrefetchCommandTag 23 | struct PrefetchCommandTag_t 24 | {}; 25 | namespace { 26 | PrefetchCommandTag_t PrefetchCommandTag; 27 | } 28 | #endif // FLEXUS_TAG_PredictorMessageTag 29 | 30 | #ifndef FLEXUS_TAG_TransactionTrackerTag 31 | #define FLEXUS_TAG_TransactionTrackerTag 32 | struct TransactionTrackerTag_t 33 | {}; 34 | struct TransactionTracker; 35 | namespace { 36 | TransactionTrackerTag_t TransactionTrackerTag; 37 | } 38 | #endif // FLEXUS_TAG_TransactionTrackerTag 39 | 40 | typedef Transport, 41 | transport_entry, 42 | transport_entry>> 43 | PrefetchTransport; 44 | 45 | } // namespace SharedTypes 46 | } // namespace Flexus 47 | 48 | #endif // FLEXUS_TRANSPORTS__PREFETCH_TRANSPORT_HPP_INCLUDED 49 | -------------------------------------------------------------------------------- /components/CommonQEMU/OneWayMuxImpl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define FLEXUS_BEGIN_COMPONENT OneWayMux 5 | #include FLEXUS_BEGIN_COMPONENT_IMPLEMENTATION() 6 | 7 | namespace nOneWayMux { 8 | 9 | using namespace Flexus; 10 | using namespace Core; 11 | using namespace SharedTypes; 12 | 13 | class FLEXUS_COMPONENT(OneWayMux) 14 | { 15 | FLEXUS_COMPONENT_IMPL(OneWayMux); 16 | 17 | public: 18 | FLEXUS_COMPONENT_CONSTRUCTOR(OneWayMux) 19 | : base(FLEXUS_PASS_CONSTRUCTOR_ARGS) 20 | { 21 | } 22 | 23 | public: 24 | // Initialization 25 | void initialize() {} 26 | 27 | // Added by PLotfi 28 | void finalize() {} 29 | // end PLotfi 30 | 31 | bool isQuiesced() const 32 | { 33 | return true; // Mux is always quiesced 34 | } 35 | 36 | // Ports 37 | // From the instruction cache 38 | bool available(interface::InI const&, index_t anIndex) { return true; } 39 | 40 | void push(interface::InI const&, index_t anIndex, MemoryMessage& aMessage) { FLEXUS_CHANNEL(Out) << aMessage; } 41 | 42 | // From the data cache 43 | bool available(interface::InD const&, index_t anIndex) { return true; } 44 | 45 | void push(interface::InD const&, index_t anIndex, MemoryMessage& aMessage) { FLEXUS_CHANNEL(Out) << aMessage; } 46 | }; 47 | 48 | } // End Namespace nOneWayMux 49 | 50 | FLEXUS_COMPONENT_INSTANTIATOR(OneWayMux, nOneWayMux); 51 | 52 | FLEXUS_PORT_ARRAY_WIDTH(OneWayMux, InI) 53 | { 54 | return 1; 55 | } 56 | FLEXUS_PORT_ARRAY_WIDTH(OneWayMux, InD) 57 | { 58 | return 1; 59 | } 60 | 61 | #include FLEXUS_END_COMPONENT_IMPLEMENTATION() 62 | #define FLEXUS_END_COMPONENT OneWayMux 63 | -------------------------------------------------------------------------------- /core/debug/field.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace Dbg { 9 | 10 | bool 11 | Field::operator==(Field const& aField) const 12 | { 13 | return theName == aField.theName; 14 | } 15 | 16 | bool 17 | Field::operator<(Field const& aField) const 18 | { 19 | return theName < aField.theName; 20 | } 21 | 22 | Field::Field(std::string const& aName) 23 | : theName(aName) 24 | { 25 | } 26 | 27 | // This method is declared const because it does not affecgt the ordering 28 | // of Fields 29 | void 30 | Field::setValue(std::string const& aString) const 31 | { 32 | theNumericValue.reset(); 33 | theTextValue.reset(aString); 34 | } 35 | 36 | // This method is declared const because it does not affecgt the ordering 37 | // of Fields 38 | void 39 | Field::setValue(int64_t aValue) const 40 | { 41 | theTextValue.reset(); 42 | theNumericValue.reset(aValue); 43 | } 44 | 45 | bool 46 | Field::isNumeric() const 47 | { 48 | return theNumericValue.is_initialized(); 49 | } 50 | 51 | std::string const& 52 | Field::value() const 53 | { 54 | if (!theTextValue) { 55 | if (isNumeric()) { 56 | theTextValue.reset(std::to_string(*theNumericValue)); 57 | } else { 58 | theTextValue.reset(std::string()); 59 | } 60 | } 61 | return *theTextValue; 62 | } 63 | 64 | int64_t 65 | Field::numericValue() const 66 | { 67 | if (isNumeric()) { 68 | return *theNumericValue; 69 | } else { 70 | return 0; 71 | } 72 | } 73 | 74 | } // namespace Dbg 75 | } // namespace Flexus 76 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/PredicatedSemanticAction.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace ll = boost::lambda; 9 | 10 | #include "../Effects.hpp" 11 | #include "../SemanticActions.hpp" 12 | #include "../SemanticInstruction.hpp" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace nDecoder { 22 | 23 | using namespace nuArch; 24 | 25 | struct PredicatedSemanticAction : public BaseSemanticAction 26 | { 27 | bool thePredicate; 28 | 29 | PredicatedSemanticAction(SemanticInstruction* anInstruction, int32_t aNumArgs, bool anInitialPredicate); 30 | 31 | struct Pred : public DependanceTarget 32 | { 33 | PredicatedSemanticAction& theAction; 34 | Pred(PredicatedSemanticAction& anAction) 35 | : theAction(anAction) 36 | { 37 | } 38 | void satisfy(int32_t anArg) 39 | { 40 | SEMANTICS_TRACE; 41 | theAction.predicate_on(anArg); 42 | } 43 | void squash(int32_t anArg) { theAction.predicate_off(anArg); } 44 | } thePredicateTarget; 45 | 46 | InternalDependance predicate() { return InternalDependance(&thePredicateTarget, 0); } 47 | 48 | virtual void squash(int); 49 | virtual void predicate_off(int); 50 | virtual void predicate_on(int); 51 | virtual void evaluate(); 52 | }; 53 | 54 | } // namespace nDecoder 55 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/IndexMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__INDEX_MESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__INDEX_MESSAGE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FLEXUS_IndexMessage_TYPE_PROVIDED 10 | 11 | namespace Flexus { 12 | namespace SharedTypes { 13 | 14 | typedef Flexus::SharedTypes::PhysicalMemoryAddress MemoryAddress; 15 | 16 | namespace IndexCommand { 17 | enum IndexCommand 18 | { 19 | eLookup, 20 | eInsert, 21 | eUpdate, 22 | eMatchReply, 23 | eNoMatchReply, 24 | eNoUpdateReply, 25 | }; 26 | 27 | namespace { 28 | char* IndexCommandStr[] = { "eLookup", "eInsert", "eUpdate", "eMatchReply", "eNoMatchReply", "eNoUpdateReply" }; 29 | } 30 | 31 | inline std::ostream& 32 | operator<<(std::ostream& aStream, IndexCommand cmd) 33 | { 34 | if (cmd <= eNoMatchReply) { aStream << IndexCommandStr[cmd]; } 35 | return aStream; 36 | } 37 | } // namespace IndexCommand 38 | 39 | struct IndexMessage : public boost::counted_base 40 | { 41 | IndexCommand::IndexCommand theCommand; 42 | MemoryAddress theAddress; 43 | int32_t theTMSc; 44 | int32_t theCMOB; 45 | int64_t theCMOBOffset; 46 | uint64_t theStartTime; 47 | std::list thePrefix; 48 | }; 49 | 50 | inline std::ostream& 51 | operator<<(std::ostream& aStream, const IndexMessage& msg) 52 | { 53 | aStream << msg.theCommand << " TMSc[" << msg.theTMSc << "] " << msg.theAddress << " -> " << msg.theCMOB << " @" 54 | << msg.theCMOBOffset; 55 | return aStream; 56 | } 57 | 58 | } // namespace SharedTypes 59 | } // namespace Flexus 60 | 61 | #endif // FLEXUS_COMMON_INDEXMESSAGE_HPP_INCLUDED 62 | -------------------------------------------------------------------------------- /components/CommonQEMU/Transports/NetworkTransport.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_TRANSPORTS__NETWORK_TRANSPORT_HPP_INCLUDED 2 | #define FLEXUS_TRANSPORTS__NETWORK_TRANSPORT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Flexus { 11 | namespace SharedTypes { 12 | 13 | #ifndef FLEXUS_TAG_NetworkMessageTag 14 | #define FLEXUS_TAG_NetworkMessageTag 15 | struct NetworkMessageTag_t 16 | {}; 17 | struct NetworkMessage; 18 | namespace { 19 | NetworkMessageTag_t NetworkMessageTag; 20 | } 21 | #endif // FLEXUS_TAG_NetworkMessageTag 22 | 23 | #ifndef FLEXUS_TAG_ProtocolMessageTag 24 | #define FLEXUS_TAG_ProtocolMessageTag 25 | struct ProtocolMessageTag_t 26 | {}; 27 | struct ProtocolMessage; 28 | namespace { 29 | ProtocolMessageTag_t ProtocolMessageTag; 30 | } 31 | #endif // FLEXUS_TAG_NetworkMessageTag 32 | 33 | #ifndef FLEXUS_TAG_TransactionTrackerTag 34 | #define FLEXUS_TAG_TransactionTrackerTag 35 | struct TransactionTrackerTag_t 36 | {}; 37 | struct TransactionTracker; 38 | namespace { 39 | TransactionTrackerTag_t TransactionTrackerTag; 40 | } 41 | #endif // FLEXUS_TAG_TransactionTrackerTag 42 | 43 | typedef Transport, 44 | transport_entry, 45 | transport_entry>> 46 | NetworkTransport; 47 | 48 | } // namespace SharedTypes 49 | } // namespace Flexus 50 | 51 | #endif // FLEXUS_TRANSPORTS__NETWORK_TRANSPORT_HPP_INCLUDED 52 | -------------------------------------------------------------------------------- /components/BranchPredictor/ITTAGE.h: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_ITTAGE 2 | #define FLEXUS_ITTAGE 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Flexus; 10 | using namespace SharedTypes; 11 | 12 | class ITTAGE 13 | { 14 | private: 15 | struct ITTAGE_entry { 16 | uint64_t tag; // (partial) tag 17 | uint64_t target; // target 18 | uint64_t confidence; // confidence for indirect branches 19 | uint64_t rrpv; // replacement information, useful bit for ITTAGE 20 | }; 21 | 22 | // parameters 23 | static const int MIN_HIST = 4; 24 | static const int MAX_HIST = 260; 25 | static const int ITTAGE_NTAB = 4; 26 | static const int ITTAGE_TAG_NBIT = 13; 27 | static const int ITTAGE_IDX_NBIT = 12; 28 | static const int ITTAGE_IDX_SIZE = 1 << ITTAGE_IDX_NBIT; 29 | 30 | ITTAGE_entry ittage_set[ITTAGE_NTAB][ITTAGE_IDX_SIZE]; 31 | 32 | // branch history 33 | uint64_t btb_ghr[16]; 34 | 35 | // ITTAGE 36 | int ittage_hlen[ITTAGE_NTAB]; 37 | int64_t ittage_tick; 38 | int64_t ittage_hit_bank; 39 | int64_t ittage_alt_diff; 40 | int64_t ittage_use_alt; 41 | uint64_t ittage_hit_pred; 42 | uint64_t ittage_alt_pred; 43 | uint64_t ittage_hash_idx[ITTAGE_NTAB]; 44 | uint64_t ittage_hash_tag[ITTAGE_NTAB]; 45 | 46 | public: 47 | ITTAGE(); 48 | 49 | void checkpointHistory(BPredState& aBPState) const; 50 | void restore_history(const BPredState& aBPState); 51 | 52 | uint64_t predict(uint64_t ip); 53 | 54 | uint64_t update_target(uint64_t target, bool mispred, const BPredState& aBPState); 55 | void update_history(uint64_t target); 56 | }; 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /components/Decoder/InstructionComponentBuffer.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_DECODER_INSTRUCTIONCOMPONENTBUFFER_HPP_INCLUDED 3 | #define FLEXUS_DECODER_INSTRUCTIONCOMPONENTBUFFER_HPP_INCLUDED 4 | 5 | #include 6 | #include 7 | 8 | static const size_t kICBSize = 2048; 9 | 10 | namespace nDecoder { 11 | extern Flexus::Stat::StatCounter theICBs; 12 | 13 | struct UncountedComponent 14 | { 15 | virtual ~UncountedComponent() {} 16 | }; 17 | 18 | struct InstructionComponentBuffer 19 | { 20 | size_t theComponentCount; 21 | std::vector theComponents; 22 | 23 | InstructionComponentBuffer() 24 | : theComponentCount(0) 25 | { 26 | theComponents.reserve(kICBSize); 27 | } 28 | 29 | ~InstructionComponentBuffer() 30 | { 31 | for (auto aComp : theComponents) { 32 | delete aComp; 33 | } 34 | } 35 | 36 | size_t addNewComponent(UncountedComponent* aComponent) 37 | { 38 | try { 39 | if (++theComponentCount >= theComponents.capacity()) { theComponents.reserve(theComponents.size() * 2); } 40 | theComponents.emplace_back(aComponent); 41 | return theComponentCount; 42 | } catch (std::exception& e) { 43 | DBG_Assert(false, 44 | (<< "Could not add component " << aComponent << " to ICB. Number of components stored: " 45 | << theComponentCount << ", vector capacity: " << theComponents.capacity() 46 | << ", threw exception type: " << e.what())); 47 | return 0; // dodge compiler error 48 | } 49 | } 50 | }; 51 | 52 | } // namespace nDecoder 53 | 54 | #endif // FLEXUS_DECODER_INSTRUCTIONCOMPONENTBUFFER_HPP_INCLUDED 55 | -------------------------------------------------------------------------------- /components/Decoder/Validations.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_DECODER_VALIDATIONS_HPP_INCLUDED 3 | #define FLEXUS_DECODER_VALIDATIONS_HPP_INCLUDED 4 | 5 | #include "OperandCode.hpp" 6 | #include "SemanticInstruction.hpp" 7 | 8 | namespace nDecoder { 9 | 10 | struct validateXRegister 11 | { 12 | uint32_t theReg; 13 | eOperandCode theOperandCode; 14 | SemanticInstruction* theInstruction; 15 | bool the_64; 16 | 17 | validateXRegister(uint32_t aReg, eOperandCode anOperand, SemanticInstruction* anInstruction, bool is_64) 18 | : theReg(aReg) 19 | , theOperandCode(anOperand) 20 | , theInstruction(anInstruction) 21 | , the_64(is_64) 22 | { 23 | } 24 | 25 | bool operator()(); 26 | }; 27 | 28 | struct validatePC 29 | { 30 | SemanticInstruction* theInstruction; 31 | bool thePreValidation; 32 | 33 | validatePC(SemanticInstruction* anInstruction, bool prevalidation = false) 34 | : theInstruction(anInstruction) 35 | , thePreValidation(prevalidation) 36 | { 37 | } 38 | 39 | bool operator()(); 40 | }; 41 | 42 | struct validateMemory 43 | { 44 | eOperandCode theAddressCode; 45 | eOperandCode theValueCode; 46 | nuArch::eSize theSize; 47 | SemanticInstruction* theInstruction; 48 | 49 | validateMemory(eOperandCode anAddressCode, 50 | eOperandCode aValueCode, 51 | nuArch::eSize aSize, 52 | SemanticInstruction* anInstruction) 53 | : theAddressCode(anAddressCode) 54 | , theValueCode(aValueCode) 55 | , theSize(aSize) 56 | , theInstruction(anInstruction) 57 | { 58 | } 59 | 60 | bool operator()(); 61 | }; 62 | 63 | } // namespace nDecoder 64 | 65 | #endif // FLEXUS_DECODER_VALIDATIONS_HPP_INCLUDED 66 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/CMOBMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__CMOB_MESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__CMOB_MESSAGE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define FLEXUS_CMOBMessage_TYPE_PROVIDED 10 | 11 | namespace Flexus { 12 | namespace SharedTypes { 13 | 14 | typedef Flexus::SharedTypes::PhysicalMemoryAddress MemoryAddress; 15 | 16 | struct CMOBLine 17 | { 18 | static const int32_t kLineSize = 12; 19 | MemoryAddress theAddresses[kLineSize]; 20 | std::bitset theWasHit; 21 | }; 22 | 23 | inline std::ostream& 24 | operator<<(std::ostream& aStream, const CMOBLine& line) 25 | { 26 | for (int32_t i = 0; i < 12; ++i) { 27 | aStream << std::hex << line.theAddresses[i] << (line.theWasHit[i] ? "(hit) " : "(nohit) "); 28 | } 29 | return aStream; 30 | } 31 | 32 | namespace CMOBCommand { 33 | enum CMOBCommand 34 | { 35 | eRead, 36 | eWrite, 37 | eInit 38 | }; 39 | } 40 | namespace { 41 | char* CMOBCommandStr[] = { "eRead", "eWrite", "eInit" }; 42 | } 43 | 44 | struct CMOBMessage : public boost::counted_base 45 | { 46 | CMOBCommand::CMOBCommand theCommand; 47 | CMOBLine theLine; 48 | int64_t theCMOBOffset; 49 | uint32_t theCMOBId; 50 | int64_t theRequestTag; 51 | }; 52 | 53 | inline std::ostream& 54 | operator<<(std::ostream& aStream, const CMOBMessage& msg) 55 | { 56 | aStream << "CMOB[" << msg.theCMOBId << "] #" << msg.theRequestTag << " " << CMOBCommandStr[msg.theCommand] << " @" 57 | << msg.theCMOBOffset << " " << msg.theLine; 58 | return aStream; 59 | } 60 | 61 | } // namespace SharedTypes 62 | } // namespace Flexus 63 | 64 | #endif // FLEXUS_COMMON_CMOBMESSAGE_HPP_INCLUDED 65 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/MRCMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__MRCMESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__MRCMESSAGE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace SharedTypes { 9 | 10 | class MRCMessage : public boost::counted_base 11 | { 12 | 13 | public: 14 | enum MRCMessageType 15 | { 16 | // Sent by Consort to inform MRCReflector that it has added a block to 17 | // its buffer 18 | kAppend, 19 | 20 | // Sent by MRCReflector to request a stream on behalf of a node which 21 | // experienced a read miss 22 | kRequestStream 23 | 24 | }; 25 | 26 | private: 27 | MRCMessageType theType; 28 | uint32_t theNode; 29 | PhysicalMemoryAddress theAddress; 30 | int64_t theLocation; 31 | int64_t theTag; 32 | 33 | public: 34 | const MRCMessageType type() const { return theType; } 35 | 36 | uint32_t node() const { return theNode; } 37 | 38 | PhysicalMemoryAddress address() const { return theAddress; } 39 | 40 | int64_t location() const { return theLocation; } 41 | 42 | int64_t tag() const { return theTag; } 43 | 44 | MRCMessage(MRCMessageType aType, 45 | uint32_t aNode, 46 | PhysicalMemoryAddress anAddress, 47 | int64_t aLocation, 48 | int64_t aTag = -1) 49 | : theType(aType) 50 | , theNode(aNode) 51 | , theAddress(anAddress) 52 | , theLocation(aLocation) 53 | , theTag(aTag) 54 | { 55 | } 56 | 57 | friend std::ostream& operator<<(std::ostream& s, MRCMessage const& aMsg); 58 | }; 59 | 60 | } // namespace SharedTypes 61 | } // namespace Flexus 62 | 63 | #endif // FLEXUS_SLICES__MRCMESSAGE_HPP_INCLUDED 64 | -------------------------------------------------------------------------------- /components/CommonQEMU/MemoryMap.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_COMPONENTS_MEMORYMAP_HPP__INCLUDED 2 | #define FLEXUS_COMPONENTS_MEMORYMAP_HPP__INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace SharedTypes { 9 | 10 | typedef Flexus::Core::index_t node_id_t; 11 | 12 | struct MemoryMap : public boost::counted_base 13 | { 14 | static boost::intrusive_ptr getMemoryMap(); 15 | static boost::intrusive_ptr getMemoryMap(Flexus::Core::index_t aRequestingNode); 16 | 17 | enum AccessType 18 | { 19 | Read, 20 | Write, 21 | NumAccessTypes /* Must be last */ 22 | }; 23 | 24 | static std::string const& AccessType_toString(AccessType anAccessType) 25 | { 26 | static std::string access_type_names[] = { "Read ", "Write" }; 27 | // xyzzy 28 | DBG_Assert((anAccessType < NumAccessTypes)); 29 | return access_type_names[anAccessType]; 30 | } 31 | 32 | virtual bool isCacheable(Flexus::SharedTypes::PhysicalMemoryAddress const&) = 0; 33 | virtual bool isMemory(Flexus::SharedTypes::PhysicalMemoryAddress const&) = 0; 34 | virtual bool isIO(Flexus::SharedTypes::PhysicalMemoryAddress const&) = 0; 35 | virtual node_id_t node(Flexus::SharedTypes::PhysicalMemoryAddress const&) = 0; 36 | virtual void loadState(std::string const&) = 0; 37 | virtual void recordAccess(Flexus::SharedTypes::PhysicalMemoryAddress const&, AccessType anAccessType) = 0; 38 | }; 39 | 40 | } // namespace SharedTypes 41 | } // namespace Flexus 42 | 43 | #endif // FLEXUS_COMPONENTS_MEMORYMAP_HPP__INCLUDED 44 | -------------------------------------------------------------------------------- /core/debug/format.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_DEBUG_FORMAT_HPP_INCLUDED 2 | #define FLEXUS_CORE_DEBUG_FORMAT_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Flexus { 9 | namespace Dbg { 10 | 11 | struct Format 12 | { 13 | virtual void format(std::ostream& anOstream, Entry const& anEntry) const = 0; 14 | virtual void printConfiguration(std::ostream& anOstream, std::string const& anIndent) const = 0; 15 | virtual ~Format() {} 16 | }; 17 | 18 | class StaticFormat : public Format 19 | { 20 | std::string theValue; 21 | 22 | public: 23 | StaticFormat(std::string const& aValue); 24 | virtual void format(std::ostream& anOstream, Entry const& anEntry) const; 25 | virtual void printConfiguration(std::ostream& anOstream, std::string const& anIndent) const; 26 | }; 27 | 28 | class FieldFormat : public Format 29 | { 30 | std::string theField; 31 | 32 | public: 33 | FieldFormat(std::string const& aField); 34 | virtual void format(std::ostream& anOstream, Entry const& anEntry) const; 35 | virtual void printConfiguration(std::ostream& anOstream, std::string const& anIndent) const; 36 | }; 37 | 38 | class CompoundFormat : public Format 39 | { 40 | std::vector theFormats; // These actions are owned by the pointers in theFormats 41 | public: 42 | virtual void printConfiguration(std::ostream& anOstream, std::string const& anIndent) const; 43 | virtual void format(std::ostream& anOstream, Entry const& anEntry) const; 44 | virtual ~CompoundFormat() { destruct(); } 45 | void destruct(); 46 | 47 | // Assumes ownership of the passed in Format 48 | void add(Format* aFormat); 49 | }; 50 | 51 | } // namespace Dbg 52 | } // namespace Flexus 53 | 54 | #endif // FLEXUS_CORE_DEBUG_FORMAT_HPP_INCLUDED 55 | -------------------------------------------------------------------------------- /components/CommonQEMU/GlobalHasher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _GLOBAL_HASHER_HPP_ 2 | #define _GLOBAL_HASHER_HPP_ 3 | 4 | #include "core/types.hpp" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace nGlobalHasher { 12 | 13 | typedef Flexus::SharedTypes::PhysicalMemoryAddress Address; 14 | 15 | class GlobalHasher 16 | { 17 | private: 18 | typedef std::function hash_fn_t; 19 | typedef std::list::iterator hash_iterator_t; 20 | 21 | GlobalHasher(); 22 | 23 | int32_t theHashShift; 24 | int32_t theHashMask; 25 | 26 | std::list theHashList; 27 | 28 | bool has_been_initialized; 29 | 30 | int32_t simple_hash(int32_t offset, const Address& addr) const; 31 | int32_t xor_hash(int32_t offset, int32_t xor_shift, const Address& addr) const; 32 | int32_t shift_hash(int32_t offset, int32_t shift, const Address& addr) const; 33 | int32_t full_prime_hash(int32_t offset, int32_t prime, const Address& addr) const; 34 | 35 | std::function createMatrixHash(std::string args, 36 | int32_t num_buckets, 37 | int32_t shift, 38 | int32_t mask, 39 | int32_t offset) const; 40 | 41 | public: 42 | std::set hashAddr(const Address& addr); 43 | 44 | void initialize(std::list& hash_configs, 45 | int32_t initial_shift, 46 | int32_t buckets_per_hash, 47 | bool partitioned); 48 | 49 | int32_t numHashes() { return theHashList.size(); } 50 | 51 | static GlobalHasher& theHasher(); 52 | }; 53 | }; // namespace nGlobalHasher 54 | 55 | #endif // ! _GLOBAL_HASHER_HPP_ -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/DirectoryEntry.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Flexus { 4 | namespace SharedTypes { 5 | 6 | // for debug output 7 | std::ostream& 8 | operator<<(std::ostream& anOstream, tDirState const x) 9 | { 10 | const char* const name[3] = { "DIR_STATE_INVALID", "DIR_STATE_SHARED", "DIR_STATE_MODIFIED" }; 11 | DBG_Assert(x < static_cast(sizeof(name) / sizeof(name[0]))); 12 | anOstream << name[x]; 13 | return anOstream; 14 | } 15 | 16 | std::ostream& 17 | operator<<(std::ostream& aStream, DirectoryEntry const& anEntry) 18 | { 19 | switch (anEntry.getState()) { 20 | case DIR_STATE_INVALID: aStream << anEntry.getState(); break; 21 | case DIR_STATE_SHARED: { 22 | bool first = true; 23 | aStream << anEntry.getState() << " Sharers{"; 24 | for (int32_t i = 0; i < 16; ++i) { 25 | if (anEntry.theNodes & (1UL << i)) { 26 | if (!first) { aStream << ","; } 27 | first = false; 28 | aStream << i; 29 | } 30 | } 31 | aStream << "}"; 32 | break; 33 | } 34 | case DIR_STATE_MODIFIED: aStream << anEntry.getState() << " Owner=" << anEntry.theNodes; break; 35 | } 36 | aStream << ((anEntry.wasModified()) ? " " : " !"); 37 | aStream << "WasModified"; 38 | bool first = true; 39 | aStream << anEntry.getState() << " PastSharers{"; 40 | for (int32_t i = 0; i < 16; ++i) { 41 | if (anEntry.getPastReaders() & (1UL << i)) { 42 | if (!first) { aStream << ","; } 43 | first = false; 44 | aStream << i; 45 | } 46 | } 47 | aStream << "}"; 48 | return aStream; 49 | } 50 | 51 | } // namespace SharedTypes 52 | } // namespace Flexus 53 | -------------------------------------------------------------------------------- /core/boost_extensions/intrusive_ptr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_CORE_BOOST_EXTENSIONS_INTRUSIVE_PTR_HPP_INCLUDED 2 | #define FLEXUS_CORE_BOOST_EXTENSIONS_INTRUSIVE_PTR_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace boost { 9 | 10 | struct counted_base 11 | { 12 | mutable int32_t theRefCount; 13 | 14 | counted_base() 15 | : theRefCount(0) 16 | { 17 | } 18 | virtual ~counted_base() {} 19 | }; 20 | 21 | template 22 | void 23 | intrusive_ptr_add_ref(T* p) 24 | { 25 | static_cast(p)->theRefCount++; 26 | } 27 | 28 | template 29 | void 30 | intrusive_ptr_release(T* p) 31 | { 32 | if (--static_cast(p)->theRefCount == 0) { delete p; } 33 | } 34 | 35 | } // namespace boost 36 | 37 | namespace boost { 38 | namespace serialization { 39 | template 40 | void 41 | save(Archive& ar, ::boost::intrusive_ptr const& ptr, uint32_t version) 42 | { 43 | T* t = ptr.get(); 44 | ar & t; 45 | } 46 | 47 | template 48 | void 49 | load(Archive& ar, ::boost::intrusive_ptr& ptr, uint32_t version) 50 | { 51 | T* t; 52 | ar & t; 53 | ptr = boost::intrusive_ptr(t); 54 | } 55 | 56 | template 57 | inline void 58 | serialize(Archive& ar, ::boost::intrusive_ptr& t, const uint32_t file_version) 59 | { 60 | split_free(ar, t, file_version); 61 | } 62 | } // namespace serialization 63 | } // namespace boost 64 | 65 | namespace boost { 66 | namespace lambda { 67 | namespace detail { 68 | 69 | template 70 | struct contentsof_type> 71 | { 72 | typedef A& type; 73 | }; 74 | 75 | } // namespace detail 76 | } // namespace lambda 77 | } // namespace boost 78 | 79 | #endif // FLEXUS_CORE_BOOST_EXTENSIONS_INTRUSIVE_PTR_HPP_INCLUDED 80 | -------------------------------------------------------------------------------- /core/types.cpp: -------------------------------------------------------------------------------- 1 | #include "types.hpp" 2 | 3 | namespace Flexus { 4 | namespace Core { 5 | 6 | // bits add_bits(const bits & lhs, const bits & rhs){ 7 | // bits sum = lhs ^ rhs; 8 | // bits carry = (lhs & rhs) << 1; 9 | // if ((sum & carry) > 0) 10 | // return add_bits (sum, carry); 11 | // else 12 | // return sum ^ carry; 13 | //} 14 | 15 | // bits sub_bits(bits x, bits y){ 16 | // while (y.to_ulong() != 0) 17 | // { 18 | // bits borrow = (~x) & y; 19 | // x = x ^ y; 20 | // y = borrow << 1; 21 | // } 22 | // return x; 23 | //} 24 | 25 | // static void populateBitSet (std::string &buffer, bits &bitMap) 26 | //{ 27 | // const bits &temp = bits(buffer); 28 | // bitMap = temp; 29 | //} 30 | 31 | // bits fillbits(const int bitSize){ 32 | // bits result; 33 | // std::string buffer; 34 | // for (int i = 0; i < bitSize; i++){ 35 | // buffer += "1"; 36 | // } 37 | // populateBitSet(buffer, result); 38 | // return result; 39 | //} 40 | 41 | bool 42 | anyBits(bits b) 43 | { 44 | return b != 0; 45 | } 46 | 47 | bits 48 | align(uint64_t x, int y) 49 | { 50 | return bits(y * (x / y)); 51 | } 52 | 53 | bits 54 | concat_bits(const bits& lhs, const bits& rhs) 55 | { 56 | 57 | return ((lhs << 64) | rhs); 58 | } 59 | 60 | bits 61 | construct(uint8_t* bytes, size_t size) 62 | { 63 | bits result; 64 | for (int i = (size - 1); i >= 0; i--) { 65 | result |= bytes[i] << i; 66 | } 67 | return result; 68 | } 69 | 70 | std::pair 71 | splitBits(const bits& input, uint64_t size) 72 | { 73 | size /= 2; 74 | bits a, b = -1; 75 | a = b <<= size; 76 | b = ~a; 77 | std::pair ret; 78 | ret.first = static_cast((a & input) >> size); 79 | ret.second = static_cast(b & input); 80 | 81 | return ret; 82 | } 83 | 84 | } // namespace Core 85 | } // namespace Flexus 86 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/MapDestInOrderAction.cpp: -------------------------------------------------------------------------------- 1 | #include "core/boost_extensions/intrusive_ptr.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | namespace ll = boost::lambda; 8 | #include "../Effects.hpp" 9 | #include "../SemanticActions.hpp" 10 | #include "../SemanticInstruction.hpp" 11 | #include "RegisterValueExtractor.hpp" 12 | #include "components/uArch/systemRegister.hpp" 13 | #include "components/uArch/uArchInterfaces.hpp" 14 | #include "core/debug/debug.hpp" 15 | #include "core/qemu/api.h" 16 | #include "core/target.hpp" 17 | #include "core/types.hpp" 18 | 19 | #include 20 | #include 21 | 22 | #define DBG_DeclareCategories Decoder 23 | #define DBG_SetDefaultOps AddCat(Decoder) 24 | #include DBG_Control() 25 | 26 | namespace nDecoder { 27 | 28 | using namespace nuArch; 29 | 30 | struct MapDestInOrderAction : public BaseSemanticAction { 31 | eOperandCode theRd; 32 | 33 | MapDestInOrderAction(SemanticInstruction *anInstruction, eOperandCode anRd) 34 | : BaseSemanticAction(anInstruction, 1, true), theRd(anRd) { 35 | setReady(0, true); 36 | } 37 | 38 | void doEvaluate() { 39 | if (ready()) { 40 | core()->mapDestInOrder(theInstruction->sequenceNo(), theInstruction->operand(theRd)); 41 | satisfyDependants(); 42 | } 43 | } 44 | 45 | void describe(std::ostream &anOstream) const { 46 | anOstream << theInstruction->identify() << " MapInOrderAction to " << theRd; 47 | } 48 | }; 49 | 50 | simple_action mapDestInOrderAction(SemanticInstruction *anInstruction, eOperandCode aMappedRegisterCode) { 51 | MapDestInOrderAction *act = new MapDestInOrderAction(anInstruction, aMappedRegisterCode); 52 | anInstruction->addNewComponent(act); 53 | return simple_action(act); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /components/MMU/MMU.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Changelog: 3 | // - June'18: msutherl - basic TLB definition, no real timing info 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // clang-format off 11 | #define FLEXUS_BEGIN_COMPONENT MMU 12 | #include FLEXUS_BEGIN_COMPONENT_DECLARATION() 13 | 14 | 15 | 16 | COMPONENT_PARAMETERS( 17 | PARAMETER( iTLBSet, size_t, "Set count of the Instruction TLB", "itlb_set", 1 ) 18 | PARAMETER( iTLBAssoc, size_t, "Associativity of the Instruction TLB", "itlb_assoc", 64 ) 19 | PARAMETER( dTLBSet, size_t, "Set count of the Data TLB", "dtlb_set", 64 ) 20 | PARAMETER( dTLBAssoc, size_t, "Associativity of the Data TLB", "dtlb_assoc", 64 ) 21 | PARAMETER( sTLBlat, int, "sTLB lookup latency", "stlblat", 2) 22 | PARAMETER( sTLBSet, size_t, "Set count of the Second-level TLB", "stlb_sete", 2048 ) 23 | PARAMETER( sTLBAssoc, size_t, "Associativity of the Second-level TLB", "stlb_assoc", 4 ) 24 | PARAMETER( PerfectTLB, bool, "TLB never misses", "perfect", true ) 25 | ); 26 | 27 | COMPONENT_INTERFACE( 28 | DYNAMIC_PORT_ARRAY( PushInput, TranslationPtr, iRequestIn ) 29 | DYNAMIC_PORT_ARRAY( PushInput, TranslationPtr, dRequestIn ) 30 | DYNAMIC_PORT_ARRAY( PushInput, int, ResyncIn) 31 | 32 | DYNAMIC_PORT_ARRAY( PushOutput, TranslationPtr, iTranslationReply ) 33 | DYNAMIC_PORT_ARRAY( PushOutput, TranslationPtr, dTranslationReply ) 34 | DYNAMIC_PORT_ARRAY( PushOutput, TranslationPtr, MemoryRequestOut ) 35 | 36 | DYNAMIC_PORT_ARRAY( PushInput, TranslationPtr, TLBReqIn ) // this is for trace 37 | 38 | DYNAMIC_PORT_ARRAY( PushOutput, int, ResyncOut ) 39 | 40 | 41 | DRIVE(MMUDrive) 42 | ); 43 | 44 | #include FLEXUS_END_COMPONENT_DECLARATION() 45 | #define FLEXUS_END_COMPONENT MMU 46 | // clang-format on 47 | -------------------------------------------------------------------------------- /components/Decoder/OperandMap.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_DECODER_OPERANDMAP_HPP_INCLUDED 3 | #define FLEXUS_DECODER_OPERANDMAP_HPP_INCLUDED 4 | 5 | #include "OperandCode.hpp" 6 | 7 | #include 8 | 9 | using namespace nuArch; 10 | 11 | namespace nDecoder { 12 | 13 | using operand_typelist_1 = mpl::push_front::type; 14 | using operand_typelist = mpl::push_front::type; 15 | using Operand = boost::make_variant_over::type; 16 | 17 | class OperandMap 18 | { 19 | 20 | typedef std::map operand_map; 21 | operand_map theOperandMap; 22 | 23 | public: 24 | template 25 | T& operand(eOperandCode anOperandId) 26 | { 27 | return boost::get(theOperandMap[anOperandId]); 28 | } 29 | 30 | Operand& operand(eOperandCode anOperandId) { return theOperandMap[anOperandId]; } 31 | 32 | template 33 | void set(eOperandCode anOperandId, T aT) 34 | { 35 | theOperandMap[anOperandId] = aT; 36 | } 37 | 38 | void set(eOperandCode anOperandId, Operand const& aT) { theOperandMap[anOperandId] = aT; } 39 | 40 | bool hasOperand(eOperandCode anOperandId) const { return (theOperandMap.find(anOperandId) != theOperandMap.end()); } 41 | 42 | struct operandPrinter 43 | { 44 | std::ostream& theOstream; 45 | operandPrinter(std::ostream& anOstream) 46 | : theOstream(anOstream) 47 | { 48 | } 49 | void operator()(operand_map::value_type const& anEntry) 50 | { 51 | theOstream << "\t " << anEntry.first << " = " << anEntry.second << "\n"; 52 | } 53 | }; 54 | 55 | void dump(std::ostream& anOstream) const 56 | { 57 | std::for_each(theOperandMap.begin(), theOperandMap.end(), operandPrinter(anOstream)); 58 | } 59 | }; 60 | 61 | } // namespace nDecoder 62 | 63 | #endif // FLEXUS_DECODER_OPERANDMAP_HPP_INCLUDED 64 | -------------------------------------------------------------------------------- /components/MMU/TranslationGranules.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _ARM_TRANSLATION_GRANULES_DEFINED_HPP_ 2 | #define _ARM_TRANSLATION_GRANULES_DEFINED_HPP_ 3 | #include 4 | 5 | namespace nMMU { 6 | 7 | /* Msutherl - june'18 8 | * - added definitions for granules and varying sizes 9 | */ 10 | class TranslationGranule 11 | { 12 | protected: 13 | unsigned KBSize; 14 | unsigned logKBSize; 15 | unsigned granuleShift; 16 | unsigned granuleEntries; 17 | 18 | uint8_t PARange_RawValue; 19 | uint8_t PAddrWidth; 20 | uint8_t IAddrOffset; 21 | 22 | public: 23 | TranslationGranule(); 24 | TranslationGranule(unsigned ksize, unsigned PASize, unsigned IASize); 25 | unsigned getKBSize() const; 26 | unsigned getlogKBSize() const; 27 | unsigned getGranuleShift() const; 28 | unsigned getGranuleEntries() const; 29 | uint8_t getPARange_Raw() const; 30 | void setPARange_Raw(uint8_t aRawValue); 31 | uint8_t getPAddrWidth() const; 32 | void setPAddrWidth(uint8_t aSize); 33 | uint8_t getIAddrOffset() const; 34 | void setIAddrOffset(uint8_t aSize); 35 | 36 | uint8_t NumBitsResolvedPerTTAccess() const; 37 | uint8_t getIAddrSize() const; 38 | uint8_t getInitialLookupLevel() const; 39 | virtual uint64_t GetLowerAddressRangeLimit() const; 40 | virtual uint64_t GetUpperAddressRangeLimit() const; 41 | }; 42 | 43 | class TG0_Granule : public TranslationGranule 44 | { 45 | public: 46 | TG0_Granule(); 47 | TG0_Granule(unsigned granuleSize, unsigned PAddrSize, unsigned IAOffset); 48 | uint64_t GetLowerAddressRangeLimit() const; 49 | uint64_t GetUpperAddressRangeLimit() const; 50 | }; 51 | 52 | class TG1_Granule : public TranslationGranule 53 | { 54 | public: 55 | TG1_Granule(); 56 | TG1_Granule(unsigned granuleSize, unsigned PAddrSize, unsigned IAOffset); 57 | uint64_t GetLowerAddressRangeLimit() const; 58 | uint64_t GetUpperAddressRangeLimit() const; 59 | }; 60 | 61 | } // namespace nMMU 62 | 63 | #endif //_ARM_TRANSLATION_GRANULES_DEFINED_HPP_ 64 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.25) 2 | project(flexus) 3 | 4 | # Add crucial definiton for compilating Flexus 5 | # TARGET_PLATFORM = Only platform supported so far, so kind of useless 6 | add_compile_definitions(FLEXUS) 7 | add_compile_definitions(TARGET_PLATFORM=aarch64) 8 | add_compile_definitions(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) 9 | add_compile_definitions(BOOST_MPL_LIMIT_VECTOR_SIZE=50) 10 | add_compile_definitions(SELECTED_DEBUG=vverb) 11 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 12 | 13 | #Include simulator specific settings only for "real" simulators 14 | include(./target/${SIMULATOR}/${SIMULATOR}.cmake) 15 | 16 | # Setup include paths 17 | include_directories(.) 18 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -fdiagnostics-color=always -g3 -gdwarf-5") 19 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -fno-eliminate-unused-debug-symbols -fno-omit-frame-pointer -funroll-loops -fno-inline -fno-lto") 20 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native -fno-omit-frame-pointer") 21 | 22 | # Find boost 23 | set(Boost_USE_DEBUG_LIBS OFF) 24 | find_package(Boost REQUIRED COMPONENTS system iostreams regex serialization) 25 | include_directories(${Boost_INCLUDE_DIRS}) 26 | 27 | # compile core 28 | file(GLOB_RECURSE CORE_SOURCE ./core/*.cpp) 29 | add_library(core STATIC ${CORE_SOURCE}) 30 | target_compile_options(core PRIVATE) 31 | 32 | # compile components 33 | foreach(COMPONENT ${REQUIRED_COMPONENTS}) 34 | file(GLOB_RECURSE COMPONENT_${COMPONENT}_SOURCE "./components/${COMPONENT}/*.cpp") 35 | add_library(${COMPONENT} STATIC ${COMPONENT_${COMPONENT}_SOURCE}) 36 | target_compile_options(${COMPONENT} PRIVATE) 37 | endforeach() 38 | 39 | # compile simulators 40 | add_library(${SIMULATOR} SHARED ./target/${SIMULATOR}/wiring.cpp) 41 | target_link_libraries(${SIMULATOR} "-Wl,--whole-archive" "-Wl,--no-undefined" core ${REQUIRED_COMPONENTS}) 42 | target_link_libraries(${SIMULATOR} "-Wl,--no-whole-archive" ${Boost_LIBRARIES} boost_system boost_regex boost_serialization boost_iostreams) 43 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/ReadConstantAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace ll = boost::lambda; 10 | 11 | #include "../Effects.hpp" 12 | #include "../SemanticActions.hpp" 13 | #include "../SemanticInstruction.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define DBG_DeclareCategories Decoder 23 | #define DBG_SetDefaultOps AddCat(Decoder) 24 | #include DBG_Control() 25 | 26 | namespace nDecoder { 27 | 28 | using namespace nuArch; 29 | 30 | struct ReadConstantAction : public BaseSemanticAction 31 | { 32 | eOperandCode theOperandCode; 33 | uint64_t theVal; 34 | 35 | ReadConstantAction(SemanticInstruction* anInstruction, int64_t aVal, eOperandCode anOperandCode) 36 | : BaseSemanticAction(anInstruction, 1) 37 | , theOperandCode(anOperandCode) 38 | , theVal(aVal) 39 | { 40 | } 41 | 42 | void doEvaluate() 43 | { 44 | DBG_(VVerb, (<< "Reading constant: 0x" << std::hex << theVal << std::dec << " into " << theOperandCode)); 45 | theInstruction->setOperand(theOperandCode, theVal); 46 | 47 | satisfyDependants(); 48 | } 49 | 50 | void describe(std::ostream& anOstream) const 51 | { 52 | anOstream << theInstruction->identify() << " ReadConstant " << theVal << " to " << theOperandCode; 53 | } 54 | }; 55 | 56 | simple_action 57 | readConstantAction(SemanticInstruction* anInstruction, uint64_t aVal, eOperandCode anOperandCode) 58 | { 59 | ReadConstantAction* act = new ReadConstantAction(anInstruction, aVal, anOperandCode); 60 | anInstruction->addNewComponent(act); 61 | return simple_action(act); 62 | } 63 | 64 | } // namespace nDecoder 65 | -------------------------------------------------------------------------------- /components/MMU/pageWalk.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_PAGEWALK_HPP_INCLUDED 3 | #define FLEXUS_PAGEWALK_HPP_INCLUDED 4 | 5 | #include "MMUUtil.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace Flexus::SharedTypes; 12 | 13 | namespace nMMU { 14 | 15 | class MMUComponent; 16 | 17 | class PageWalk 18 | { 19 | std::list theTranslationTransports; 20 | 21 | std::queue> theDoneTranslations; 22 | std::queue> theMemoryTranslations; 23 | 24 | PhysicalMemoryAddress trace_address; 25 | 26 | bool TheInitialized; 27 | 28 | public: 29 | PageWalk(uint32_t aNode, MMUComponent* aMMU) 30 | : TheInitialized(false) 31 | , mmu(aMMU) 32 | , theNode(aNode) 33 | { 34 | } 35 | ~PageWalk() {} 36 | void translate(TranslationTransport& aTransport); 37 | void preTranslate(TranslationTransport& aTransport); 38 | void cycle(); 39 | bool push_back(boost::intrusive_ptr aTranslation); 40 | bool push_back_trace(boost::intrusive_ptr aTranslation, Flexus::Qemu::Processor theCPU); 41 | TranslationPtr popMemoryRequest(); 42 | bool hasMemoryRequest(); 43 | void annulAll(); 44 | 45 | private: 46 | void preWalk(TranslationTransport& aTranslation); 47 | bool walk(TranslationTransport& aTranslation); 48 | void setupTTResolver(TranslationTransport& aTr, uint64_t TTDescriptor); 49 | bool InitialTranslationSetup(TranslationTransport& aTranslation); 50 | void pushMemoryRequest(TranslationPtr aTranslation); 51 | 52 | TTEDescriptor getNextTTDescriptor(TranslationTransport& aTranslation); 53 | 54 | std::list delay; 55 | MMUComponent* mmu; 56 | 57 | uint8_t currentEL(); 58 | uint32_t currentPSTATE(); 59 | 60 | uint32_t theNode; 61 | }; 62 | 63 | } // end namespace nMMU 64 | 65 | #endif // FLEXUS_PAGEWALK_HPP_INCLUDED 66 | -------------------------------------------------------------------------------- /components/NetShim/netnode.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "netnode.hpp" 3 | 4 | #include "netcontainer.hpp" 5 | 6 | namespace nNetShim { 7 | 8 | NetNode::NetNode(const int32_t nodeId_, NetContainer* nc_) 9 | : nodeId(nodeId_) 10 | , nc(nc_) 11 | , messagesWaiting(0) 12 | { 13 | fromNodePort = new ChannelOutputPort(INT_MAX); 14 | toNodePort = new ChannelInputPort(1, 1, nullptr, this); 15 | } 16 | 17 | bool 18 | NetNode::drive(void) 19 | { 20 | MessageState* msg; 21 | 22 | int i; 23 | 24 | if (!messagesWaiting) return false; 25 | 26 | for (i = 0; i < MAX_VC; i++) { 27 | if (toNodePort->hasMessage(i) && nc->isNodeAvailable(nodeId, NETVC_TO_PROTVC(i))) { 28 | 29 | toNodePort->removeMessage(i, msg); 30 | 31 | if (msg->destNode != nodeId) { 32 | cerr << "Message " << msg->serial << " delivered to wrong node (" << nodeId << ")" << endl; 33 | return true; 34 | } 35 | 36 | TRACE(msg, "Node " << nodeId << " is delivering message "); 37 | 38 | if (nc->deliverMessage(msg)) { return true; } 39 | 40 | messagesWaiting--; 41 | 42 | } else if (toNodePort->hasMessage(i)) { 43 | toNodePort->peekMessage(i, msg); 44 | TRACE(msg, "Port unavailable to deliver msg to " << msg->destNode << " on vc " << i); 45 | } 46 | } 47 | 48 | return false; 49 | } 50 | 51 | bool 52 | NetNode::checkTopology(void) const 53 | { 54 | int i; 55 | 56 | for (i = 0; i < MAX_NET_VC; i++) { 57 | if (!fromNodePort->isConnected() || !toNodePort->isConnected()) { 58 | 59 | std::cerr << "ERROR: node " << nodeId << " is missing channel connections (node unreachable)" << endl; 60 | 61 | return true; 62 | } 63 | } 64 | 65 | return false; 66 | } 67 | 68 | bool 69 | NetNode::dumpState(ostream& out) 70 | { 71 | out << "Node: " << nodeId << endl; 72 | if (fromNodePort->dumpState(out) || toNodePort->dumpState(out)) return true; 73 | 74 | out << endl; 75 | return false; 76 | } 77 | 78 | } // namespace nNetShim 79 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.v": "coq", 4 | "any": "cpp", 5 | "array": "cpp", 6 | "atomic": "cpp", 7 | "bit": "cpp", 8 | "*.tcc": "cpp", 9 | "bitset": "cpp", 10 | "cctype": "cpp", 11 | "charconv": "cpp", 12 | "chrono": "cpp", 13 | "clocale": "cpp", 14 | "cmath": "cpp", 15 | "codecvt": "cpp", 16 | "compare": "cpp", 17 | "concepts": "cpp", 18 | "cstdarg": "cpp", 19 | "cstddef": "cpp", 20 | "cstdint": "cpp", 21 | "cstdio": "cpp", 22 | "cstdlib": "cpp", 23 | "cstring": "cpp", 24 | "ctime": "cpp", 25 | "cwchar": "cpp", 26 | "cwctype": "cpp", 27 | "deque": "cpp", 28 | "forward_list": "cpp", 29 | "list": "cpp", 30 | "map": "cpp", 31 | "set": "cpp", 32 | "string": "cpp", 33 | "unordered_map": "cpp", 34 | "unordered_set": "cpp", 35 | "vector": "cpp", 36 | "exception": "cpp", 37 | "algorithm": "cpp", 38 | "functional": "cpp", 39 | "iterator": "cpp", 40 | "memory": "cpp", 41 | "memory_resource": "cpp", 42 | "numeric": "cpp", 43 | "optional": "cpp", 44 | "random": "cpp", 45 | "ratio": "cpp", 46 | "string_view": "cpp", 47 | "system_error": "cpp", 48 | "tuple": "cpp", 49 | "type_traits": "cpp", 50 | "utility": "cpp", 51 | "format": "cpp", 52 | "fstream": "cpp", 53 | "initializer_list": "cpp", 54 | "iomanip": "cpp", 55 | "iosfwd": "cpp", 56 | "iostream": "cpp", 57 | "istream": "cpp", 58 | "limits": "cpp", 59 | "new": "cpp", 60 | "numbers": "cpp", 61 | "ostream": "cpp", 62 | "ranges": "cpp", 63 | "span": "cpp", 64 | "sstream": "cpp", 65 | "stdexcept": "cpp", 66 | "streambuf": "cpp", 67 | "cinttypes": "cpp", 68 | "typeinfo": "cpp", 69 | "valarray": "cpp", 70 | "variant": "cpp" 71 | } 72 | } -------------------------------------------------------------------------------- /components/Decoder/encodings/DataProcReg.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_armDECODER_armDATAPROCREG_HPP_INCLUDED 3 | #define FLEXUS_armDECODER_armDATAPROCREG_HPP_INCLUDED 4 | 5 | #include "components/Decoder/Instruction.hpp" 6 | 7 | using namespace nuArch; 8 | 9 | namespace nDecoder { 10 | 11 | // Logical (shifted register) 12 | archinst 13 | LOGICAL(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 14 | 15 | // Add/subtract (shifted register / extended register) 16 | archinst 17 | ADDSUB_SHIFTED(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 18 | archinst 19 | ADDSUB_EXTENDED(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 20 | 21 | // Data-processing (3 source) 22 | archinst 23 | DP_1_SRC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 24 | archinst 25 | DP_2_SRC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 26 | archinst 27 | DP_3_SRC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 28 | 29 | // Add/subtract (with carry) 30 | archinst 31 | ADDSUB_CARRY(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 32 | 33 | // Conditional compare (immediate / register) 34 | archinst 35 | CCMP(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 36 | 37 | // Conditional select 38 | archinst 39 | CSEL(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 40 | 41 | // Data-processing (1 source) 42 | archinst 43 | RBIT(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 44 | archinst 45 | REV(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 46 | archinst 47 | CL(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 48 | 49 | // Data-processing (2 sources) 50 | archinst 51 | DIV(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 52 | archinst 53 | SHIFT(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 54 | archinst 55 | CRC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 56 | 57 | } // namespace nDecoder 58 | 59 | #endif // FLEXUS_armDECODER_armDATAPROCREG_HPP_INCLUDED 60 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/PrefetchCommand.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__PREFETCHCOMMAND_HPP_INCLUDED 2 | #define FLEXUS_SLICES__PREFETCHCOMMAND_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Flexus { 9 | namespace SharedTypes { 10 | 11 | class PrefetchCommand : public boost::counted_base 12 | { 13 | typedef PhysicalMemoryAddress MemoryAddress; 14 | 15 | public: 16 | enum PrefetchCommandType 17 | { 18 | // This command tells the PrefetchListener to prefetch the specified 19 | // list of addresses. 20 | ePrefetchAddressList, 21 | 22 | ePrefetchRequestMoreAddresses 23 | 24 | }; 25 | 26 | private: 27 | PrefetchCommandType theType; 28 | std::list theAddressList; 29 | unsigned theSource; 30 | int32_t theQueue; 31 | int64_t theLocation; 32 | int64_t theTag; 33 | 34 | public: 35 | const PrefetchCommandType type() const { return theType; } 36 | PrefetchCommandType& type() { return theType; } 37 | 38 | std::list& addressList() { return theAddressList; } 39 | 40 | std::list const& addressList() const { return theAddressList; } 41 | 42 | unsigned& source() { return theSource; } 43 | 44 | int32_t queue() const { return theQueue; } 45 | 46 | int32_t& queue() { return theQueue; } 47 | 48 | unsigned source() const { return theSource; } 49 | 50 | int64_t& location() { return theLocation; } 51 | 52 | int64_t location() const { return theLocation; } 53 | 54 | int64_t& tag() { return theTag; } 55 | 56 | int64_t tag() const { return theTag; } 57 | 58 | explicit PrefetchCommand(PrefetchCommandType aType) 59 | : theType(aType) 60 | , theSource(0) 61 | , theQueue(0) 62 | , theLocation(-1) 63 | , theTag(-1) 64 | { 65 | } 66 | 67 | friend std::ostream& operator<<(std::ostream& s, PrefetchCommand const& aMsg); 68 | }; 69 | 70 | } // namespace SharedTypes 71 | } // namespace Flexus 72 | 73 | #endif // FLEXUS_SLICES__PREFETCHCOMMAND_HPP_INCLUDED 74 | -------------------------------------------------------------------------------- /components/NetShim/netnode.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _NS_NETNODE_HPP_ 3 | #define _NS_NETNODE_HPP_ 4 | 5 | #include "channel.hpp" 6 | 7 | namespace nNetShim { 8 | 9 | class NetContainer; 10 | 11 | class NetNode 12 | { 13 | public: 14 | NetNode(const int32_t nodeId_, NetContainer* nc_); 15 | 16 | public: 17 | bool addFromChannel(Channel* fromChan) { return fromChan->setFromPort(fromNodePort); } 18 | 19 | bool addToChannel(Channel* toChan) { return toChan->setToPort(toNodePort); } 20 | 21 | bool insertMessage(MessageState* msg) 22 | { 23 | TRACE(msg, 24 | "NetNode " << nodeId << " received message " 25 | << " to node " << msg->destNode << " with priority " << msg->priority); 26 | bool ret = fromNodePort->insertMessage(msg); 27 | TRACE(msg, "Returning from insertMessage"); 28 | return ret; 29 | } 30 | 31 | bool drive(void); 32 | 33 | bool driveInputPorts(void) { return toNodePort->drive(); } 34 | 35 | bool checkTopology(void) const; 36 | 37 | bool dumpState(ostream& out); 38 | 39 | // We want to closely monitor this statistic, to make sure the 40 | // buffers don't fill up too much in normal usage. 41 | // 42 | // This interface is left as future work, right now I'm going to assume 43 | // the queues don't get too big. 44 | // 45 | int32_t getInfiniteBufferUsed(void) const 46 | { 47 | int i, count = 0; 48 | 49 | for (i = 0; i < MAX_NET_VC; i++) 50 | count += fromNodePort->getBuffersUsed(); 51 | 52 | return count; 53 | } 54 | 55 | bool isOutputAvailable(const int32_t vc) { return fromNodePort->hasBufferSpace(vc); } 56 | 57 | bool notifyWaitingMessage(void) 58 | { 59 | messagesWaiting++; 60 | return false; 61 | } 62 | 63 | protected: 64 | int32_t nodeId; 65 | 66 | NetContainer* nc; 67 | 68 | ChannelOutputPort* fromNodePort; 69 | ChannelInputPort* toNodePort; 70 | 71 | int32_t messagesWaiting; 72 | }; 73 | 74 | typedef NetNode* NetNodeP; 75 | } // namespace nNetShim 76 | 77 | #endif /* _NS_NETNODE_HPP_ */ 78 | -------------------------------------------------------------------------------- /components/Decoder/encodings/Encodings.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Encodings.hpp" 3 | 4 | #include "Unallocated.hpp" 5 | 6 | namespace nDecoder { 7 | 8 | /* C3.1 A64 instruction index by encoding */ 9 | archinst 10 | disas_a64_insn(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo, int32_t aUop, bool &aLastUop) 11 | { 12 | if (aFetchedOpcode.theOpcode == 1) { // instruction fetch page fault 13 | return blackBox(aFetchedOpcode, aCPU, aSequenceNo); 14 | } 15 | DECODER_DBG("#" << aSequenceNo << ": opcode = " << std::hex << aFetchedOpcode.theOpcode << std::dec); 16 | 17 | switch (extract32(aFetchedOpcode.theOpcode, 25, 4)) { 18 | case 0x0: 19 | case 0x1: 20 | case 0x2: 21 | case 0x3: /* UNALLOCATED */ return unallocated_encoding(aFetchedOpcode, aCPU, aSequenceNo); 22 | case 0x8: 23 | case 0x9: /* Data processing - immediate */ return disas_data_proc_imm(aFetchedOpcode, aCPU, aSequenceNo); 24 | case 0xa: 25 | case 0xb: /* Branch, exception generation and system insns */ 26 | return disas_b_exc_sys(aFetchedOpcode, aCPU, aSequenceNo); 27 | case 0x4: 28 | case 0x6: 29 | case 0xc: 30 | case 0xe: /* Loads and stores */ return disas_ldst(aFetchedOpcode, aCPU, aSequenceNo, aUop, aLastUop); 31 | case 0x5: 32 | case 0xd: /* Data processing - register */ return disas_data_proc_reg(aFetchedOpcode, aCPU, aSequenceNo); 33 | case 0x7: 34 | case 0xf: /* Data processing - SIMD and floating point */ 35 | return disas_data_proc_simd_fp(aFetchedOpcode, aCPU, aSequenceNo); 36 | default: 37 | DBG_Assert(false, (<< "DECODER: unhandled decoding case!")); /* all 15 cases should 38 | be handled above */ 39 | break; 40 | } 41 | DBG_Assert(false, (<< "DECODER: unhandled decoding case!")); /* all 15 cases should 42 | be handled above */ 43 | return blackBox(aFetchedOpcode, aCPU, aSequenceNo); 44 | } 45 | 46 | } // namespace nDecoder -------------------------------------------------------------------------------- /components/uArch/CoreModel/FPStatRegisters.hpp: -------------------------------------------------------------------------------- 1 | // 2 | #pragma once 3 | 4 | /* Author: @msutherl 5 | * - Implementation of the Arm FPSRs (FPSR and FPCR). 6 | * These are read/reset by QEMU on resync, and then can be mapped to a phys 7 | * register whenever an FP instruction uses them. 8 | * - References: 9 | * ARMv8 FPCR/SR status register description - Section C5.2.7/8 of ISA Manual 10 | * (on /home/parsacom/docs/qflex/arm_isa_reference_manual). 11 | */ 12 | 13 | #include "components/Decoder/BitManip.hpp" 14 | 15 | /* Bit flags/definitions for all fields in FPSR 16 | */ 17 | #define FPSR_N (1 << 31) 18 | #define FPSR_Z (1 << 30) 19 | #define FPSR_C (1 << 29) 20 | #define FPSR_V (1 << 28) 21 | #define FPSR_QC (1 << 27) 22 | #define FPSR_IDC (1 << 7) 23 | #define FPSR_IXC (1 << 4) 24 | #define FPSR_UFC (1 << 3) 25 | #define FPSR_OFC (1 << 2) 26 | #define FPSR_DZC (1 << 1) 27 | #define FPSR_IOC (1) 28 | 29 | /* Bit flags/definitions for all fields in FPCR 30 | */ 31 | #define FPCR_AHP (1 << 26) 32 | #define FPCR_DN (1 << 25) 33 | #define FPCR_FZ (1 << 24) 34 | #define FPCR_RMODE ((1ULL << 23) | (1ULL << 22)) 35 | #define FPCR_STRIDE ((1ULL << 21) | (1ULL << 20)) 36 | #define FPCR_FZ16 (1 << 19) 37 | #define FPCR_LEN ((1ULL << 18) | (1ULL << 17) | (1ULL << 16)) 38 | #define FPCR_IDE (1 << 15) 39 | #define FPCR_IXE (1 << 12) 40 | #define FPCR_UFE (1 << 11) 41 | #define FPCR_OFE (1 << 10) 42 | #define FPCR_DZE (1 << 9) 43 | #define FPCR_IOE (1 << 8) 44 | 45 | // using namespace nuArch; 46 | 47 | class CImpl_FPSR 48 | { 49 | public: 50 | CImpl_FPSR() { theVal = 0; } 51 | 52 | CImpl_FPSR(uint64_t src) { theVal = src; } 53 | 54 | const uint64_t get(void) const { return theVal; } 55 | 56 | void set(uint64_t aNewVal) { theVal = aNewVal; } 57 | 58 | private: 59 | uint64_t theVal; 60 | }; 61 | 62 | class CImpl_FPCR 63 | { 64 | public: 65 | CImpl_FPCR() { theVal = 0; } 66 | 67 | CImpl_FPCR(uint64_t src) { theVal = src; } 68 | 69 | const uint64_t get(void) const { return theVal; } 70 | 71 | void set(uint64_t aNewVal) { theVal = aNewVal; } 72 | 73 | private: 74 | uint64_t theVal; 75 | }; -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/DirectoryMessage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES__DIRECTORY_MESSAGE_HPP_INCLUDED 2 | #define FLEXUS_SLICES__DIRECTORY_MESSAGE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define FLEXUS_DirectoryMessage_TYPE_PROVIDED 9 | 10 | namespace Flexus { 11 | namespace SharedTypes { 12 | 13 | typedef Flexus::SharedTypes::PhysicalMemoryAddress DirectoryAddress; 14 | namespace DirectoryCommand { 15 | enum DirectoryCommand 16 | { 17 | Get, 18 | Found, 19 | Set, 20 | // Saved, 21 | Lock, 22 | Acquired, 23 | Unlock, 24 | // Released, 25 | Squash 26 | }; 27 | } 28 | namespace { 29 | const char* DirectoryCommandStr[] = { "GetEntry", 30 | "EntryRetrieved", 31 | "SetEntry", 32 | //"EntryCommitted", 33 | "LockRequest", 34 | "LockAcquired", 35 | "UnlockRequest", 36 | //"LockReleased", 37 | "SquashPending" }; 38 | } 39 | 40 | struct DirectoryMessage : public boost::counted_base 41 | { 42 | DirectoryMessage(DirectoryCommand::DirectoryCommand anOp) 43 | : op(anOp) 44 | , addr(0) 45 | { 46 | } 47 | DirectoryMessage(DirectoryCommand::DirectoryCommand anOp, DirectoryAddress anAddr) 48 | : op(anOp) 49 | , addr(anAddr) 50 | { 51 | } 52 | DirectoryMessage(const DirectoryMessage& oldMsg) 53 | : op(oldMsg.op) 54 | , addr(oldMsg.addr) 55 | { 56 | } 57 | 58 | DirectoryCommand::DirectoryCommand op; 59 | DirectoryAddress addr; 60 | }; 61 | 62 | inline std::ostream& 63 | operator<<(std::ostream& aStream, const DirectoryMessage& msg) 64 | { 65 | aStream << "DirMsg: op=" << DirectoryCommandStr[msg.op] << " addr=" << &std::hex << msg.addr << &std::dec; 66 | return aStream; 67 | } 68 | 69 | } // namespace SharedTypes 70 | } // namespace Flexus 71 | 72 | #endif // FLEXUS_COMMON_MEMORYMESSAGE_HPP_INCLUDED 73 | -------------------------------------------------------------------------------- /components/CMPCache/AbstractRegionDirectory.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __ABSTRACT_REGION_DIRECTORY_HPP__ 3 | #define __ABSTRACT_REGION_DIRECTORY_HPP__ 4 | 5 | #include 6 | #include 7 | 8 | namespace nCMPCache { 9 | 10 | template 11 | class AbstractRegionLookupResult : public AbstractLookupResult<_State> 12 | { 13 | public: 14 | virtual ~AbstractRegionLookupResult() {} 15 | virtual int32_t owner() const = 0; 16 | 17 | virtual const _State& regionState(int32_t i) const = 0; 18 | virtual const std::vector<_State>& regionState() const = 0; 19 | 20 | virtual MemoryAddress regionTag() const = 0; 21 | 22 | virtual void setRegionOwner(int32_t new_owner) = 0; 23 | virtual void setRegionState(const std::vector<_State>& new_state) = 0; 24 | virtual void setRegionSharerState(int32_t sharer, 25 | boost::dynamic_bitset& presence, 26 | boost::dynamic_bitset& exclusive) = 0; 27 | 28 | virtual bool emptyRegion() = 0; 29 | }; 30 | 31 | template 32 | class AbstractRegionEvictBuffer : public DirEvictBuffer<_State> 33 | { 34 | public: 35 | AbstractRegionEvictBuffer(int32_t size) 36 | : DirEvictBuffer<_State>(size) 37 | { 38 | } 39 | virtual ~AbstractRegionEvictBuffer() {} 40 | }; 41 | 42 | template 43 | class AbstractRegionDirectory : public AbstractDirectory<_State, _EState> 44 | { 45 | public: 46 | virtual ~AbstractRegionDirectory() {} 47 | 48 | typedef AbstractRegionLookupResult<_State> RegLookupResult; 49 | typedef typename boost::intrusive_ptr RegLookupResult_p; 50 | 51 | virtual RegLookupResult_p nativeLookup(MemoryAddress address) = 0; 52 | virtual AbstractRegionEvictBuffer<_EState>* getRegionEvictBuffer() = 0; 53 | 54 | virtual int32_t blocksPerRegion() = 0; 55 | virtual MemoryAddress getRegion(MemoryAddress addr) = 0; 56 | }; 57 | 58 | }; // namespace nCMPCache 59 | 60 | #endif // __ABSTRACT_REGION_DIRECTORY_HPP__ 61 | -------------------------------------------------------------------------------- /core/debug/control.hpp: -------------------------------------------------------------------------------- 1 | #if defined(DBG_NewCategories) 2 | #error "DBG_NewCategories has been replaced with DBG_DefineCategories" 3 | #endif 4 | 5 | #if defined(DBG_SetCompileTimeMinSev) 6 | 7 | #undef DBG__internal_tmp_MinimumSeverity 8 | #define DBG__internal_tmp_MinimumSeverity \ 9 | BOOST_PP_CAT(DBG__Undefined_Severity_Level__, DBG_SetCompileTimeMinSev) \ 10 | (DBG_internal_Sev_to_int)(DBG_SetCompileTimeMinSev) /**/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #undef DBG_SetCompileTimeMinSev 23 | 24 | #endif // DBG_SetCompileTimeMinSev 25 | 26 | #if defined(DBG_SetInitialRuntimeMinSev) 27 | #ifdef DBG__internal_GlobalRunTimeMinSev_SET 28 | #error "Runtime global minimum severity may only be set once" 29 | #else 30 | #define DBG__internal_GlobalRunTimeMinSev_SET 31 | #endif 32 | 33 | #include 34 | 35 | #undef DBG_SetInitialRuntimeMinSev 36 | 37 | #endif // DBG_SetGlobalRunTimeMinSev 38 | 39 | #if defined(DBG_DefineCategories) 40 | 41 | #include 42 | #undef DBG_DefineCategories 43 | 44 | #endif // DBG_NewCategories 45 | 46 | #if defined(DBG_DeclareCategories) 47 | 48 | #include 49 | #undef DBG_DeclareCategories 50 | 51 | #endif // DBG_DeclareCategories 52 | 53 | #if defined(DBG_SetAssertions) 54 | 55 | #include 56 | #undef DBG_SetAssertions 57 | 58 | #endif // DBG_SetMinimumSeverity 59 | 60 | #if defined(DBG_SetDefaultOps) 61 | 62 | #include 63 | 64 | #endif // DBG_SetDefaultOps 65 | 66 | #if defined(DBG_Reset) 67 | 68 | #undef DBG_Reset 69 | #include 70 | 71 | #endif // DBG_SetDefaultOps 72 | -------------------------------------------------------------------------------- /core/aux_/layout/begin_comp_wiring_sec.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__CORE_TEST 2 | 3 | #ifdef FLEXUS__LAYOUT_COMPONENTS_WIRED 4 | #error "Wiring.cpp may contain only one component wiring section" 5 | #endif // FLEXUS__LAYOUT_COMPONENTS_WIRED 6 | 7 | #ifndef FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 8 | #error "The component wiring section of wiring.cpp must follow the component instantiation section" 9 | #endif // FLEXUS__LAYOUT_COMPONENTS_INSTANTIATED 10 | 11 | #ifdef FLEXUS__LAYOUT_IN_SECTION 12 | #error "Previous wiring.cpp section is missing the end of section #include" 13 | #endif // FLEXUS__LAYOUT_IN_SECTION 14 | 15 | #define FLEXUS__LAYOUT_IN_SECTION 16 | #define FLEXUS__LAYOUT_COMPONENT_WIRING_SECTION 17 | 18 | #endif // FLEXUS__CORE_TEST 19 | 20 | #ifdef FLEXUS__CORE_TEST 21 | #define nFLEXUS FLEXUS__CORE_TEST 22 | #else 23 | #define nFLEXUS Flexus 24 | #endif // FLEXUS__CORE_TEST 25 | 26 | namespace nFLEXUS { 27 | namespace Wiring { 28 | 29 | #define WIRE(FromInstance, FromPort, ToInstance, ToPort) \ 30 | BOOST_PP_CAT(FromInstance, _instance).theJumpTable.BOOST_PP_CAT(wire_available_, FromPort) = \ 31 | &resolve_channel::invoke_available; \ 35 | BOOST_PP_CAT(FromInstance, _instance).theJumpTable.BOOST_PP_CAT(wire_manip_, FromPort) = \ 36 | &resolve_channel::invoke_manip; /**/ 40 | 41 | void 42 | connectWiring() 43 | { 44 | -------------------------------------------------------------------------------- /components/BranchPredictor/BTBSet.cpp: -------------------------------------------------------------------------------- 1 | #include "BTBSet.hpp" 2 | 3 | #include "core/types.hpp" 4 | 5 | #include 6 | 7 | using namespace Flexus::SharedTypes; 8 | 9 | BTBSet::BTBSet() 10 | : blocks(64) 11 | , replacementQueue(64, 0) 12 | { 13 | } 14 | 15 | BTBSet::BTBSet(uint32_t associativity) 16 | : blocks(associativity, BTBEntry()) 17 | , replacementQueue(associativity) 18 | { 19 | for (uint32_t i = 0; i < associativity; ++i) { 20 | replacementQueue[i] = i; 21 | } 22 | } 23 | 24 | void 25 | BTBSet::updateReplacementQueue(uint32_t index) 26 | { 27 | for (auto i = replacementQueue.begin(); i != replacementQueue.end(); ++i) 28 | if (*i == index) { 29 | replacementQueue.erase(i); 30 | break; 31 | } 32 | 33 | replacementQueue.push_back(index); 34 | } 35 | 36 | bool 37 | BTBSet::isHit(VirtualMemoryAddress anAddress) 38 | { 39 | for (uint32_t i = 0; i < blocks.size(); ++i) { 40 | if (blocks[i].thePC == anAddress && blocks[i].valid) { return true; } 41 | } 42 | return false; 43 | } 44 | 45 | // [MADHUR] Return the Hit BTB entry 46 | BTBEntry* 47 | BTBSet::access(VirtualMemoryAddress anAddress) 48 | { 49 | for (uint32_t i = 0; i < blocks.size(); ++i) { 50 | if (blocks[i].thePC == anAddress && blocks[i].valid) { 51 | updateReplacementQueue(i); 52 | return &blocks[i]; 53 | } 54 | } 55 | 56 | return NULL; 57 | } 58 | 59 | // [MADHUR] Insert a new BTB Entry 60 | void 61 | BTBSet::insert(BTBEntry btbEntry) 62 | { 63 | for (uint32_t i = 0; i < blocks.size(); ++i) { 64 | if (!blocks[i].valid) { 65 | blocks[i] = btbEntry; 66 | updateReplacementQueue(i); 67 | return; 68 | } 69 | } 70 | 71 | uint32_t index = replacementQueue.front(); 72 | blocks[index] = btbEntry; 73 | updateReplacementQueue(index); 74 | } 75 | 76 | // [MADHUR] Invalidate entry if present 77 | void 78 | BTBSet::invalidate(VirtualMemoryAddress anAddress) 79 | { 80 | for (auto& block : blocks) { 81 | if (block.thePC == anAddress && block.valid) block.valid = false; 82 | } 83 | } 84 | 85 | void 86 | BTBSet::invalidateAll() 87 | { 88 | 89 | for (auto& block : blocks) { 90 | block.valid = false; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/ReadPCAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | namespace ll = boost::lambda; 9 | 10 | #include "../Effects.hpp" 11 | #include "../SemanticActions.hpp" 12 | #include "../SemanticInstruction.hpp" 13 | #include "PredicatedSemanticAction.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define DBG_DeclareCategories Decoder 23 | #define DBG_SetDefaultOps AddCat(Decoder) 24 | #include DBG_Control() 25 | 26 | namespace nDecoder { 27 | 28 | using namespace nuArch; 29 | 30 | static const bits kAM = 0x8; 31 | 32 | struct ReadPCAction : public PredicatedSemanticAction 33 | { 34 | eOperandCode theResult; 35 | 36 | ReadPCAction(SemanticInstruction* anInstruction, eOperandCode aResult) 37 | : PredicatedSemanticAction(anInstruction, 1, true) 38 | , theResult(aResult) 39 | { 40 | setReady(0, true); 41 | } 42 | 43 | void doEvaluate() 44 | { 45 | // bits pstate = theInstruction->core()->getPSTATE() ; 46 | // if (pstate & kAM ) { 47 | // //Need to mask upper 32 bits when AM is set 48 | // theInstruction->setOperand(theResult, 49 | // static_cast(theInstruction->pc()) & 0xFFFFFFFFULL); 50 | 51 | // } else { 52 | uint64_t pc = theInstruction->pc(); 53 | theInstruction->setOperand(theResult, (bits)pc); 54 | // } 55 | DBG_(VVerb, (<< *this << " read PC")); 56 | satisfyDependants(); 57 | } 58 | 59 | void describe(std::ostream& anOstream) const 60 | { 61 | anOstream << theInstruction->identify() << " Read PC store in " << theResult; 62 | } 63 | }; 64 | 65 | predicated_action 66 | readPCAction(SemanticInstruction* anInstruction) 67 | { 68 | ReadPCAction* act = new ReadPCAction(anInstruction, kResult); 69 | anInstruction->addNewComponent(act); 70 | 71 | return predicated_action(act, act->predicate()); 72 | } 73 | 74 | } // namespace nDecoder 75 | -------------------------------------------------------------------------------- /components/Decoder/encodings/Branch.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_armDECODER_armBRANCH_HPP_INCLUDED 3 | #define FLEXUS_armDECODER_armBRANCH_HPP_INCLUDED 4 | 5 | #include "SharedFunctions.hpp" 6 | 7 | namespace nDecoder { 8 | 9 | // Unconditional branch (immediate) 10 | archinst 11 | UNCONDBR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 12 | 13 | // Unconditional branch (register) 14 | archinst 15 | BR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 16 | archinst 17 | BLR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 18 | archinst 19 | RET(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 20 | archinst 21 | ERET(archcode const& aFetchedOpcode, 22 | uint32_t aCPU, 23 | int64_t aSequenceNo); // TODO 24 | archinst 25 | DPRS(archcode const& aFetchedOpcode, 26 | uint32_t aCPU, 27 | int64_t aSequenceNo); // TODO 28 | 29 | // Compare and branch (immediate) 30 | archinst 31 | CMPBR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 32 | 33 | // Test and branch (immediate) 34 | archinst 35 | TSTBR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 36 | 37 | // Conditional branch (immediate) 38 | archinst 39 | CONDBR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 40 | 41 | // System TODO 42 | archinst 43 | HINT(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 44 | archinst 45 | SYNC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 46 | archinst 47 | MSR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 48 | archinst 49 | SYS(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 50 | 51 | // Exception generation TODO 52 | archinst 53 | SVC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 54 | archinst 55 | HVC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 56 | archinst 57 | SMC(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 58 | archinst 59 | BRK(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 60 | archinst 61 | HLT(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 62 | archinst 63 | DCPS(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 64 | 65 | } // namespace nDecoder 66 | #endif // FLEXUS_armDECODER_armBRANCH_HPP_INCLUDED -------------------------------------------------------------------------------- /components/MMU/TTResolvers.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _ARM_TT_RESOLVERS_DEFINED_HPP_ 3 | #define _ARM_TT_RESOLVERS_DEFINED_HPP_ 4 | #include "MMUUtil.hpp" 5 | #include "TranslationGranules.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace nMMU { 11 | 12 | typedef std::shared_ptr _TTResolver_Shptr_T; 13 | typedef uint64_t address_t; 14 | 15 | /* Used for dealing with all varying address widths and granules, figures out 16 | * which bits to get and index and discard. 17 | */ 18 | class TTResolver 19 | { 20 | public: 21 | TTResolver(bool abro, _TTResolver_Shptr_T aGranule, address_t aTTBR, uint8_t PAddrWidth); 22 | virtual address_t resolve(address_t inputAddress); 23 | virtual address_t getBlockOutputBits(address_t rawTTEFromPhysMemory); 24 | void updateRawBaseRegister(address_t newTTBR); 25 | 26 | protected: 27 | // for going through the TT 28 | bool isBR0; 29 | address_t RawTTBRReg; 30 | uint8_t TTBR_LSB; 31 | uint8_t TTBR_MSB; 32 | uint8_t offset_LSB; 33 | uint8_t offset_MSB; 34 | uint8_t IAddressWidth; 35 | uint8_t PAddressWidth; 36 | uint8_t TnSz; 37 | address_t descriptorIndex; 38 | 39 | // for setting input-output bits dependent on TG size 40 | _TTResolver_Shptr_T regimeTG; 41 | 42 | // utility 43 | address_t maskAndShiftInputAddress(address_t anAddr); 44 | }; 45 | 46 | class L0Resolver : public TTResolver 47 | { 48 | public: 49 | L0Resolver(bool abro, _TTResolver_Shptr_T aGranule, address_t tbr, uint8_t aPAW); 50 | address_t getBlockOutputBits(address_t rawTTEFromPhysMemory); 51 | }; 52 | class L1Resolver : public TTResolver 53 | { 54 | public: 55 | L1Resolver(bool abro, _TTResolver_Shptr_T aGranule, address_t attbr, uint8_t aPAW); 56 | address_t getBlockOutputBits(address_t rawTTEFromPhysMemory); 57 | }; 58 | class L2Resolver : public TTResolver 59 | { 60 | public: 61 | L2Resolver(bool abro, _TTResolver_Shptr_T aGranule, address_t attbr, uint8_t aPAW); 62 | address_t getBlockOutputBits(address_t rawTTEFromPhysMemory); 63 | }; 64 | class L3Resolver : public TTResolver 65 | { 66 | public: 67 | L3Resolver(bool abro, _TTResolver_Shptr_T aGranule, address_t attbr, uint8_t aPAW); 68 | address_t getBlockOutputBits(address_t rawTTEFromPhysMemory); 69 | }; 70 | 71 | } // namespace nMMU 72 | #endif // _ARM_TT_RESOLVERS_DEFINED_HPP_ -------------------------------------------------------------------------------- /components/Decoder/encodings/LoadStore.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FLEXUS_armDECODER_armLOADSTORE_HPP_INCLUDED 3 | #define FLEXUS_armDECODER_armLOADSTORE_HPP_INCLUDED 4 | 5 | #include "SharedFunctions.hpp" 6 | 7 | namespace nDecoder { 8 | 9 | // Load/store exclusive 10 | // archinst CASP(archcode const & aFetchedOpcode, uint32_t aCPU, int64_t 11 | // aSequenceNo); 12 | archinst 13 | CAS(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 14 | archinst 15 | STXR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 16 | archinst 17 | STRL(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 18 | archinst 19 | LDAQ(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 20 | archinst 21 | LDXR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 22 | 23 | // Load register (literal) 24 | archinst 25 | LDR_lit(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 26 | 27 | // Load/store pair (all forms) 28 | archinst 29 | LDP(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo, int32_t aUop); 30 | archinst 31 | STP(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo, int32_t aUop); 32 | 33 | /* Load/store register (all forms) */ 34 | archinst 35 | LDR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 36 | archinst 37 | STR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 38 | 39 | /* atomic memory operations */ // TODO 40 | archinst 41 | LDADD(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 42 | archinst 43 | LDCLR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 44 | archinst 45 | LDEOR(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 46 | archinst 47 | LDSET(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 48 | archinst 49 | LDSMAX(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 50 | archinst 51 | LDSMIN(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 52 | archinst 53 | LDUMAX(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 54 | archinst 55 | LDUMIN(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 56 | archinst 57 | SWP(archcode const& aFetchedOpcode, uint32_t aCPU, int64_t aSequenceNo); 58 | 59 | } // namespace nDecoder 60 | 61 | #endif // FLEXUS_armDECODER_armLOADSTORE_HPP_INCLUDED -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/ReadNZCVAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace ll = boost::lambda; 10 | 11 | #include "../Effects.hpp" 12 | #include "../SemanticActions.hpp" 13 | #include "../SemanticInstruction.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define DBG_DeclareCategories Decoder 24 | #define DBG_SetDefaultOps AddCat(Decoder) 25 | #include DBG_Control() 26 | 27 | namespace nDecoder { 28 | 29 | using namespace nuArch; 30 | 31 | struct ReadNZCVAction : public BaseSemanticAction 32 | { 33 | eOperandCode theOperandCode; 34 | eNZCV theBit; 35 | 36 | ReadNZCVAction(SemanticInstruction* anInstruction, eNZCV aBit, eOperandCode anOperandCode) 37 | : BaseSemanticAction(anInstruction, 1) 38 | , theOperandCode(anOperandCode) 39 | , theBit(aBit) 40 | { 41 | } 42 | 43 | void doEvaluate() 44 | { 45 | 46 | SEMANTICS_DBG(*this); 47 | bits nzcv_bit; 48 | 49 | switch (theBit) { 50 | case kN: nzcv_bit = theInstruction->core()->_PSTATE().N(); break; 51 | case kZ: nzcv_bit = theInstruction->core()->_PSTATE().Z(); break; 52 | case kC: nzcv_bit = theInstruction->core()->_PSTATE().C(); break; 53 | case kV: nzcv_bit = theInstruction->core()->_PSTATE().V(); break; 54 | default: DBG_Assert(false); 55 | } 56 | 57 | theInstruction->setOperand(theOperandCode, nzcv_bit); 58 | satisfyDependants(); 59 | } 60 | 61 | void describe(std::ostream& anOstream) const { anOstream << theInstruction->identify() << " ReadNZCVAction "; } 62 | }; 63 | 64 | simple_action 65 | readNZCVAction(SemanticInstruction* anInstruction, eNZCV aBit, eOperandCode anOperandCode) 66 | { 67 | ReadNZCVAction* act = new ReadNZCVAction(anInstruction, aBit, anOperandCode); 68 | anInstruction->addNewComponent(act); 69 | return simple_action(act); 70 | } 71 | 72 | } // namespace nDecoder 73 | -------------------------------------------------------------------------------- /components/PhantomCPU/PhantomCPU.cpp: -------------------------------------------------------------------------------- 1 | #include "core/component.hpp" 2 | #include "core/flexus.hpp" 3 | #include "core/types.hpp" 4 | #include 5 | 6 | #define FLEXUS_BEGIN_COMPONENT PhantomCPU 7 | #include FLEXUS_BEGIN_COMPONENT_IMPLEMENTATION() 8 | 9 | #include "core/qemu/configuration_api.hpp" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace Stat = Flexus::Stat; 19 | 20 | #define DBG_DefineCategories PhantomCPU 21 | #define DBG_SetDefaultOps AddCat(PhantomCPU) 22 | #include DBG_Control() 23 | 24 | namespace nphatromCPU { 25 | 26 | class FLEXUS_COMPONENT(PhantomCPU) 27 | { 28 | FLEXUS_COMPONENT_IMPL(PhantomCPU); 29 | 30 | private: 31 | Flexus::Qemu::Processor theCPU; 32 | uint64_t theCPUIndex; 33 | 34 | Stat::StatCounter theCommitCount; 35 | 36 | public: 37 | FLEXUS_COMPONENT_CONSTRUCTOR(PhantomCPU) 38 | : base(FLEXUS_PASS_CONSTRUCTOR_ARGS), 39 | theCPU(), 40 | theCPUIndex(0), 41 | theCommitCount(std::string("Phantom-") + std::to_string(flexusIndex()) + std::string("-CommitCount")) 42 | { 43 | } 44 | 45 | bool isQuiesced() const { return true; } 46 | 47 | void initialize() { 48 | uint64_t cpu_index = flexusIndex() + Flexus::Core::ComponentManager::getComponentManager().systemWidth(); 49 | 50 | theCPU = Flexus::Qemu::Processor::getProcessor(cpu_index); 51 | theCPUIndex = cpu_index; 52 | } 53 | 54 | void finalize() {} 55 | 56 | public: 57 | void drive(interface::PhantomDrive const&) { doCycle(); } 58 | 59 | private: 60 | void doCycle() { 61 | // 1. advance the CPU by the estimated IPC. 62 | for(std::size_t i = 0; i < cfg.EstimatedIPC; i++) { 63 | uint64_t return_value = theCPU.advance(); 64 | if(return_value != 0x10003){ 65 | ++theCommitCount; 66 | } 67 | } 68 | } 69 | }; 70 | 71 | } // End namespace nPhantomCPU 72 | 73 | FLEXUS_COMPONENT_INSTANTIATOR(PhantomCPU, nphatromCPU); 74 | 75 | #include FLEXUS_END_COMPONENT_IMPLEMENTATION() 76 | #define FLEXUS_END_COMPONENT PhantomCPU 77 | 78 | #define DBG_Reset 79 | #include DBG_Control() 80 | -------------------------------------------------------------------------------- /components/CommonQEMU/Slices/AbstractInstruction.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS_SLICES_ABSTRACTINSTRUCTION_HPP_INCLUDED 2 | #define FLEXUS_SLICES_ABSTRACTINSTRUCTION_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Flexus { 10 | namespace SharedTypes { 11 | 12 | struct AbstractInstruction : public boost::counted_base 13 | { 14 | boost::intrusive_ptr theFetchTransaction; 15 | 16 | protected: 17 | tFillLevel theInsnSourceLevel; 18 | bool theExclusive; 19 | 20 | public: 21 | 22 | bool theUnprivAccess; 23 | virtual void setUnprivAccess() { theUnprivAccess = true; } 24 | virtual bool unprivAccess() const { return theUnprivAccess; } 25 | 26 | virtual bool isExclusive() const { return theExclusive; } 27 | virtual void setExclusive() { theExclusive = true; } 28 | virtual void describe(std::ostream& anOstream) const; 29 | virtual bool resync() const = 0; 30 | virtual void forceResync(bool r = true) = 0; 31 | virtual bool haltDispatch() const; 32 | virtual void setFetchTransactionTracker(boost::intrusive_ptr aTransaction) 33 | { 34 | theFetchTransaction = aTransaction; 35 | } 36 | virtual boost::intrusive_ptr getFetchTransactionTracker() const { return theFetchTransaction; } 37 | AbstractInstruction() 38 | : theInsnSourceLevel(eL1I) 39 | , theExclusive(false) 40 | , theUnprivAccess(false) 41 | { 42 | } 43 | virtual ~AbstractInstruction() {} 44 | 45 | virtual void setSourceLevel(tFillLevel aLevel) { theInsnSourceLevel = aLevel; } 46 | virtual tFillLevel sourceLevel() const { return theInsnSourceLevel; } 47 | virtual uint32_t getOpcode() = 0; 48 | }; 49 | 50 | enum eSquashCause 51 | { 52 | kResynchronize = 1, 53 | kBranchMispredict = 2, 54 | kException = 3, 55 | kInterrupt = 4, 56 | kFailedSpec = 5 57 | }; 58 | 59 | std::ostream& 60 | operator<<(std::ostream& anOstream, eSquashCause aCause); 61 | 62 | std::ostream& 63 | operator<<(std::ostream& anOstream, AbstractInstruction const& anInstruction); 64 | 65 | } // namespace SharedTypes 66 | } // namespace Flexus 67 | 68 | #endif // FLEXUS_SLICES_ABSTRACTINSTRUCTION_HPP_INCLUDED -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/InvertAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | namespace ll = boost::lambda; 10 | 11 | #include "../Effects.hpp" 12 | #include "../SemanticActions.hpp" 13 | #include "../SemanticInstruction.hpp" 14 | #include "PredicatedSemanticAction.hpp" 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define DBG_DeclareCategories Decoder 24 | #define DBG_SetDefaultOps AddCat(Decoder) 25 | #include DBG_Control() 26 | 27 | namespace nDecoder { 28 | 29 | using namespace nuArch; 30 | 31 | struct InvertAction : public PredicatedSemanticAction 32 | { 33 | eOperandCode theRegisterCode; 34 | bool the64; 35 | 36 | InvertAction(SemanticInstruction* anInstruction, eOperandCode aRegisterCode, bool is64) 37 | : PredicatedSemanticAction(anInstruction, 1, true) 38 | , theRegisterCode(aRegisterCode) 39 | , the64(is64) 40 | { 41 | } 42 | 43 | void doEvaluate() 44 | { 45 | SEMANTICS_DBG(*this); 46 | 47 | if (!signalled()) { 48 | SEMANTICS_DBG("Signalling"); 49 | 50 | mapped_reg name = theInstruction->operand(theRegisterCode); 51 | Operand aValue = core()->readRegister(name); 52 | 53 | bits val = boost::get(aValue); 54 | val = ~val; 55 | 56 | if (!the64) { val &= 0xffffffff; } 57 | 58 | theInstruction->setOperand(theRegisterCode, val); 59 | satisfyDependants(); 60 | } 61 | } 62 | 63 | void describe(std::ostream& anOstream) const 64 | { 65 | anOstream << theInstruction->identify() << " InvertRegisterAction " << theRegisterCode; 66 | } 67 | }; 68 | 69 | predicated_action 70 | invertAction(SemanticInstruction* anInstruction, eOperandCode aRegisterCode, bool is64) 71 | { 72 | 73 | InvertAction* act = new InvertAction(anInstruction, aRegisterCode, is64); 74 | anInstruction->addNewComponent(act); 75 | return predicated_action(act, act->predicate()); 76 | } 77 | 78 | } // namespace nDecoder 79 | -------------------------------------------------------------------------------- /components/Decoder/SemanticActions/IncrementAction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace ll = boost::lambda; 11 | 12 | #include "../Effects.hpp" 13 | #include "../SemanticActions.hpp" 14 | #include "../SemanticInstruction.hpp" 15 | #include "PredicatedSemanticAction.hpp" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define DBG_DeclareCategories Decoder 25 | #define DBG_SetDefaultOps AddCat(Decoder) 26 | #include DBG_Control() 27 | 28 | namespace nDecoder { 29 | 30 | using namespace nuArch; 31 | 32 | struct IncrementAction : public PredicatedSemanticAction 33 | { 34 | eOperandCode theRegisterCode; 35 | bool the64; 36 | 37 | IncrementAction(SemanticInstruction* anInstruction, eOperandCode aRegisterCode, bool is64) 38 | : PredicatedSemanticAction(anInstruction, 1, true) 39 | , theRegisterCode(aRegisterCode) 40 | , the64(is64) 41 | { 42 | } 43 | 44 | void doEvaluate() 45 | { 46 | SEMANTICS_DBG(*this); 47 | 48 | if (!signalled()) { 49 | SEMANTICS_DBG("Signalling"); 50 | 51 | mapped_reg name = theInstruction->operand(theRegisterCode); 52 | Operand aValue = core()->readRegister(name); 53 | 54 | bits val = boost::get(aValue); 55 | val++; 56 | 57 | if (!the64) { val &= 0xffffffff; } 58 | 59 | theInstruction->setOperand(theRegisterCode, val); 60 | satisfyDependants(); 61 | } 62 | } 63 | 64 | void describe(std::ostream& anOstream) const 65 | { 66 | anOstream << theInstruction->identify() << " IncrementAction " << theRegisterCode; 67 | } 68 | }; 69 | 70 | predicated_action 71 | incrementAction(SemanticInstruction* anInstruction, eOperandCode aRegisterCode, bool is64) 72 | { 73 | IncrementAction* act = new IncrementAction(anInstruction, aRegisterCode, is64); 74 | anInstruction->addNewComponent(act); 75 | return predicated_action(act, act->predicate()); 76 | } 77 | 78 | } // namespace nDecoder 79 | -------------------------------------------------------------------------------- /core/component_interface.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLEXUS__COMPONENT_INTERFACE_HPP_INCLUDED 2 | #define FLEXUS__COMPONENT_INTERFACE_HPP_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | namespace Flexus { 8 | namespace Core { 9 | 10 | struct ComponentInterface 11 | { 12 | 13 | // This allows components to have push output ports 14 | template 15 | static Flexus::Core::aux_::port get_channel(Port const&, 16 | AvailableFn avail, 17 | ManipulateFn manip, 18 | Flexus::Core::index_t aComponentIndex) 19 | { 20 | return Flexus::Core::aux_::port(avail, manip, aComponentIndex); 21 | } 22 | 23 | template 24 | static Flexus::Core::aux_::port get_channel_array( 25 | Port const&, 26 | AvailableFn avail, 27 | ManipulateFn manip, 28 | Flexus::Core::index_t aComponentIndex, 29 | Flexus::Core::index_t aPortIndex, 30 | Flexus::Core::index_t aPortWidth) 31 | { 32 | 33 | DBG_Assert(aPortIndex < aPortWidth, (<< "PortIndex: " << aPortIndex << " Width: " << aPortWidth)); 34 | 35 | return Flexus::Core::aux_::port(avail, 36 | manip, 37 | aComponentIndex * aPortWidth + aPortIndex); 38 | } 39 | 40 | // All components must provide the following members 41 | virtual void initialize() = 0; 42 | // added by PLotfi 43 | virtual void finalize() = 0; 44 | // end PLotfi 45 | virtual bool isQuiesced() const = 0; 46 | virtual void saveState(std::string const& aDirectory) = 0; 47 | virtual void loadState(std::string const& aDirectory) = 0; 48 | virtual std::string name() const = 0; 49 | virtual ~ComponentInterface() {} 50 | }; 51 | 52 | } // namespace Core 53 | } // namespace Flexus 54 | 55 | #endif // FLEXUS__COMPONENT_INTERFACE_HPP_INCLUDED 56 | --------------------------------------------------------------------------------