diff --git a/litedram/common.py b/litedram/common.py index 4e4fe46..23efa65 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -43,7 +43,7 @@ class GeomSettings: class TimingSettings: - def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC): + def __init__(self, tRP, tRCD, tWR, tWTR, tREFI, tRFC, tFAW, tCCD, tRRD, tRC, tRAS): self.tRP = tRP self.tRCD = tRCD self.tWR = tWR @@ -54,6 +54,7 @@ class TimingSettings: self.tCCD = tCCD self.tRRD = tRRD self.tRC = tRC + self.tRAS = tRAS def cmd_layout(address_width): diff --git a/litedram/core/bankmachine.py b/litedram/core/bankmachine.py index b4fa9bd..cfe3dde 100644 --- a/litedram/core/bankmachine.py +++ b/litedram/core/bankmachine.py @@ -100,12 +100,23 @@ class BankMachine(Module): else: self.comb += activate_allowed.eq(1) + # Respect tRAS activate-precharge time + precharge_allowed = Signal() + if settings.timing.tRAS is not None: + tras_time = settings.timing.tRAS - 1 + tras_timer = WaitTimer(tras_time) + self.submodules += tras_timer + self.comb += tras_timer.wait.eq(~(cmd.valid & cmd.ready & track_open)) + self.comb += precharge_allowed.eq(tras_timer.done) + else: + self.comb += precharge_allowed.eq(1) + # Auto Precharge if settings.with_auto_precharge: self.comb += [ If(cmd_buffer_lookahead.source.valid & cmd_buffer.source.valid, If(slicer.row(cmd_buffer_lookahead.source.addr) != slicer.row(cmd_buffer.source.addr), - auto_precharge.eq((track_close == 0)) + auto_precharge.eq((track_close == 0) & precharge_allowed) ) ) ] @@ -144,7 +155,7 @@ class BankMachine(Module): ) fsm.act("PRECHARGE", # Note: we are presenting the column address, A10 is always low - If(precharge_timer.done, + If(precharge_timer.done & precharge_allowed, cmd.valid.eq(1), If(cmd.ready, NextState("TRP") diff --git a/litedram/modules.py b/litedram/modules.py index 6459511..da6a020 100644 --- a/litedram/modules.py +++ b/litedram/modules.py @@ -35,7 +35,8 @@ class SDRAMModule: tFAW=None if self.get("tFAW") is None else self.ck_ns_to_cycles(*self.get("tFAW")), tCCD=None if self.get("tCCD") is None else self.ck_ns_to_cycles(*self.get("tCCD")), tRRD=None if self.get("tRRD") is None else self.ns_to_cycles_trrd(self.get("tRRD")), - tRC=None if self.get("tRC") is None else self.ns_to_cycles(self.get("tRC")) + tRC=None if self.get("tRC") is None else self.ns_to_cycles(self.get("tRC")), + tRAS=None if self.get("tRAS") is None else self.ns_to_cycles(self.get("tRAS")) ) def get(self, name): @@ -254,6 +255,7 @@ class MT41J128M16(SDRAMModule): tRFC_1066 = 86 tFAW_1066 = (27, None) tRC_1066 = 50.625 + tRAS_1066 = 37.5 # DDR3-1333 tRP_1333 = 13.5 tRCD_1333 = 13.5 @@ -261,6 +263,7 @@ class MT41J128M16(SDRAMModule): tRFC_1333 = 107 tFAW_1333 = (30, None) tRC_1333 = 49.5 + tRAS_1333 = 36 # DDR3-1600 tRP_1600 = 13.75 tRCD_1600 = 13.75 @@ -268,6 +271,7 @@ class MT41J128M16(SDRAMModule): tRFC_1600 = 128 tFAW_1600 = (32, None) tRC_1600 = 48.75 + tRAS_1600 = 35 # API retro-compatibility tRP = tRP_1600 tRCD = tRCD_1600 @@ -275,6 +279,7 @@ class MT41J128M16(SDRAMModule): tRFC = tRFC_1600 tFAW = tFAW_1600 tRC = tRC_1600 + tRAS = tRAS_1600 class MT41K128M16(MT41J128M16):