mem: Add DDR3 and LPDDR2 DRAM controller configurations
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 31 Jan 2013 12:49:14 +0000 (07:49 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 31 Jan 2013 12:49:14 +0000 (07:49 -0500)
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.

configs/common/FSConfig.py
src/mem/SimpleDRAM.py
tests/configs/inorder-timing.py
tests/configs/o3-timing-checker.py
tests/configs/o3-timing-mp.py
tests/configs/o3-timing.py
tests/configs/tgen-simple-dram.py

index eb0730ffa861f8e8a9fdefe7b55f03fb10ba1116..fb3a5408f715539e57efbf865a3c659f604c6037 100644 (file)
@@ -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
index 83eaac61138c88daa94194ca2ee461d8cba8480b..41bad93565ca4629f7253382abec7bc9007ac853 100644 (file)
@@ -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
index a92c61ba19cd1af9f0ca190c23abca45f61965ca..77c4f3d18be0845cc4af69e1329469eb76c193eb 100644 (file)
@@ -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
index a33a2ac06251a6e7e91e2086e251fd9ee4cf35c2..cd15cf66bf614c0fd4e95a8fd4728451187cca22 100644 (file)
@@ -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
index c3a4929bb4afb0a752a3e49ec861655acfc88528..59f91a3920ba03794369eea7a93b36e7f0331dff 100644 (file)
@@ -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")
 
index 474d139023414a45ffe9f87141d300a2f44d2f67..8c3c9abe7bf7d4b40a9103452a4519ebd8a8950e 100644 (file)
@@ -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
index 0e9edc171553dcb8ae2df235a2802712f5d5c113..19eb1593388433b2e8273550c808ca007feaf3b5 100644 (file)
@@ -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