Skip to content

Commit

Permalink
asmicon: refresher (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastien Bourdeauducq committed Mar 15, 2012
1 parent e3ef121 commit 7c37788
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 14 deletions.
19 changes: 11 additions & 8 deletions milkymist/asmicon/__init__.py
Expand Up @@ -6,21 +6,23 @@
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

Expand All @@ -32,12 +34,12 @@ def __init__(self, phy_settings, geom_settings, timing_settings, time=0):
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)

Expand All @@ -47,8 +49,9 @@ def finalize(self):
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)
Expand Down
17 changes: 17 additions & 0 deletions milkymist/asmicon/multiplexer.py
@@ -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
Expand Down
72 changes: 69 additions & 3 deletions milkymist/asmicon/refresher.py
@@ -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 changes: 4 additions & 3 deletions top.py
Expand Up @@ -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)
)
Expand All @@ -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)

Expand Down

0 comments on commit 7c37788

Please sign in to comment.