blob: b7eba919fc98b45c2f34e8f1f436ba36cb2aeb21 [file] [log] [blame]
import m5
import os
import configparser
from m5.objects import DRAMsim3, AddrRange, Port, MemCtrl
from m5.util.convert import toMemorySize
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().__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().__init__()
self.mem_ctrl = DRAMSim3MemCtrl(mem_type, 1)
self._size = toMemorySize(size)
if not size:
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_size(self) -> int:
return self._size
@overrides(AbstractMemorySystem)
def set_memory_range(self, ranges: List[AddrRange]) -> None:
if len(ranges != 1) or ranges[0].size != self._size:
raise Exception(
"Single channel DRAMSim memory controller requires a single "
"range which matches the memory's size."
)
self.mem_ctrl.range = ranges[0]
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)