mem: Split memory controller into base MemCtrl and HeteroMemCtrl

This change splits the default gem5 memory controller into two
memory controllers: MemCtrl (base memory controller which can be
used with only a single memory interface dram/nvm), and
HeteroMemCtrl (heterogeneous memory controller which inherits from
MemCtrl and requires a dram and an nvm memory interface).
New arguments are added to many of the base class (MemCtrl) functions
(for example memory inteface to use that function for) which helps
in easier use of these in the inherited class (HeteroMemCtrl).

Change-Id: Ifa4e9f9f1560c47063d1a8159a8c94add2e670bb
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/59731
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
Maryam Babaie
2022-05-13 18:03:37 -07:00
committed by Bobby Bruce
parent c7c11c5661
commit b0fd05dd3d
11 changed files with 1018 additions and 343 deletions

View File

@@ -235,7 +235,7 @@ def config_mem(options, system):
# Create a controller if not sharing a channel with DRAM
# in which case the controller has already been created
if not opt_hybrid_channel:
mem_ctrl = m5.objects.MemCtrl()
mem_ctrl = m5.objects.HeteroMemCtrl()
mem_ctrl.nvm = nvm_intf
mem_ctrls.append(mem_ctrl)

View File

@@ -106,14 +106,14 @@ MemConfig.config_mem(args, system)
# controller with an NVM interface, check to be sure
if not isinstance(system.mem_ctrls[0], m5.objects.MemCtrl):
fatal("This script assumes the controller is a MemCtrl subclass")
if not isinstance(system.mem_ctrls[0].nvm, m5.objects.NVMInterface):
if not isinstance(system.mem_ctrls[0].dram, m5.objects.NVMInterface):
fatal("This script assumes the memory is a NVMInterface class")
# there is no point slowing things down by saving any data
system.mem_ctrls[0].nvm.null = True
system.mem_ctrls[0].dram.null = True
# Set the address mapping based on input argument
system.mem_ctrls[0].nvm.addr_mapping = args.addr_map
system.mem_ctrls[0].dram.addr_mapping = args.addr_map
# stay in each state for 0.25 ms, long enough to warm things up, and
# short enough to avoid hitting a refresh
@@ -124,21 +124,21 @@ period = 250000000
# the DRAM maximum bandwidth to ensure that it is saturated
# get the number of regions
nbr_banks = system.mem_ctrls[0].nvm.banks_per_rank.value
nbr_banks = system.mem_ctrls[0].dram.banks_per_rank.value
# determine the burst length in bytes
burst_size = int((system.mem_ctrls[0].nvm.devices_per_rank.value *
system.mem_ctrls[0].nvm.device_bus_width.value *
system.mem_ctrls[0].nvm.burst_length.value) / 8)
burst_size = int((system.mem_ctrls[0].dram.devices_per_rank.value *
system.mem_ctrls[0].dram.device_bus_width.value *
system.mem_ctrls[0].dram.burst_length.value) / 8)
# next, get the page size in bytes
buffer_size = system.mem_ctrls[0].nvm.devices_per_rank.value * \
system.mem_ctrls[0].nvm.device_rowbuffer_size.value
buffer_size = system.mem_ctrls[0].dram.devices_per_rank.value * \
system.mem_ctrls[0].dram.device_rowbuffer_size.value
# match the maximum bandwidth of the memory, the parameter is in seconds
# and we need it in ticks (ps)
itt = system.mem_ctrls[0].nvm.tBURST.value * 1000000000000
itt = system.mem_ctrls[0].dram.tBURST.value * 1000000000000
# assume we start at 0
max_addr = mem_range.end
@@ -179,7 +179,7 @@ def trace():
0, max_addr, burst_size, int(itt), int(itt),
args.rd_perc, 0,
num_seq_pkts, buffer_size, nbr_banks, bank,
addr_map, args.nvm_ranks)
addr_map, args.dram_ranks)
yield system.tgen.createExit(0)
system.tgen.start(trace())

View File

@@ -117,8 +117,8 @@ MemConfig.config_mem(args, system)
# the following assumes that we are using the native controller
# with NVM and DRAM interfaces, check to be sure
if not isinstance(system.mem_ctrls[0], m5.objects.MemCtrl):
fatal("This script assumes the controller is a MemCtrl subclass")
if not isinstance(system.mem_ctrls[0], m5.objects.HeteroMemCtrl):
fatal("This script assumes the controller is a HeteroMemCtrl subclass")
if not isinstance(system.mem_ctrls[0].dram, m5.objects.DRAMInterface):
fatal("This script assumes the first memory is a DRAMInterface subclass")
if not isinstance(system.mem_ctrls[0].nvm, m5.objects.NVMInterface):