asmicon: refresher (untested)
This commit is contained in:
parent
e3ef121440
commit
7c377880fa
|
@ -6,21 +6,23 @@ from milkymist.asmicon.bankmachine import *
|
|||
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
|
||||
|
||||
|
@ -32,12 +34,12 @@ class ASMIcon:
|
|||
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)
|
||||
|
||||
|
@ -47,8 +49,9 @@ class ASMIcon:
|
|||
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)
|
||||
|
|
|
@ -1,5 +1,22 @@
|
|||
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
|
||||
|
|
|
@ -1,8 +1,74 @@
|
|||
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()
|
||||
|
|
7
top.py
7
top.py
|
@ -21,17 +21,18 @@ def ns(t, margin=False):
|
|||
|
||||
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)
|
||||
)
|
||||
|
@ -58,8 +59,8 @@ def get():
|
|||
#
|
||||
# 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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue