The purpose of the gem5 components library is to provide gem5 users a standard set of common and useful gem5 components pre-built to add to their experiments. The gem5 components library adopts a modular architecture design with the goal of components being easy to add and remove from designs, and extendable as needed. E.g., any Memory system should be interchangable with any other, and if not a helpful error messages should be raised. Examples of using the gem5 components library can be found in `configs/example/components-library`. Important Disclaimer: This is a pre-alpha release of the gem5 components library. The purpose of this release is to get some community feedback on this new component of gem5. Though some testing has been done, we expect regular fixes and improvements until this is in a stable state. The components library has been formatted with Python Black; typing has been checked with MyPy; and the library has been tested with the scripts in `configs/example/components-libary`. More rigorous tests are to be added in future revisions. More detailed documentation will appear in future revisions. Jira Ticket outlining TODOs and known bugs can be found here: https://gem5.atlassian.net/browse/GEM5-648 Change-Id: I3492ec4a6d8c59ffbae899ce8e87ab4ffb92b976 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47466 Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
158 lines
4.8 KiB
Python
158 lines
4.8 KiB
Python
import m5
|
|
import os
|
|
import configparser
|
|
|
|
from m5.objects import DRAMsim3, AddrRange, Port, MemCtrl
|
|
|
|
from ..utils.override import overrides
|
|
from ..boards.abstract_board import AbstractBoard
|
|
from .abstract_memory_system import AbstractMemorySystem
|
|
|
|
|
|
from typing import Optional, Tuple, Sequence, List
|
|
|
|
|
|
def config_ds3(mem_type: str, num_chnls: int) -> Tuple[str, str]:
|
|
"""
|
|
This function creates a config file that will be used to create a memory
|
|
controller of type DRAMSim3. It stores the config file in /tmp/ directory.
|
|
|
|
:param mem_type: The name for the type of the memory to be configured.
|
|
:param num_chnls: The number of channels to configure for the memory
|
|
:returns: A tuple containing the output file and the output directory.
|
|
"""
|
|
config = configparser.ConfigParser()
|
|
|
|
# TODO: We need a better solution to this. This hard-coding is not
|
|
# an acceptable solution.
|
|
dramsim_3_dir = os.path.join(
|
|
os.path.dirname(os.path.abspath(__file__)),
|
|
os.pardir,
|
|
os.pardir,
|
|
os.pardir,
|
|
"ext",
|
|
"DRAMsim3",
|
|
)
|
|
|
|
dramsim_3_mem_configs = os.path.join(dramsim_3_dir, "configs")
|
|
|
|
input_file = os.path.join(dramsim_3_mem_configs, mem_type + ".ini")
|
|
|
|
# Run checks to ensure the `ext/DRAMsim3` directory is present, contains
|
|
# the configs directory, and the configuration file we require.
|
|
if not os.path.isdir(dramsim_3_dir):
|
|
raise Exception(
|
|
"The `ext/DRAMsim3` directory cannot be found.\n"
|
|
"Please navigate to `ext` and run:\n"
|
|
"git clone git@github.com:umd-memsys/DRAMsim3.git"
|
|
)
|
|
elif os.path.isdir(dramsim_3_mem_configs):
|
|
raise Exception(
|
|
"The `ext/DRAMsim3/configs` directory cannot be found."
|
|
)
|
|
elif os.path.isfile(input_file):
|
|
raise Exception(
|
|
"The configuration file '" + input_file + "' cannot " " be found."
|
|
)
|
|
|
|
output_file = "/tmp/" + mem_type + "_chnls" + str(num_chnls) + ".ini"
|
|
new_config = open(output_file, "w")
|
|
config.read(input_file)
|
|
config.set("system", "channels", str(num_chnls))
|
|
config.write(new_config)
|
|
new_config.close()
|
|
return output_file, m5.options.outdir
|
|
|
|
|
|
class DRAMSim3MemCtrl(DRAMsim3):
|
|
"""
|
|
A DRAMSim3 Memory Controller.
|
|
|
|
The class serves as a SimObject object wrapper, utiliszing the DRAMSim3
|
|
configuratons.
|
|
"""
|
|
|
|
def __init__(self, mem_name: str, num_chnls: int) -> None:
|
|
"""
|
|
:param mem_name: The name of the type of memory to be configured.
|
|
:param num_chnls: The number of channels.
|
|
"""
|
|
super(DRAMSim3MemCtrl, self).__init__()
|
|
ini_path, outdir = config_ds3(mem_name, num_chnls)
|
|
self.configFile = ini_path
|
|
self.filePath = outdir
|
|
|
|
|
|
class SingleChannel(AbstractMemorySystem):
|
|
"""
|
|
A Single Channel Memory system.
|
|
"""
|
|
|
|
def __init__(self, mem_type: str, size: Optional[str]):
|
|
"""
|
|
:param mem_name: The name of the type of memory to be configured.
|
|
:param num_chnls: The number of channels.
|
|
"""
|
|
super(SingleChannel, self).__init__()
|
|
self.mem_ctrl = DRAMSim3MemCtrl(mem_type, 1)
|
|
if size:
|
|
self.mem_ctrl.range = AddrRange(size)
|
|
else:
|
|
raise NotImplementedError(
|
|
"DRAMSim3 memory controller requires a size parameter."
|
|
)
|
|
|
|
@overrides(AbstractMemorySystem)
|
|
def incorporate_memory(self, board: AbstractBoard) -> None:
|
|
pass
|
|
|
|
@overrides(AbstractMemorySystem)
|
|
def get_mem_ports(self) -> Tuple[Sequence[AddrRange], Port]:
|
|
return [(self.mem_ctrl.range, self.mem_ctrl.port)]
|
|
|
|
@overrides(AbstractMemorySystem)
|
|
def get_memory_controllers(self) -> List[MemCtrl]:
|
|
return [self.mem_ctrl]
|
|
|
|
@overrides(AbstractMemorySystem)
|
|
def get_memory_ranges(self):
|
|
return [self.mem_ctrl.range]
|
|
|
|
|
|
def SingleChannelDDR3_1600(
|
|
size: Optional[str] = "2048MB",
|
|
) -> SingleChannel:
|
|
"""
|
|
A single channel DDR3_1600.
|
|
|
|
:param size: The size of the memory system. Default value of 2048MB.
|
|
"""
|
|
return SingleChannel("DDR3_8Gb_x8_1600", size)
|
|
|
|
|
|
def SingleChannelDDR4_2400(size: Optional[str] = "1024MB") -> SingleChannel:
|
|
"""
|
|
A single channel DDR3_2400.
|
|
|
|
:param size: The size of the memory system. Default value of 1024MB.
|
|
"""
|
|
return SingleChannel("DDR4_4Gb_x8_2400", size)
|
|
|
|
|
|
def SingleChannelLPDDR3_1600(size: Optional[str] = "256MB") -> SingleChannel:
|
|
"""
|
|
A single channel LPDDR3_1600.
|
|
|
|
:param size: The size of the memory system. Default value of 256MB.
|
|
"""
|
|
return SingleChannel("LPDDR3_8Gb_x32_1600", size)
|
|
|
|
|
|
def SingleChannelHBM(size: Optional[str] = "64MB") -> SingleChannel:
|
|
"""
|
|
A single channel HBM.
|
|
|
|
:param size: The size of the memory system. Default value of 64MB.
|
|
"""
|
|
return SingleChannel("HBM1_4Gb_x128", size)
|