stdlib: Removing SingleChannelMemory
This change removes the code base for SingleChannelMemory and
replaces it with MultiChannelMemory. muli_channel defines all
the classes that were defined by single_channel. Basically any
SingleChannelMemory could be thought of as a MultiChannelMemory
with 1 channel.
Change-Id: If96079d5f77be5a3ba26d2c2ddb98f5c60375cd8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53304
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/configs/example/gem5_library/arm-hello.py b/configs/example/gem5_library/arm-hello.py
index 540a96b..5a2f46c 100644
--- a/configs/example/gem5_library/arm-hello.py
+++ b/configs/example/gem5_library/arm-hello.py
@@ -47,11 +47,11 @@
from gem5.isas import ISA
from gem5.utils.requires import requires
from gem5.resources.resource import Resource
+from gem5.components.memory import SingleChannelDDR3_1600
+from gem5.components.processors.cpu_types import CPUTypes
from gem5.components.boards.simple_board import SimpleBoard
from gem5.components.cachehierarchies.classic.no_cache import NoCache
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.simple_processor import SimpleProcessor
-from gem5.components.processors.cpu_types import CPUTypes
# This check ensures the gem5 binary is compiled to the ARM ISA target. If not,
# an exception will be thrown.
diff --git a/configs/example/gem5_library/riscv-fs.py b/configs/example/gem5_library/riscv-fs.py
index f46a345..4d0a2c8 100644
--- a/configs/example/gem5_library/riscv-fs.py
+++ b/configs/example/gem5_library/riscv-fs.py
@@ -43,7 +43,7 @@
from m5.objects import Root
from gem5.components.boards.riscv_board import RiscvBoard
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
+from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.processors.simple_processor import SimpleProcessor
from gem5.components.cachehierarchies.classic.\
private_l1_private_l2_cache_hierarchy import (
diff --git a/configs/example/gem5_library/x86-ubuntu-run.py b/configs/example/gem5_library/x86-ubuntu-run.py
index 9979c14..622f4f3 100644
--- a/configs/example/gem5_library/x86-ubuntu-run.py
+++ b/configs/example/gem5_library/x86-ubuntu-run.py
@@ -47,8 +47,8 @@
import m5
from m5.objects import Root
-from gem5.prebuilt.demo.x86_demo_board import X86DemoBoard
from gem5.resources.resource import Resource
+from gem5.prebuilt.demo.x86_demo_board import X86DemoBoard
# Here we setup the board. The prebuilt X86DemoBoard allows for Full-System X86
# simulation.
@@ -64,4 +64,4 @@
root = Root(full_system=True, system=board)
m5.instantiate()
-m5.simulate()
\ No newline at end of file
+m5.simulate()
diff --git a/src/python/SConscript b/src/python/SConscript
index 4487bdd..3d91ccb 100644
--- a/src/python/SConscript
+++ b/src/python/SConscript
@@ -133,8 +133,9 @@
PySource('gem5.components.memory', 'gem5/components/memory/__init__.py')
PySource('gem5.components.memory', 'gem5/components/memory/abstract_memory_system.py')
PySource('gem5.components.memory', 'gem5/components/memory/dramsim_3.py')
-PySource('gem5.components.memory', 'gem5/components/memory/single_channel.py')
PySource('gem5.components.memory', 'gem5/components/memory/simple.py')
+PySource('gem5.components.memory', 'gem5/components/memory/memory.py')
+PySource('gem5.components.memory', 'gem5/components/memory/single_channel.py')
PySource('gem5.components.memory', 'gem5/components/memory/multi_channel.py')
PySource('gem5.components.memory.dram_interfaces',
'gem5/components/memory/dram_interfaces/__init__.py')
diff --git a/src/python/gem5/components/memory/__init__.py b/src/python/gem5/components/memory/__init__.py
index e69de29..5e16865 100644
--- a/src/python/gem5/components/memory/__init__.py
+++ b/src/python/gem5/components/memory/__init__.py
@@ -0,0 +1,36 @@
+# Copyright (c) 2021 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from .single_channel import SingleChannelDDR3_1600
+from .single_channel import SingleChannelDDR3_2133
+from .single_channel import SingleChannelDDR4_2400
+from .single_channel import SingleChannelHBM
+from .single_channel import SingleChannelLPDDR3_1600
+from .multi_channel import DualChannelDDR3_1600
+from .multi_channel import DualChannelDDR3_2133
+from .multi_channel import DualChannelDDR4_2400
+from .multi_channel import HBM2Stack
+from .multi_channel import DualChannelLPDDR3_1600
diff --git a/src/python/gem5/components/memory/memory.py b/src/python/gem5/components/memory/memory.py
new file mode 100644
index 0000000..929a6ae
--- /dev/null
+++ b/src/python/gem5/components/memory/memory.py
@@ -0,0 +1,185 @@
+# Copyright (c) 2021 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+""" Channeled "generic" DDR memory controllers
+"""
+
+from math import log
+from ...utils.override import overrides
+from m5.util.convert import toMemorySize
+from ..boards.abstract_board import AbstractBoard
+from .abstract_memory_system import AbstractMemorySystem
+from m5.objects import AddrRange, DRAMInterface, MemCtrl, Port
+from typing import Type, Sequence, Tuple, List, Optional, Union
+
+
+def _try_convert(val, cls):
+ try:
+ return cls(val)
+ except:
+ raise Exception(f"Could not convert {val} to {cls}")
+
+def _isPow2(num):
+ log_num = int(log(num, 2))
+ if 2 ** log_num != num:
+ return False
+ else:
+ return True
+
+class ChanneledMemory(AbstractMemorySystem):
+ """A class to implement multi-channel memory system
+
+ This class can take a DRAM Interface as a parameter to model a multi
+ channel DDR DRAM memory system.
+ """
+ def __init__(
+ self,
+ dram_interface_class: Type[DRAMInterface],
+ num_channels: Union[int, str],
+ interleaving_size: Union[int, str],
+ size: Optional[str] = None,
+ addr_mapping: Optional[str] = None,
+ ) -> None:
+ """
+ :param dram_interface_class: The DRAM interface type to create with
+ this memory controller
+ :param num_channels: The number of channels that needs to be
+ simulated
+ :param size: Optionally specify the size of the DRAM controller's
+ address space. By default, it starts at 0 and ends at the size of
+ the DRAM device specified
+ :param addr_mapping: Defines the address mapping scheme to be used.
+ If None, it is defaulted to addr_mapping from dram_interface_class.
+ :param interleaving_size: Defines the interleaving size of the multi-
+ channel memory system. By default, it is equivalent to the atom
+ size, i.e., 64.
+ """
+ num_channels = _try_convert(num_channels, int)
+ interleaving_size = _try_convert(interleaving_size, int)
+
+ if size:
+ size = _try_convert(size, str)
+
+ if addr_mapping:
+ addr_mapping = _try_convert(addr_mapping, str)
+
+ super().__init__()
+ self._dram_class = dram_interface_class
+ self._num_channels = num_channels
+
+ if not _isPow2(interleaving_size):
+ raise ValueError("Memory interleaving size should be a power of 2")
+ self._intlv_size = interleaving_size
+
+ if addr_mapping:
+ self._addr_mapping = addr_mapping
+ else:
+ self._addr_mapping = self._dram_class.addr_mapping.value
+
+ if size:
+ self._size = toMemorySize(size)
+ else:
+ self._size = self._get_dram_size(num_channels, self._dram_class)
+
+ self._dram = [
+ self._dram_class(addr_mapping=self._addr_mapping)
+ for _ in range(num_channels)
+ ]
+ self.mem_ctrl = [
+ MemCtrl(dram=self._dram[i]) for i in range(num_channels)
+ ]
+
+ def _get_dram_size(self, num_channels: int, dram: DRAMInterface) -> int:
+ return num_channels * (
+ dram.device_size.value
+ * dram.devices_per_rank.value
+ * dram.ranks_per_channel.value
+ )
+
+ def _interleave_addresses(self):
+ if self._addr_mapping == "RoRaBaChCo":
+ rowbuffer_size = (
+ self._dram_class.device_rowbuffer_size.value
+ * self._dram_class.devices_per_rank.value
+ )
+ intlv_low_bit = log(rowbuffer_size, 2)
+ elif self._addr_mapping in ["RoRaBaCoCh", "RoCoRaBaCh"]:
+ intlv_low_bit = log(self._intlv_size, 2)
+ else:
+ raise ValueError(
+ "Only these address mappings are supported: "
+ "RoRaBaChCo, RoRaBaCoCh, RoCoRaBaCh"
+ )
+
+ intlv_bits = log(self._num_channels, 2)
+ for i, ctrl in enumerate(self.mem_ctrl):
+ ctrl.dram.range = AddrRange(
+ start=self._mem_range.start,
+ size=self._mem_range.size(),
+ intlvHighBit=intlv_low_bit + intlv_bits - 1,
+ xorHighBit=0,
+ intlvBits=intlv_bits,
+ intlvMatch=i,
+ )
+
+ @overrides(AbstractMemorySystem)
+ def incorporate_memory(self, board: AbstractBoard) -> None:
+ if self._intlv_size < int(board.get_cache_line_size()):
+ raise ValueError(
+ "Memory interleaving size can not be smaller than"
+ " board's cache line size.\nBoard's cache line size: "
+ f"{board.get_cache_line_size()}\n, This memory's interleaving "
+ f"size: {self._intlv_size}"
+ )
+
+ @overrides(AbstractMemorySystem)
+ def get_mem_ports(self) -> Sequence[Tuple[AddrRange, Port]]:
+ return [(ctrl.dram.range, ctrl.port) for ctrl in self.mem_ctrl]
+
+ @overrides(AbstractMemorySystem)
+ def get_memory_controllers(self) -> List[MemCtrl]:
+ return [ctrl for ctrl in self.mem_ctrl]
+
+ @overrides(AbstractMemorySystem)
+ def get_size(self) -> int:
+ return self._size
+
+ @overrides(AbstractMemorySystem)
+ def set_memory_range(self, ranges: List[AddrRange]) -> None:
+ """Need to add support for non-contiguous non overlapping ranges in
+ the future.
+ """
+ if len(ranges) != 1 or ranges[0].size() != self._size:
+ raise Exception(
+ "Multi channel memory controller requires a single range "
+ "which matches the memory's size.\n"
+ f"The range size: {range[0].size()}\n"
+ f"This memory's size: {self._size}"
+ )
+ self._mem_range = ranges[0]
+ self._interleave_addresses()
+
+
diff --git a/src/python/gem5/components/memory/multi_channel.py b/src/python/gem5/components/memory/multi_channel.py
index 8736f02..d54347a 100644
--- a/src/python/gem5/components/memory/multi_channel.py
+++ b/src/python/gem5/components/memory/multi_channel.py
@@ -24,182 +24,15 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Multi channel "generic" DDR memory controllers
-"""
-
-from math import log
-from ...utils.override import overrides
-from m5.util.convert import toMemorySize
-from ..boards.abstract_board import AbstractBoard
+from .memory import ChanneledMemory
from .abstract_memory_system import AbstractMemorySystem
-from m5.objects import AddrRange, DRAMInterface, MemCtrl, Port
-from typing import Type, Sequence, Tuple, List, Optional, Union
-
-def _try_convert(val, cls):
- try:
- return cls(val)
- except:
- raise Exception(f"Could not convert {val} to {cls}")
-
-def _isPow2(num):
- log_num = int(log(num, 2))
- if 2 ** log_num != num:
- return False
- else:
- return True
-
-class MultiChannelMemory(AbstractMemorySystem):
- """A class to implement multi-channel memory system
-
- This class can take a DRAM Interface as a parameter to model a multi
- channel DDR DRAM memory system.
- """
- def __init__(
- self,
- dram_interface_class: Type[DRAMInterface],
- num_channels: Union[int, str],
- interleaving_size: Union[int, str],
- size: Optional[str] = None,
- addr_mapping: Optional[str] = None,
- ) -> None:
- """
- :param dram_interface_class: The DRAM interface type to create with
- this memory controller
- :param num_channels: The number of channels that needs to be
- simulated
- :param size: Optionally specify the size of the DRAM controller's
- address space. By default, it starts at 0 and ends at the size of
- the DRAM device specified
- :param addr_mapping: Defines the address mapping scheme to be used.
- If None, it is defaulted to addr_mapping from dram_interface_class.
- :param interleaving_size: Defines the interleaving size of the multi-
- channel memory system. By default, it is equivalent to the atom
- size, i.e., 64.
- """
- num_channels = _try_convert(num_channels, int)
- interleaving_size = _try_convert(interleaving_size, int)
-
- if size:
- size = _try_convert(size, str)
-
- if addr_mapping:
- addr_mapping = _try_convert(addr_mapping, str)
-
- super().__init__()
- self._dram_class = dram_interface_class
- self._num_channels = num_channels
-
- if not _isPow2(interleaving_size):
- raise ValueError("Memory interleaving size should be a power of 2")
- self._intlv_size = interleaving_size
-
- if addr_mapping:
- self._addr_mapping = addr_mapping
- else:
- self._addr_mapping = self._dram_class.addr_mapping.value
-
- if size:
- self._size = toMemorySize(size)
- else:
- self._size = self._get_dram_size(num_channels, self._dram_class)
-
- self._dram = [
- self._dram_class(addr_mapping=self._addr_mapping)
- for _ in range(num_channels)
- ]
- self.mem_ctrl = [
- MemCtrl(dram=self._dram[i]) for i in range(num_channels)
- ]
-
- def _get_dram_size(self, num_channels: int, dram: DRAMInterface) -> int:
- return num_channels * (
- dram.device_size.value
- * dram.devices_per_rank.value
- * dram.ranks_per_channel.value
- )
-
- def _interleave_addresses(self):
- if self._addr_mapping == "RoRaBaChCo":
- rowbuffer_size = (
- self._dram_class.device_rowbuffer_size.value
- * self._dram_class.devices_per_rank.value
- )
- intlv_low_bit = log(rowbuffer_size, 2)
- elif self._addr_mapping in ["RoRaBaCoCh", "RoCoRaBaCh"]:
- intlv_low_bit = log(self._intlv_size, 2)
- else:
- raise ValueError(
- "Only these address mappings are supported: "
- "RoRaBaChCo, RoRaBaCoCh, RoCoRaBaCh"
- )
-
- intlv_bits = log(self._num_channels, 2)
- for i, ctrl in enumerate(self.mem_ctrl):
- ctrl.dram.range = AddrRange(
- start=self._mem_range.start,
- size=self._mem_range.size(),
- intlvHighBit=intlv_low_bit + intlv_bits - 1,
- xorHighBit=0,
- intlvBits=intlv_bits,
- intlvMatch=i,
- )
-
- @overrides(AbstractMemorySystem)
- def incorporate_memory(self, board: AbstractBoard) -> None:
- if self._intlv_size < int(board.get_cache_line_size()):
- raise ValueError(
- "Memory interleaving size can not be smaller than"
- " board's cache line size.\nBoard's cache line size: "
- f"{board.get_cache_line_size()}\n, This memory's interleaving "
- f"size: {self._intlv_size}"
- )
-
- @overrides(AbstractMemorySystem)
- def get_mem_ports(self) -> Sequence[Tuple[AddrRange, Port]]:
- return [(ctrl.dram.range, ctrl.port) for ctrl in self.mem_ctrl]
-
- @overrides(AbstractMemorySystem)
- def get_memory_controllers(self) -> List[MemCtrl]:
- return [ctrl for ctrl in self.mem_ctrl]
-
- @overrides(AbstractMemorySystem)
- def get_size(self) -> int:
- return self._size
-
- @overrides(AbstractMemorySystem)
- def set_memory_range(self, ranges: List[AddrRange]) -> None:
- """Need to add support for non-contiguous non overlapping ranges in
- the future.
- """
- if len(ranges) != 1 or ranges[0].size() != self._size:
- raise Exception(
- "Multi channel memory controller requires a single range "
- "which matches the memory's size.\n"
- f"The range size: {range[0].size()}\n"
- f"This memory's size: {self._size}"
- )
- self._mem_range = ranges[0]
- self._interleave_addresses()
-
-
+from typing import Optional
from .dram_interfaces.ddr3 import DDR3_1600_8x8, DDR3_2133_8x8
from .dram_interfaces.ddr4 import DDR4_2400_8x8
from .dram_interfaces.lpddr3 import LPDDR3_1600_1x32
-from .dram_interfaces.hbm import HBM_1000_4H_1x64, HBM_1000_4H_1x128
+from .dram_interfaces.hbm import HBM_1000_4H_1x64
-def SingleChannelDDR3_1600(
- size: Optional[str] = None,
-) -> AbstractMemorySystem:
- """
- A single channel memory system using DDR3_1600_8x8 based DIMM
- """
- return MultiChannelMemory(
- DDR3_1600_8x8,
- 1,
- 64,
- size=size,
- )
def DualChannelDDR3_1600(
size: Optional[str] = None,
@@ -207,103 +40,55 @@
"""
A dual channel memory system using DDR3_1600_8x8 based DIMM
"""
- return MultiChannelMemory(
+ return ChanneledMemory(
DDR3_1600_8x8,
2,
64,
size=size,
)
-def SingleChannelDDR3_2133(
- size: Optional[str] = None,
-) -> AbstractMemorySystem:
- """
- A single channel memory system using DDR3_2133_8x8 based DIMM
- """
- return MultiChannelMemory(
- DDR3_2133_8x8,
- 1,
- 64,
- size=size,
- )
-
def DualChannelDDR3_2133(
size: Optional[str] = None,
) -> AbstractMemorySystem:
"""
A dual channel memory system using DDR3_2133_8x8 based DIMM
"""
- return MultiChannelMemory(
+ return ChanneledMemory(
DDR3_2133_8x8,
2,
64,
size=size,
)
-def SingleChannelDDR4_2400(
- size: Optional[str] = None,
-) -> AbstractMemorySystem:
- """
- A single channel memory system using DDR4_2400_8x8 based DIMM
- """
- return MultiChannelMemory(
- DDR4_2400_8x8,
- 1,
- 64,
- size=size,
- )
-
def DualChannelDDR4_2400(
size: Optional[str] = None,
) -> AbstractMemorySystem:
"""
A dual channel memory system using DDR4_2400_8x8 based DIMM
"""
- return MultiChannelMemory(
+ return ChanneledMemory(
DDR4_2400_8x8,
2,
64,
size=size,
)
-def SingleChannelLPDDR3_1600(
- size: Optional[str] = None,
-) -> AbstractMemorySystem:
- return MultiChannelMemory(
- LPDDR3_1600_1x32,
- 1,
- 64,
- size=size,
- )
-
def DualChannelLPDDR3_1600(
size: Optional[str] = None,
) -> AbstractMemorySystem:
- return MultiChannelMemory(
+ return ChanneledMemory(
LPDDR3_1600_1x32,
2,
64,
size=size,
)
-def SingleChannelHBM(
- size: Optional[str] = None,
-) -> AbstractMemorySystem:
- if not size:
- size = "256MiB"
- return MultiChannelMemory(
- HBM_1000_4H_1x128,
- 1,
- 64,
- size=size
- )
-
def HBM2Stack(
size: Optional[str] = None,
) -> AbstractMemorySystem:
if not size:
size = "4GiB"
- return MultiChannelMemory(
+ return ChanneledMemory(
HBM_1000_4H_1x64,
16,
64,
diff --git a/src/python/gem5/components/memory/single_channel.py b/src/python/gem5/components/memory/single_channel.py
index 11a0b15..57ce232 100644
--- a/src/python/gem5/components/memory/single_channel.py
+++ b/src/python/gem5/components/memory/single_channel.py
@@ -24,113 +24,74 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Single channel "generic" DDR memory controllers
-"""
-
-from ..boards.abstract_board import AbstractBoard
+from .memory import ChanneledMemory
from .abstract_memory_system import AbstractMemorySystem
-from ...utils.override import overrides
-from m5.objects import AddrRange, DRAMInterface, MemCtrl, Port
-from m5.util.convert import toMemorySize
+from typing import Optional
-from typing import List, Sequence, Tuple, Type, Optional
-
-
-class SingleChannelMemory(AbstractMemorySystem):
- """A simple implementation of a single channel memory system
-
- This class can take a DRAM Interface as a parameter to model many different
- DDR memory systems.
- """
-
- def __init__(
- self,
- dram_interface_class: Type[DRAMInterface],
- size: Optional[str] = None,
- ):
- """
- :param dram_interface_class: The DRAM interface type to create with
- this memory controller
- :param size: Optionally specify the size of the DRAM controller's
- address space. By default, it starts at 0 and ends at the size of
- the DRAM device specified
- """
- super().__init__()
-
- self._dram = dram_interface_class()
- if size:
- self._size = toMemorySize(size)
- else:
- self._size = self._get_dram_size(self._dram)
- self.mem_ctrl = MemCtrl(dram=self._dram)
-
- def _get_dram_size(self, dram: DRAMInterface) -> int:
- return (
- dram.device_size.value
- * dram.devices_per_rank.value
- * dram.ranks_per_channel.value
- )
-
- @overrides(AbstractMemorySystem)
- def incorporate_memory(self, board: AbstractBoard) -> None:
- pass
-
- @overrides(AbstractMemorySystem)
- def get_mem_ports(self) -> Tuple[Sequence[AddrRange], Port]:
- return [(self._dram.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:
- print(ranges[0].size())
- raise Exception(
- "Single channel memory controller requires a single range "
- "which matches the memory's size."
- )
- self.mem_ctrl.dram.range = ranges[0]
-
-
-from .dram_interfaces.ddr3 import DDR3_1600_8x8, DDR3_2133_8x8
from .dram_interfaces.ddr4 import DDR4_2400_8x8
-from .dram_interfaces.lpddr3 import LPDDR3_1600_1x32
from .dram_interfaces.hbm import HBM_1000_4H_1x128
-
-# Enumerate all of the different DDR memory systems we support
-def SingleChannelDDR3_1600(size: Optional[str] = None) -> AbstractMemorySystem:
- """
- A single channel memory system using a single DDR3_1600_8x8 based DIMM
- """
- return SingleChannelMemory(DDR3_1600_8x8, size)
+from .dram_interfaces.lpddr3 import LPDDR3_1600_1x32
+from .dram_interfaces.ddr3 import DDR3_1600_8x8, DDR3_2133_8x8
-def SingleChannelDDR3_2133(size: Optional[str] = None) -> AbstractMemorySystem:
+def SingleChannelDDR3_1600(
+ size: Optional[str] = None,
+) -> AbstractMemorySystem:
"""
- A single channel memory system using a single DDR3_2133_8x8 based DIMM
+ A single channel memory system using DDR3_1600_8x8 based DIMM
"""
- return SingleChannelMemory(DDR3_2133_8x8, size)
+ return ChanneledMemory(
+ DDR3_1600_8x8,
+ 1,
+ 64,
+ size=size,
+ )
-
-def SingleChannelDDR4_2400(size: Optional[str] = None) -> AbstractMemorySystem:
+def SingleChannelDDR3_2133(
+ size: Optional[str] = None,
+) -> AbstractMemorySystem:
"""
- A single channel memory system using a single DDR4_2400_8x8 based DIMM
+ A single channel memory system using DDR3_2133_8x8 based DIMM
"""
- return SingleChannelMemory(DDR4_2400_8x8, size)
+ return ChanneledMemory(
+ DDR3_2133_8x8,
+ 1,
+ 64,
+ size=size,
+ )
+def SingleChannelDDR4_2400(
+ size: Optional[str] = None,
+) -> AbstractMemorySystem:
+ """
+ A single channel memory system using DDR4_2400_8x8 based DIMM
+ """
+ return ChanneledMemory(
+ DDR4_2400_8x8,
+ 1,
+ 64,
+ size=size,
+ )
def SingleChannelLPDDR3_1600(
size: Optional[str] = None,
) -> AbstractMemorySystem:
- return SingleChannelMemory(LPDDR3_1600_1x32, size)
+ return ChanneledMemory(
+ LPDDR3_1600_1x32,
+ 1,
+ 64,
+ size=size,
+ )
-
-def SingleChannelHBM(size: Optional[str] = None) -> AbstractMemorySystem:
- return SingleChannelMemory(HBM_1000_4H_1x128, size)
+def SingleChannelHBM(
+ size: Optional[str] = None,
+) -> AbstractMemorySystem:
+ if not size:
+ size = "256MiB"
+ return ChanneledMemory(
+ HBM_1000_4H_1x128,
+ 1,
+ 64,
+ size=size
+ )
diff --git a/tests/gem5/configs/boot_kvm_fork_run.py b/tests/gem5/configs/boot_kvm_fork_run.py
index 14d6a4b..2cd180a 100644
--- a/tests/gem5/configs/boot_kvm_fork_run.py
+++ b/tests/gem5/configs/boot_kvm_fork_run.py
@@ -46,7 +46,7 @@
from gem5.components.boards.x86_board import X86Board
from gem5.coherence_protocol import CoherenceProtocol
from gem5.isas import ISA
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
+from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.processors.cpu_types import CPUTypes
from gem5.components.processors.simple_switchable_processor import (
SimpleSwitchableProcessor,
diff --git a/tests/gem5/configs/boot_kvm_switch_exit.py b/tests/gem5/configs/boot_kvm_switch_exit.py
index 68651eb..5aa19f5 100644
--- a/tests/gem5/configs/boot_kvm_switch_exit.py
+++ b/tests/gem5/configs/boot_kvm_switch_exit.py
@@ -33,10 +33,10 @@
import m5
from m5.objects import Root
+from gem5.isas import ISA
from gem5.components.boards.x86_board import X86Board
from gem5.coherence_protocol import CoherenceProtocol
-from gem5.isas import ISA
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
+from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.processors.cpu_types import CPUTypes
from gem5.components.processors.simple_switchable_processor import (
SimpleSwitchableProcessor,
diff --git a/tests/gem5/configs/parsec_disk_run.py b/tests/gem5/configs/parsec_disk_run.py
index c65be10..1315c58 100644
--- a/tests/gem5/configs/parsec_disk_run.py
+++ b/tests/gem5/configs/parsec_disk_run.py
@@ -42,7 +42,7 @@
from gem5.resources.resource import Resource
from gem5.components.boards.x86_board import X86Board
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
+from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.processors.simple_switchable_processor import (
SimpleSwitchableProcessor,
)
diff --git a/tests/gem5/configs/riscv_boot_exit_run.py b/tests/gem5/configs/riscv_boot_exit_run.py
index 45ce62c..38f57d8 100644
--- a/tests/gem5/configs/riscv_boot_exit_run.py
+++ b/tests/gem5/configs/riscv_boot_exit_run.py
@@ -125,7 +125,7 @@
)
# Setup the system memory.
-python_module = "gem5.components.memory.multi_channel"
+python_module = "gem5.components.memory"
memory_class = getattr(
importlib.import_module(python_module), args.dram_class
)
diff --git a/tests/gem5/configs/simple_binary_run.py b/tests/gem5/configs/simple_binary_run.py
index b41f26d..fa4faa0 100644
--- a/tests/gem5/configs/simple_binary_run.py
+++ b/tests/gem5/configs/simple_binary_run.py
@@ -34,11 +34,11 @@
from m5.objects import Root
from gem5.resources.resource import Resource
+from gem5.components.processors.cpu_types import CPUTypes
+from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.boards.simple_board import SimpleBoard
from gem5.components.cachehierarchies.classic.no_cache import NoCache
-from gem5.components.memory.single_channel import SingleChannelDDR3_1600
from gem5.components.processors.simple_processor import SimpleProcessor
-from gem5.components.processors.cpu_types import CPUTypes
import argparse
diff --git a/tests/gem5/configs/x86_boot_exit_run.py b/tests/gem5/configs/x86_boot_exit_run.py
index 58e7713..96d1dad 100644
--- a/tests/gem5/configs/x86_boot_exit_run.py
+++ b/tests/gem5/configs/x86_boot_exit_run.py
@@ -161,7 +161,7 @@
# Setup the system memory.
# Warning: This must be kept at 3GB for now. X86Motherboard does not support
# anything else right now!
-python_module = "gem5.components.memory.multi_channel"
+python_module = "gem5.components.memory"
memory_class = getattr(
importlib.import_module(python_module), args.dram_class
)
diff --git a/tests/gem5/traffic_gen/test_memory_traffic_gen.py b/tests/gem5/traffic_gen/test_memory_traffic_gen.py
index 13b4638..5910f96 100644
--- a/tests/gem5/traffic_gen/test_memory_traffic_gen.py
+++ b/tests/gem5/traffic_gen/test_memory_traffic_gen.py
@@ -89,14 +89,12 @@
cache_classes = ["NoCache", "PrivateL1", "PrivateL1PrivateL2", "MESITwoLevel"]
-common_memory_classes = [
+memory_classes = [
"SingleChannelDDR3_1600",
"SingleChannelDDR3_2133",
"SingleChannelDDR4_2400",
"SingleChannelLPDDR3_1600",
"SingleChannelHBM",
-]
-multi_memory_classes = [
"DualChannelDDR3_1600",
"DualChannelDDR3_2133",
"DualChannelDDR4_2400",
@@ -135,19 +133,10 @@
)
create_single_core_tests(
- "gem5.components.memory.single_channel",
- common_memory_classes,
+ "gem5.components.memory",
+ memory_classes,
)
create_dual_core_tests(
- "gem5.components.memory.single_channel",
- common_memory_classes,
-)
-
-create_single_core_tests(
- "gem5.components.memory.multi_channel",
- common_memory_classes + multi_memory_classes,
-)
-create_dual_core_tests(
- "gem5.components.memory.multi_channel",
- common_memory_classes + multi_memory_classes,
+ "gem5.components.memory",
+ memory_classes,
)