mem: Add DDR3 and LPDDR2 DRAM controller configurations
This patch moves the default DRAM parameters from the SimpleDRAM class to two different subclasses, one for DDR3 and one for LPDDR2. More can be added as we go forward. The regressions that previously used the SimpleDRAM are now using SimpleDDR3 as this is the most similar configuration.
This commit is contained in:
parent
eaa37e611f
commit
c4898b15bc
7 changed files with 111 additions and 35 deletions
|
@ -73,7 +73,7 @@ def makeLinuxAlphaSystem(mem_mode, mdesc = None):
|
|||
# base address (including the PCI config space)
|
||||
self.bridge = Bridge(delay='50ns',
|
||||
ranges = [AddrRange(IO_address_space_base, Addr.max)])
|
||||
self.physmem = SimpleDRAM(range = AddrRange(mdesc.mem()))
|
||||
self.physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
self.bridge.master = self.iobus.slave
|
||||
self.bridge.slave = self.membus.master
|
||||
|
@ -110,7 +110,7 @@ def makeLinuxAlphaRubySystem(mem_mode, mdesc = None):
|
|||
ide = IdeController(disks=[Parent.disk0, Parent.disk2],
|
||||
pci_func=0, pci_dev=0, pci_bus=0)
|
||||
|
||||
physmem = SimpleDRAM(range = AddrRange(mdesc.mem()))
|
||||
physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
|
||||
self = LinuxAlphaSystem(physmem = physmem)
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
if not mdesc:
|
||||
|
@ -180,10 +180,10 @@ def makeSparcSystem(mem_mode, mdesc = None):
|
|||
self.t1000 = T1000()
|
||||
self.t1000.attachOnChipIO(self.membus)
|
||||
self.t1000.attachIO(self.iobus)
|
||||
self.physmem = SimpleDRAM(range = AddrRange(Addr('1MB'), size = '64MB'),
|
||||
zero = True)
|
||||
self.physmem2 = SimpleDRAM(range = AddrRange(Addr('2GB'), size ='256MB'),
|
||||
zero = True)
|
||||
self.physmem = SimpleDDR3(range = AddrRange(Addr('1MB'), size = '64MB'),
|
||||
zero = True)
|
||||
self.physmem2 = SimpleDDR3(range = AddrRange(Addr('2GB'), size ='256MB'),
|
||||
zero = True)
|
||||
self.mem_ranges = [self.physmem.range, self.physmem2.range]
|
||||
self.bridge.master = self.iobus.slave
|
||||
self.bridge.slave = self.membus.master
|
||||
|
@ -274,8 +274,8 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
|||
if bare_metal:
|
||||
# EOT character on UART will end the simulation
|
||||
self.realview.uart.end_on_eot = True
|
||||
self.physmem = SimpleDRAM(range = AddrRange(Addr(mdesc.mem())),
|
||||
zero = True)
|
||||
self.physmem = SimpleDDR3(range = AddrRange(Addr(mdesc.mem())),
|
||||
zero = True)
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
else:
|
||||
self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8')
|
||||
|
@ -289,10 +289,10 @@ def makeArmSystem(mem_mode, machine_type, mdesc = None, bare_metal=False):
|
|||
boot_flags = 'earlyprintk console=ttyAMA0 lpj=19988480 norandmaps ' + \
|
||||
'rw loglevel=8 mem=%s root=/dev/sda1' % mdesc.mem()
|
||||
|
||||
self.physmem = SimpleDRAM(range =
|
||||
AddrRange(self.realview.mem_start_addr,
|
||||
size = mdesc.mem()),
|
||||
conf_table_reported = True)
|
||||
self.physmem = SimpleDDR3(range =
|
||||
AddrRange(self.realview.mem_start_addr,
|
||||
size = mdesc.mem()),
|
||||
conf_table_reported = True)
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
self.realview.setupBootLoader(self.membus, self, binary)
|
||||
self.gic_cpu_addr = self.realview.gic.cpu_addr
|
||||
|
@ -328,7 +328,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None):
|
|||
self.iobus = NoncoherentBus()
|
||||
self.membus = MemBus()
|
||||
self.bridge = Bridge(delay='50ns')
|
||||
self.physmem = SimpleDRAM(range = AddrRange('1GB'))
|
||||
self.physmem = SimpleDDR3(range = AddrRange('1GB'))
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
self.bridge.master = self.iobus.slave
|
||||
self.bridge.slave = self.membus.master
|
||||
|
@ -434,7 +434,7 @@ def makeX86System(mem_mode, numCPUs = 1, mdesc = None, self = None, Ruby = False
|
|||
self.mem_mode = mem_mode
|
||||
|
||||
# Physical memory
|
||||
self.physmem = SimpleDRAM(range = AddrRange(mdesc.mem()))
|
||||
self.physmem = SimpleDDR3(range = AddrRange(mdesc.mem()))
|
||||
self.mem_ranges = [self.physmem.range]
|
||||
|
||||
# Platform
|
||||
|
|
|
@ -63,11 +63,6 @@ class SimpleDRAM(AbstractMemory):
|
|||
# bus in front of the controller for multiple ports
|
||||
port = SlavePort("Slave port")
|
||||
|
||||
# the physical organisation of the DRAM
|
||||
lines_per_rowbuffer = Param.Unsigned(64, "Row buffer size in cache lines")
|
||||
ranks_per_channel = Param.Unsigned(2, "Number of ranks per channel")
|
||||
banks_per_rank = Param.Unsigned(8, "Number of banks per rank")
|
||||
|
||||
# the basic configuration of the controller architecture
|
||||
write_buffer_size = Param.Unsigned(32, "Number of read queue entries")
|
||||
read_buffer_size = Param.Unsigned(32, "Number of write queue entries")
|
||||
|
@ -77,21 +72,26 @@ class SimpleDRAM(AbstractMemory):
|
|||
write_thresh_perc = Param.Percent(70, "Threshold to trigger writes")
|
||||
|
||||
# scheduler, address map and page policy
|
||||
mem_sched_policy = Param.MemSched('fcfs', "Memory scheduling policy")
|
||||
mem_sched_policy = Param.MemSched('frfcfs', "Memory scheduling policy")
|
||||
addr_mapping = Param.AddrMap('openmap', "Address mapping policy")
|
||||
page_policy = Param.PageManage('open', "Page closure management policy")
|
||||
|
||||
# the physical organisation of the DRAM
|
||||
lines_per_rowbuffer = Param.Unsigned("Row buffer size in cache lines")
|
||||
ranks_per_channel = Param.Unsigned("Number of ranks per channel")
|
||||
banks_per_rank = Param.Unsigned("Number of banks per rank")
|
||||
|
||||
# timing behaviour and constraints - all in nanoseconds
|
||||
|
||||
# the amount of time in nanoseconds from issuing an activate command
|
||||
# to the data being available in the row buffer for a read/write
|
||||
tRCD = Param.Latency("14ns", "RAS to CAS delay")
|
||||
tRCD = Param.Latency("RAS to CAS delay")
|
||||
|
||||
# the time from issuing a read/write command to seeing the actual data
|
||||
tCL = Param.Latency("14ns", "CAS latency")
|
||||
tCL = Param.Latency("CAS latency")
|
||||
|
||||
# minimum time between a precharge and subsequent activate
|
||||
tRP = Param.Latency("14ns", "Row precharge time")
|
||||
tRP = Param.Latency("Row precharge time")
|
||||
|
||||
# time to complete a burst transfer, typically the burst length
|
||||
# divided by two due to the DDR bus, but by making it a parameter
|
||||
|
@ -99,23 +99,22 @@ class SimpleDRAM(AbstractMemory):
|
|||
# This parameter has to account for bus width and burst length.
|
||||
# Adjustment also necessary if cache line size is greater than
|
||||
# data size read/written by one full burst.
|
||||
tBURST = Param.Latency("4ns",
|
||||
"Burst duration (for DDR burst length / 2 cycles)")
|
||||
tBURST = Param.Latency("Burst duration (for DDR burst length / 2 cycles)")
|
||||
|
||||
# time taken to complete one refresh cycle (N rows in all banks)
|
||||
tRFC = Param.Latency("300ns", "Refresh cycle time")
|
||||
tRFC = Param.Latency("Refresh cycle time")
|
||||
|
||||
# refresh command interval, how often a "ref" command needs
|
||||
# to be sent. It is 7.8 us for a 64ms refresh requirement
|
||||
tREFI = Param.Latency("7.8us", "Refresh command interval")
|
||||
tREFI = Param.Latency("Refresh command interval")
|
||||
|
||||
# write-to-read turn around penalty, assumed same as read-to-write
|
||||
tWTR = Param.Latency("1ns", "Write to read switching time")
|
||||
tWTR = Param.Latency("Write to read switching time")
|
||||
|
||||
# time window in which a maximum number of activates are allowed
|
||||
# to take place, set to 0 to disable
|
||||
tXAW = Param.Latency("0ns", "X activation window")
|
||||
activation_limit = Param.Unsigned(4, "Max number of activates in window")
|
||||
tXAW = Param.Latency("X activation window")
|
||||
activation_limit = Param.Unsigned("Max number of activates in window")
|
||||
|
||||
# Currently rolled into other params
|
||||
######################################################################
|
||||
|
@ -127,3 +126,80 @@ class SimpleDRAM(AbstractMemory):
|
|||
# tRC - assumed to be 4 * tRP
|
||||
|
||||
# burst length for an access derived from peerBlockSize
|
||||
|
||||
# High-level model of a single DDR3 x64 interface (one command and
|
||||
# address bus), with default timings based on a DDR3-1600 4 Gbit part,
|
||||
# which would amount to 4 Gbyte of memory in 8x8 or 8 GByte in 16x4
|
||||
# configuration.
|
||||
class SimpleDDR3(SimpleDRAM):
|
||||
# Assuming 64 byte cache lines, use a 2kbyte page size, this
|
||||
# depends on the memory density
|
||||
lines_per_rowbuffer = 32
|
||||
|
||||
# Use two ranks
|
||||
ranks_per_channel = 2
|
||||
|
||||
# DDR3 has 8 banks in all configurations
|
||||
banks_per_rank = 8
|
||||
|
||||
# DDR3-1600 11-11-11
|
||||
tRCD = '13.75ns'
|
||||
tCL = '13.75ns'
|
||||
tRP = '13.75ns'
|
||||
|
||||
# Assuming 64 byte cache lines, across an x64 (8x8 or 16x4)
|
||||
# interface, translates to BL8, 4 clocks @ 800 MHz
|
||||
tBURST = '5ns'
|
||||
|
||||
# DDR3, 4 Gb has a tRFC of 240 CK and tCK = 1.25 ns
|
||||
tRFC = '300ns'
|
||||
|
||||
# DDR3, <=85C, half for >85C
|
||||
tREFI = '7.8us'
|
||||
|
||||
# Greater of 4 CK or 7.5 ns, 4 CK @ 800 MHz = 5 ns
|
||||
tWTR = '7.5ns'
|
||||
|
||||
# With a 2kbyte page size, DDR3-1600 lands around 40 ns
|
||||
tXAW = '40ns'
|
||||
activation_limit = 4
|
||||
|
||||
|
||||
# High-level model of a single LPDDR2-S4 x64 interface (one
|
||||
# command/address bus), with default timings based on a LPDDR2-1066
|
||||
# 4Gbit part, which whould amount to 1 GByte of memory in 2x32 or
|
||||
# 2GByte in 4x16 configuration.
|
||||
class SimpleLPDDR2_S4(SimpleDRAM):
|
||||
# Assuming 64 byte cache lines, use a 2kbyte page size, this
|
||||
# depends on the memory density
|
||||
lines_per_rowbuffer = 32
|
||||
|
||||
# Use two ranks
|
||||
ranks_per_channel = 2
|
||||
|
||||
# LPDDR2-S4 has 8 banks in all configurations
|
||||
banks_per_rank = 8
|
||||
|
||||
# Fixed at 15 ns
|
||||
tRCD = '15ns'
|
||||
|
||||
# 8 CK read latency, 4 CK write latency @ 533 MHz, 1.876 ns cycle time
|
||||
tCL = '15ns'
|
||||
|
||||
# Pre-charge one bank 15 ns and all banks 18 ns
|
||||
tRP = '18ns'
|
||||
|
||||
# Assuming 64 byte cache lines, across a x64 interface (2x32 or
|
||||
# 4x16), translates to BL8, 4 clocks @ 533 MHz
|
||||
tBURST = '7.5ns'
|
||||
|
||||
# LPDDR2-S4, 4 Gb
|
||||
tRFC = '130ns'
|
||||
tREFI = '3.9us'
|
||||
|
||||
# Irrespective of speed grade, tWTR is 7.5 ns
|
||||
tWTR = '7.5ns'
|
||||
|
||||
# Irrespective of size, tFAW is 50 ns
|
||||
tXAW = '50ns'
|
||||
activation_limit = 4
|
||||
|
|
|
@ -39,7 +39,7 @@ cpu.addTwoLevelCacheHierarchy(L1Cache(size = '128kB'),
|
|||
cpu.clock = '2GHz'
|
||||
|
||||
system = System(cpu = cpu,
|
||||
physmem = SimpleDRAM(),
|
||||
physmem = SimpleDDR3(),
|
||||
membus = CoherentBus(),
|
||||
mem_mode = "timing")
|
||||
system.system_port = system.membus.slave
|
||||
|
|
|
@ -52,7 +52,7 @@ cpu.addTwoLevelCacheHierarchy(L1Cache(size = '128kB'),
|
|||
cpu.clock = '2GHz'
|
||||
|
||||
system = System(cpu = cpu,
|
||||
physmem = SimpleDRAM(),
|
||||
physmem = SimpleDDR3(),
|
||||
membus = CoherentBus(),
|
||||
mem_mode = "timing")
|
||||
system.system_port = system.membus.slave
|
||||
|
|
|
@ -36,7 +36,7 @@ cpus = [ DerivO3CPU(cpu_id=i) for i in xrange(nb_cores) ]
|
|||
|
||||
# system simulated
|
||||
system = System(cpu = cpus,
|
||||
physmem = SimpleDRAM(),
|
||||
physmem = SimpleDDR3(),
|
||||
membus = CoherentBus(),
|
||||
mem_mode = "timing")
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ cpu.addTwoLevelCacheHierarchy(L1Cache(size = '128kB'),
|
|||
cpu.clock = '2GHz'
|
||||
|
||||
system = System(cpu = cpu,
|
||||
physmem = SimpleDRAM(),
|
||||
physmem = SimpleDDR3(),
|
||||
membus = CoherentBus(),
|
||||
mem_mode = "timing")
|
||||
system.system_port = system.membus.slave
|
||||
|
|
|
@ -48,7 +48,7 @@ require_sim_object("CommMonitor")
|
|||
cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-dram.cfg")
|
||||
|
||||
# system simulated
|
||||
system = System(cpu = cpu, physmem = SimpleDRAM(),
|
||||
system = System(cpu = cpu, physmem = SimpleDDR3(),
|
||||
membus = NoncoherentBus(clock="1GHz", width = 16))
|
||||
|
||||
# add a communication monitor
|
||||
|
|
Loading…
Reference in a new issue