2015/4/8 Function call sequence for gem5: system.py & simulate.py & simulate.cc SoC CAD 黃喬楷 Department of Electrical Engineering National Cheng Kung University Tainan, Taiwan, R.O.C 1 NCKU SoC CAD The figure below shows the function call sequence for the initialization of gem5 when running the "Hello, World" example. Initialization Function Call Sequence (1/2) Each node in the graph gives the path to the source code file in which the function is located. This representation should aid in the first steps of familiarization with the basic initialization steps of gem5, including how the configuration files are used and how the objects are constructed. Huang, Ciao Kai SoC & ASIC Lab 2 NCKU SoC CAD Initialization Function Call Sequence (2/2) ARM Huang, Ciao Kai function call sequence for gem5 ”Hello,World” example SoC & ASIC Lab 3 NCKU SoC CAD System.py (1/5) from m5.SimObject import SimObject from m5.defines import buildEnv from m5.params import * from m5.proxy import * from SimpleMemory import * class MemoryMode(Enum): vals = ['invalid', 'atomic', 'timing', 'atomic_noncaching'] class System(MemObject): type = 'System' cxx_header = "sim/system.hh" system_port = MasterPort("System port") memories = VectorParam.AbstractMemory(Self.all,"All memories in the system") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") # The memory ranges are to be populated when creating the system such that these can be passed # from the I/O subsystem through an I/O bridge or cache mem_ranges = VectorParam.AddrRange([], "Ranges that constitute main memory") cache_line_size = Param.Unsigned(64, "Cache line size in bytes") Huang, Ciao Kai SoC & ASIC Lab 4 NCKU SoC CAD System.py (2/5) work_item_id = Param.Int(-1, "specific work item id") num_work_ids = Param.Int(16, "Number of distinct work item types") work_begin_cpu_id_exit = Param.Int(-1,"work started on specific id, now exit simulation") work_begin_ckpt_count = Param.Counter(0,"create checkpoint when work items begin count value is reached") work_begin_exit_count = Param.Counter(0,"exit simulation when work items begin count value is reached") work_end_ckpt_count = Param.Counter(0,"create checkpoint when work items end count value is reached") work_end_exit_count = Param.Counter(0,"exit simulation when work items end count value is reached") work_cpus_ckpt_count = Param.Counter(0,"create checkpoint when active cpu count value is reached") init_param = Param.UInt64(0, "numerical value to pass into simulator") boot_osflags = Param.String("a", "boot flags to pass to the kernel") kernel = Param.String("", "file that contains the kernel code") readfile = Param.String("", "file to read startup script from") symbolfile = Param.String("", "file to get the symbols from") load_addr_mask = Param.UInt64(0xffffffffff,"Address to mask loading binaries with") load_offset = Param.UInt64(0, "Address to offset loading binaries with") Huang, Ciao Kai SoC & ASIC Lab 5 NCKU SoC CAD System.py (3/5) 由於開頭導入所有m5 package的 params module,可用params內定 義的函數成員。 在params module中定義了 Huang, Ciao Kai from m5.params import * SoC & ASIC Lab 6 NCKU SoC CAD System.py (4/5) Param = ParamFactory(ParamDesc) VectorParam = ParamFactory(VectorParamDesc) cache_line_size = Param.Unsigned(64, "Cache line size in bytes") class Unsigned(CheckedInt): cxx_type = 'unsigned'; size = 32; unsigned = True work_item_id = Param.Int(-1, "specific work item id") num_work_ids = Param.Int(16, "Number of distinct work item types") class Int(CheckedInt): cxx_type = 'int'; size = 32; unsigned = False work_begin_ckpt_count = Param.Counter(0,"create checkpoint when work items begin count value is reached") work_begin_exit_count = Param.Counter(0,"exit simulation when work items begin count value is reached") work_end_ckpt_count = Param.Counter(0,"create checkpoint when work items end count value is reached") work_end_exit_count = Param.Counter(0,"exit simulation when work items end count value is reached") class Counter(CheckedInt): cxx_type = 'Counter'; size = 64; unsigned = True Huang, Ciao Kai SoC & ASIC Lab 7 NCKU SoC CAD System.py (5/5) init_param = Param.UInt64(0, "numerical value to pass into simulator") load_addr_mask = Param.UInt64(0xffffffffff,"Address to mask loading binaries with") load_offset = Param.UInt64(0, "Address to offset loading binaries with") class UInt64(CheckedInt): cxx_type = 'uint64_t'; size = 64; unsigned = True boot_osflags = Param.String("a", "boot flags to pass to the kernel") kernel = Param.String("", "file that contains the kernel code") readfile = Param.String("", "file to read startup script from") symbolfile = Param.String("", "file to get the symbols from") Huang, Ciao Kai SoC & ASIC Lab 8 NCKU SoC CAD simulate.cc : simulate() (1/3) simulate(Tick num_cycles) { // The first time simulate() is called from the Python code, we need to create a thread for // each of event queues referenced by the instantiated sim objects. static bool threads_initialized = false; static std::vector<std::thread *> threads; if (!threads_initialized) { … … inform("Entering event queue @ %d. Starting simulation...\n", curTick()); if (num_cycles < MaxTick - curTick()) num_cycles = curTick() + num_cycles; else // counter would roll over or be set to MaxTick anyhow num_cycles = MaxTick; GlobalEvent *limit_event = new GlobalSimLoopExitEvent(num_cycles, "simulate() limit reached", 0, 0); GlobalSyncEvent *quantum_event = NULL; if (numMainEventQueues > 1) { … … Huang, Ciao Kai SoC & ASIC Lab 9 NCKU SoC CAD simulate.cc : simulate() (2/3) // all subordinate (created) threads should be waiting on the barrier; the arrival of the // main thread here will satisfy the barrier, and all threads will enter doSimLoop in parallel threadBarrier->wait(); Event *local_event = doSimLoop(mainEventQueue[0]); assert(local_event != NULL); inParallelMode = false; // locate the global exit event and return it to Python BaseGlobalEvent *global_event = local_event->globalEvent(); assert(global_event != NULL); GlobalSimLoopExitEvent *global_exit_event = dynamic_cast<GlobalSimLoopExitEvent *>(global_event); assert(global_exit_event != NULL); // if we didn't hit limit_event, delete it. if (global_exit_event != limit_event) { … … //! Delete the simulation quantum event. if (quantum_event != NULL) { … … } return global_exit_event; Huang, Ciao Kai SoC & ASIC Lab 10 NCKU SoC CAD simulate.cc : simulate() (3/3) Simulate for num_cycles additional cycles. If num_cycles is -1 (the default), do not limit simulation; some other event must terminate the loop. Exported to Python via SWIG. Returns:The SimLoopExitEvent that caused the loop to exit. Delete the simulation quantum event. Huang, Ciao Kai SoC & ASIC Lab 11 NCKU SoC CAD Simulate.py : instantiate() (1/2) def instantiate(ckpt_dir=None): from m5 import options root = objects.Root.getInstance() if not root: fatal("Need to instantiate Root() before calling instantiate()") # we need to fix the global frequency ticks.fixGlobalFrequency() # Make sure SimObject-valued params are in the configuration hierarchy so we catch # them with future descendants() walks for obj in root.descendants(): obj.adoptOrphanParams() # Check to see if any of the stat events are in the past after resuming from a checkpoint, # If so, this call will shift them to be at a valid time. updateStatEvents() # Reset to put the stats in a consistent state. stats.reset() Huang, Ciao Kai SoC & ASIC Lab 12 NCKU SoC CAD Simulate.py (2/2) 透過Root.py.cc得到程式中所見m5.objects.Root的檔案的絕對位置 為/home/asic/gem5/src/sim/Root.py root = objects.Root.getInstance() _the_instance = None #一開始為零根據實例所增加的類別進行擴增 def getInstance(cls): return Root._the_instance 透過gem5/src/Sconscript中定義了obj = sim_objects = m5.SimObject.allClasses 完成實例後重新設定狀態使其處於一致的狀態。 stats.reset() Huang, Ciao Kai SoC & ASIC Lab 13