From 0e63d2cd62bbab47a5b05b9b5bee8c1dc0da1683 Mon Sep 17 00:00:00 2001 From: Omar Naji Date: Tue, 2 Dec 2014 06:07:32 -0500 Subject: [PATCH] mem: Add a GDDR5 DRAM config This patch adds a first cut GDDR5 config to accommodate the users combining gem5 and GPUSim. The config is based on a SK Hynix datasheet, and the Nvidia GTX580 specification. Someone from the GPUSim user-camp should tweak the default page-policy and static frontend and backend latencies. --- src/mem/DRAMCtrl.py | 85 ++++++++++++++++++++++++++++++++++++++++++++ src/mem/dram_ctrl.cc | 6 +++- src/mem/drampower.cc | 5 +-- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/src/mem/DRAMCtrl.py b/src/mem/DRAMCtrl.py index 74fb7c7be..4c500960a 100644 --- a/src/mem/DRAMCtrl.py +++ b/src/mem/DRAMCtrl.py @@ -736,3 +736,88 @@ class LPDDR3_1600_x32(DRAMCtrl): IDD52 = '150mA' VDD = '1.8V' VDD2 = '1.2V' + +# A single GDDR5 x64 interface, with +# default timings based on a GDDR5-4000 1 Gbit part (SK Hynix +# H5GQ1H24AFR) in a 2x32 configuration. +class GDDR5_4000_x64(DRAMCtrl): + # size of device + device_size = '128MB' + + # 2x32 configuration, 1 device with a 32-bit interface + device_bus_width = 32 + + # GDDR5 is a BL8 device + burst_length = 8 + + # Each device has a page (row buffer) size of 2Kbits (256Bytes) + device_rowbuffer_size = '256B' + + # 2x32 configuration, so 2 devices + devices_per_rank = 2 + + # assume single rank + ranks_per_channel = 1 + + # GDDR5 has 4 bank groups + bank_groups_per_rank = 4 + + # GDDR5 has 16 banks with 4 bank groups + banks_per_rank = 16 + + # 1000 MHz + tCK = '1ns' + + # 8 beats across an x64 interface translates to 2 clocks @ 1000 MHz + # Data bus runs @2000 Mhz => DDR ( data runs at 4000 MHz ) + # 8 beats at 4000 MHz = 2 beats at 1000 MHz + # tBURST is equivalent to the CAS-to-CAS delay (tCCD) + # With bank group architectures, tBURST represents the CAS-to-CAS + # delay for bursts to different bank groups (tCCD_S) + tBURST = '2ns' + + # @1000MHz data rate, tCCD_L is 3 CK + # CAS-to-CAS delay for bursts to the same bank group + # tBURST is equivalent to tCCD_S; no explicit parameter required + # for CAS-to-CAS delay for bursts to different bank groups + tCCD_L = '3ns'; + + tRCD = '12ns' + + # tCL is not directly found in datasheet and assumed equal tRCD + tCL = '12ns' + + tRP = '12ns' + tRAS = '28ns' + + # RRD_S (different bank group) + # RRD_S is 5.5 ns in datasheet. + # rounded to the next multiple of tCK + tRRD = '6ns' + + # RRD_L (same bank group) + # RRD_L is 5.5 ns in datasheet. + # rounded to the next multiple of tCK + tRRD_L = '6ns' + + tXAW = '23ns' + + # tXAW < 4 x tRRD. + # Therefore, activation limit is set to 0 + activation_limit = 0 + + tRFC = '65ns' + tWR = '12ns' + + # Here using the average of WTR_S and WTR_L + tWTR = '5ns' + + # Read-to-Precharge 2 CK + tRTP = '2ns' + + # Assume 2 cycles + tRTW = '2ns' + + # Default different rank bus delay to 2 CK, @1000 MHz = 2 ns + tCS = '2ns' + tREFI = '3.9us' diff --git a/src/mem/dram_ctrl.cc b/src/mem/dram_ctrl.cc index 1beebdd01..8378debf1 100644 --- a/src/mem/dram_ctrl.cc +++ b/src/mem/dram_ctrl.cc @@ -115,6 +115,9 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : for (int b = 0; b < banksPerRank; b++) { banks[r][b].rank = r; banks[r][b].bank = b; + // GDDR addressing of banks to BG is linear. + // Here we assume that all DRAM generations address bank groups as + // follows: if (bankGroupArch) { // Simply assign lower bits to bank group in order to // rotate across bank groups as banks are incremented @@ -224,7 +227,8 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) : tCCD_L, tBURST, bankGroupsPerRank); } // tRRD_L is greater than minimal, same bank group ACT-to-ACT delay - if (tRRD_L <= tRRD) { + // some datasheets might specify it equal to tRRD + if (tRRD_L < tRRD) { fatal("tRRD_L (%d) should be larger than tRRD (%d) when " "bank groups per rank (%d) is greater than 1\n", tRRD_L, tRRD, bankGroupsPerRank); diff --git a/src/mem/drampower.cc b/src/mem/drampower.cc index a7339656a..c15379d92 100644 --- a/src/mem/drampower.cc +++ b/src/mem/drampower.cc @@ -155,7 +155,8 @@ DRAMPower::getDataRate(const DRAMCtrlParams* p) { uint32_t burst_cycles = divCeil(p->tBURST, p->tCK); uint8_t data_rate = p->burst_length / burst_cycles; - if (data_rate != 1 && data_rate != 2) - fatal("Got unexpected data rate %d, should be 1 or 2\n"); + // 4 for GDDR5 + if (data_rate != 1 && data_rate != 2 && data_rate != 4) + fatal("Got unexpected data rate %d, should be 1 or 2 or 4\n"); return data_rate; }