asmicon: refresher (untested)

This commit is contained in:
Sebastien Bourdeauducq 2012-03-15 20:29:26 +01:00
parent e3ef121440
commit 7c377880fa
4 changed files with 101 additions and 14 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
View File

@ -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)