from milkymist.asmicon.multiplexer import *
class PhySettings:
- def __init__(self, dfi_a, dfi_ba, dfi_d, nphases, rdphase, wrphase):
+ def __init__(self, dfi_a, dfi_d, nphases, rdphase, wrphase):
+ # NB: dfi_ba is obtained from GeomSettings.bank_a
self.dfi_a = dfi_a
- self.dfi_ba = dfi_ba
self.dfi_d = dfi_d
self.nphases = nphases
self.rdphase = rdphase
self.wrphase = wrphase
class GeomSettings:
- def __init__(self, row_a, col_a):
+ def __init__(self, bank_a, row_a, col_a):
+ self.bank_a = bank_a
self.row_a = row_a
self.col_a = col_a
class TimingSettings:
- def __init__(self, tREFI, tRFC):
+ def __init__(self, tRP, tREFI, tRFC):
+ self.tRP = tRP
self.tREFI = tREFI
self.tRFC = tRFC
self.finalized = False
self.dfi = dfi.Interface(self.phy_settings.dfi_a,
- self.phy_settings.dfi_ba,
+ self.geom_settings.bank_a,
self.phy_settings.dfi_d,
self.phy_settings.nphases)
burst_length = self.phy_settings.nphases*2
self.address_align = log2_int(burst_length)
- aw = self.phy_settings.dfi_ba + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align
+ aw = self.geom_settings.bank_a + self.geom_settings.row_a + self.geom_settings.col_a - self.address_align
dw = self.phy_settings.dfi_d*self.phy_settings.nphases
self.hub = asmibus.Hub(aw, dw, time)
self.finalized = True
self.hub.finalize()
slots = self.hub.get_slots()
- self.refresher = Refresher(self.timing_settings)
- self.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots) for i in range(2**self.phy_settings.dfi_ba)]
+ self.refresher = Refresher(self.phy_settings.dfi_a, self.geom_settings.bank_a,
+ self.timing_settings.tRP, self.timing_settings.tREFI, self.timing_settings.tRFC)
+ self.bank_machines = [BankMachine(self.geom_settings, self.timing_settings, self.address_align, i, slots) for i in range(2**self.geom_settings.bank_a)]
self.multiplexer = Multiplexer(self.phy_settings, self.geom_settings, self.timing_settings,
self.bank_machines, self.refresher,
self.dfi, self.hub)
from migen.fhdl.structure import *
+class CommandRequest:
+ def __init__(self, dfi_a, dfi_ba):
+ self.a = Signal(BV(dfi_a))
+ self.ba = Signal(BV(dfi_ba))
+ self.cas_n = Signal(reset=1)
+ self.ras_n = Signal(reset=1)
+ self.we_n = Signal(reset=1)
+
+class CommandRequestRW(CommandRequest):
+ def __init__(self, dfi_a, dfi_ba, tagbits):
+ CommandRequest.__init__(self, dfi_a, dfi_ba)
+ self.stb = Signal()
+ self.ack = Signal()
+ self.is_read = Signal()
+ self.is_write = Signal()
+ self.tag = Signal(BV(tagbits))
+
class Multiplexer:
def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, hub):
pass
from migen.fhdl.structure import *
+from migen.corelogic.misc import timeline
+from migen.corelogic.fsm import FSM
+
+from milkymist.asmicon.multiplexer import *
class Refresher:
- def __init__(self, timing_settings):
- pass
+ def __init__(self, dfi_a, dfi_ba, tRP, tREFI, tRFC):
+ self.tRP = tRP
+ self.tREFI = tREFI
+ self.tRFC = tRFC
+
+ self.req = Signal()
+ self.ack = Signal()
+ self.cmd_request = CommandRequest(dfi_a, dfi_ba)
def get_fragment(self):
- return Fragment()
+ comb = []
+ sync = []
+
+ # Refresh sequence generator:
+ # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
+ seq_start = Signal()
+ seq_done = Signal()
+ sync += [
+ self.cmd_request.a.eq(2**10),
+ self.cmd_request.ba.eq(0),
+ self.cmd_request.cas_n.eq(1),
+ self.cmd_request.ras_n.eq(1),
+ self.cmd_request.we_n.eq(1)
+ ]
+ sync += timeline(seq_start, [
+ (0, [
+ self.cmd_request.ras_n.eq(0),
+ self.cmd_request.we_n.eq(0)
+ ]),
+ (self.tRP, [
+ self.cmd_request.cas_n.eq(0),
+ self.cmd_request.ras_n.eq(0)
+ ]),
+ (self.tRP+self.tRFC, [
+ seq_done.eq(1)
+ ])
+ ])
+
+ # Periodic refresh counter
+ counter = Signal(BV(bits_for(self.tREFI - 1)))
+ start = Signal()
+ sync += [
+ start.eq(0),
+ If(counter == 0,
+ start.eq(1),
+ counter.eq(self.tREFI - 1)
+ ).Else(
+ counter.eq(counter - 1)
+ )
+ ]
+
+ # Control FSM
+ fsm = FSM("IDLE", "WAIT_GRANT", "WAIT_SEQ")
+ fsm.act(fsm.IDLE, If(start, fsm.next_state(fsm.WAIT_GRANT)))
+ fsm.act(fsm.WAIT_GRANT,
+ self.req.eq(1),
+ If(self.ack,
+ seq_start.eq(1),
+ fsm.next_state(fsm.WAIT_SEQ)
+ )
+ )
+ fsm.act(fsm.WAIT_SEQ,
+ self.req.eq(1),
+ If(seq_done, fsm.next_state(fsm.IDLE))
+ )
+
+ return Fragment(comb, sync) + fsm.get_fragment()
sdram_phy = asmicon.PhySettings(
dfi_a=13,
- dfi_ba=2,
dfi_d=64,
nphases=2,
rdphase=0,
wrphase=1
)
sdram_geom = asmicon.GeomSettings(
+ bank_a=2,
row_a=13,
col_a=10
)
sdram_timing = asmicon.TimingSettings(
+ tRP=ns(15),
tREFI=ns(7800),
tRFC=ns(70)
)
#
# DFI
#
- ddrphy0 = s6ddrphy.S6DDRPHY(sdram_phy.dfi_a, sdram_phy.dfi_ba, sdram_phy.dfi_d)
- dfii0 = dfii.DFIInjector(1, sdram_phy.dfi_a, sdram_phy.dfi_ba, sdram_phy.dfi_d, sdram_phy.nphases)
+ ddrphy0 = s6ddrphy.S6DDRPHY(sdram_phy.dfi_a, sdram_geom.bank_a, sdram_phy.dfi_d)
+ dfii0 = dfii.DFIInjector(1, sdram_phy.dfi_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
dficon1 = dfi.Interconnect(asmicon0.dfi, dfii0.slave)