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.
This commit is contained in:
parent
b0aa5a326d
commit
0e63d2cd62
3 changed files with 93 additions and 3 deletions
|
@ -736,3 +736,88 @@ class LPDDR3_1600_x32(DRAMCtrl):
|
||||||
IDD52 = '150mA'
|
IDD52 = '150mA'
|
||||||
VDD = '1.8V'
|
VDD = '1.8V'
|
||||||
VDD2 = '1.2V'
|
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'
|
||||||
|
|
|
@ -115,6 +115,9 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
|
||||||
for (int b = 0; b < banksPerRank; b++) {
|
for (int b = 0; b < banksPerRank; b++) {
|
||||||
banks[r][b].rank = r;
|
banks[r][b].rank = r;
|
||||||
banks[r][b].bank = b;
|
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) {
|
if (bankGroupArch) {
|
||||||
// Simply assign lower bits to bank group in order to
|
// Simply assign lower bits to bank group in order to
|
||||||
// rotate across bank groups as banks are incremented
|
// rotate across bank groups as banks are incremented
|
||||||
|
@ -224,7 +227,8 @@ DRAMCtrl::DRAMCtrl(const DRAMCtrlParams* p) :
|
||||||
tCCD_L, tBURST, bankGroupsPerRank);
|
tCCD_L, tBURST, bankGroupsPerRank);
|
||||||
}
|
}
|
||||||
// tRRD_L is greater than minimal, same bank group ACT-to-ACT delay
|
// 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 "
|
fatal("tRRD_L (%d) should be larger than tRRD (%d) when "
|
||||||
"bank groups per rank (%d) is greater than 1\n",
|
"bank groups per rank (%d) is greater than 1\n",
|
||||||
tRRD_L, tRRD, bankGroupsPerRank);
|
tRRD_L, tRRD, bankGroupsPerRank);
|
||||||
|
|
|
@ -155,7 +155,8 @@ DRAMPower::getDataRate(const DRAMCtrlParams* p)
|
||||||
{
|
{
|
||||||
uint32_t burst_cycles = divCeil(p->tBURST, p->tCK);
|
uint32_t burst_cycles = divCeil(p->tBURST, p->tCK);
|
||||||
uint8_t data_rate = p->burst_length / burst_cycles;
|
uint8_t data_rate = p->burst_length / burst_cycles;
|
||||||
if (data_rate != 1 && data_rate != 2)
|
// 4 for GDDR5
|
||||||
fatal("Got unexpected data rate %d, should be 1 or 2\n");
|
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;
|
return data_rate;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue