blob: ba713970d1799cc6b77b4ae25115c9c009b78673 [file] [log] [blame]
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)