sdram: use names that are more explicit for bank_a, row_a,...: bankbits, rowbits, .... Add databits to GeomSettings.

This commit is contained in:
Florent Kermarrec 2015-03-24 17:25:59 +01:00
parent 73c2b7ebaa
commit 7ea9e2ba89
15 changed files with 140 additions and 132 deletions

View file

@ -1,11 +1,11 @@
from collections import namedtuple
PhySettingsT = namedtuple("PhySettings", "memtype dfi_d nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency")
def PhySettings(memtype, dfi_d, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, read_latency, write_latency, cwl=0):
return PhySettingsT(memtype, dfi_d, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, cwl, read_latency, write_latency)
PhySettingsT = namedtuple("PhySettings", "memtype dfi_databits nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency")
def PhySettings(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, read_latency, write_latency, cwl=0):
return PhySettingsT(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, cwl, read_latency, write_latency)
GeomSettingsT = namedtuple("_GeomSettings", "bank_a row_a col_a mux_a")
def GeomSettings(bank_a, row_a, col_a):
return GeomSettingsT(bank_a, row_a, col_a, max(row_a, col_a))
GeomSettingsT = namedtuple("_GeomSettings", "databits bankbits rowbits colbits addressbits")
def GeomSettings(databits, bankbits, rowbits, colbits):
return GeomSettingsT(databits, bankbits, rowbits, colbits, max(rowbits, colbits))
TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC")

View file

@ -9,8 +9,8 @@ from misoclib.mem.sdram.core import lasmixbar
class SDRAMCore(Module, AutoCSR):
def __init__(self, phy, geom_settings, timing_settings, controller_settings, **kwargs):
# DFI
self.submodules.dfii = dfii.DFIInjector(geom_settings.mux_a, geom_settings.bank_a,
phy.settings.dfi_d, phy.settings.nphases)
self.submodules.dfii = dfii.DFIInjector(geom_settings.addressbits, geom_settings.bankbits,
phy.settings.dfi_databits, phy.settings.nphases)
self.comb += Record.connect(self.dfii.master, phy.dfi)
# LASMICON

View file

@ -28,26 +28,26 @@ class LASMIcon(Module):
burst_length = phy_settings.nphases*2 # command multiplication*DDR
address_align = log2_int(burst_length)
self.dfi = dfi.Interface(geom_settings.mux_a,
geom_settings.bank_a,
phy_settings.dfi_d,
self.dfi = dfi.Interface(geom_settings.addressbits,
geom_settings.bankbits,
phy_settings.dfi_databits,
phy_settings.nphases)
self.lasmic = lasmibus.Interface(
aw=geom_settings.row_a + geom_settings.col_a - address_align,
dw=phy_settings.dfi_d*phy_settings.nphases,
nbanks=2**geom_settings.bank_a,
aw=geom_settings.rowbits + geom_settings.colbits - address_align,
dw=phy_settings.dfi_databits*phy_settings.nphases,
nbanks=2**geom_settings.bankbits,
req_queue_size=controller_settings.req_queue_size,
read_latency=phy_settings.read_latency+1,
write_latency=phy_settings.write_latency+1)
self.nrowbits = geom_settings.col_a - address_align
self.nrowbits = geom_settings.colbits - address_align
###
self.submodules.refresher = Refresher(geom_settings.mux_a, geom_settings.bank_a,
self.submodules.refresher = Refresher(geom_settings.addressbits, geom_settings.bankbits,
timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, controller_settings, address_align, i,
getattr(self.lasmic, "bank"+str(i)))
for i in range(2**geom_settings.bank_a)]
for i in range(2**geom_settings.bankbits)]
self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings, controller_settings,
self.bank_machines, self.refresher,
self.dfi, self.lasmic,

View file

@ -7,19 +7,19 @@ from migen.genlib.fifo import SyncFIFO
from misoclib.mem.sdram.core.lasmicon.multiplexer import *
class _AddressSlicer:
def __init__(self, col_a, address_align):
self.col_a = col_a
def __init__(self, colbits, address_align):
self.colbits = colbits
self.address_align = address_align
def row(self, address):
split = self.col_a - self.address_align
split = self.colbits - self.address_align
if isinstance(address, int):
return address >> split
else:
return address[split:]
def col(self, address):
split = self.col_a - self.address_align
split = self.colbits - self.address_align
if isinstance(address, int):
return (address & (2**split - 1)) << self.address_align
else:
@ -29,7 +29,7 @@ class BankMachine(Module):
def __init__(self, geom_settings, timing_settings, controller_settings, address_align, bankn, req):
self.refresh_req = Signal()
self.refresh_gnt = Signal()
self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a)
self.cmd = CommandRequestRW(geom_settings.addressbits, geom_settings.bankbits)
###
@ -46,11 +46,11 @@ class BankMachine(Module):
]
reqf = self.req_fifo.dout
slicer = _AddressSlicer(geom_settings.col_a, address_align)
slicer = _AddressSlicer(geom_settings.colbits, address_align)
# Row tracking
has_openrow = Signal()
openrow = Signal(geom_settings.row_a)
openrow = Signal(geom_settings.rowbits)
hit = Signal()
self.comb += hit.eq(openrow == slicer.row(reqf.adr))
track_open = Signal()

View file

@ -108,7 +108,7 @@ class Multiplexer(Module, AutoCSR):
]
# Command steering
nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
nop = CommandRequest(geom_settings.addressbits, geom_settings.bankbits)
commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
(STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
steerer = _Steerer(commands, dfi)

View file

@ -5,30 +5,30 @@ from migen.genlib.fsm import FSM, NextState
from misoclib.mem.sdram.phy import dfi as dfibus
class _AddressSlicer:
def __init__(self, col_a, bank_a, row_a, address_align):
self.col_a = col_a
self.bank_a = bank_a
self.row_a = row_a
self.max_a = col_a + row_a + bank_a
def __init__(self, colbits, bankbits, rowbits, address_align):
self.colbits = colbits
self.bankbits = bankbits
self.rowbits = rowbits
self.max_a = colbits + rowbits + bankbits
self.address_align = address_align
def row(self, address):
split = self.bank_a + self.col_a
split = self.bankbits + self.colbits
if isinstance(address, int):
return address >> split
else:
return address[split:self.max_a]
def bank(self, address):
mask = 2**(self.bank_a + self.col_a) - 1
shift = self.col_a
mask = 2**(self.bankbits + self.colbits) - 1
shift = self.colbits
if isinstance(address, int):
return (address & mask) >> shift
else:
return address[self.col_a:self.col_a+self.bank_a]
return address[self.colbits:self.colbits+self.bankbits]
def col(self, address):
split = self.col_a
split = self.colbits
if isinstance(address, int):
return (address & (2**split - 1)) << self.address_align
else:
@ -46,20 +46,20 @@ class Minicon(Module):
burst_length = phy_settings.nphases*2 # command multiplication*DDR
address_align = log2_int(burst_length)
nbanks = range(2**geom_settings.bank_a)
nbanks = range(2**geom_settings.bankbits)
A10_ENABLED = 0
COLUMN = 1
ROW = 2
rdphase = phy_settings.rdphase
wrphase = phy_settings.wrphase
self.dfi = dfi = dfibus.Interface(geom_settings.mux_a,
geom_settings.bank_a,
phy_settings.dfi_d,
self.dfi = dfi = dfibus.Interface(geom_settings.addressbits,
geom_settings.bankbits,
phy_settings.dfi_databits,
phy_settings.nphases)
self.bus = bus = wishbone.Interface(data_width=phy_settings.nphases*flen(dfi.phases[rdphase].rddata))
slicer = _AddressSlicer(geom_settings.col_a, geom_settings.bank_a, geom_settings.row_a, address_align)
slicer = _AddressSlicer(geom_settings.colbits, geom_settings.bankbits, geom_settings.rowbits, address_align)
refresh_req = Signal()
refresh_ack = Signal()
refresh_counter = Signal(max=timing_settings.tREFI+1)
@ -70,7 +70,7 @@ class Minicon(Module):
has_curbank_openrow = Signal()
# Extra bit means row is active when asserted
self.openrow = openrow = Array(Signal(geom_settings.row_a + 1) for b in nbanks)
self.openrow = openrow = Array(Signal(geom_settings.rowbits + 1) for b in nbanks)
self.comb += [
hit.eq(openrow[slicer.bank(bus.adr)] == Cat(slicer.row(bus.adr), 1)),

View file

@ -24,9 +24,10 @@ class SDRAMModule:
def __init__(self, clk_freq, geom_settings, timing_settings):
self.clk_freq = clk_freq
self.geom_settings = sdram.GeomSettings(
bank_a=log2_int(geom_settings["nbanks"]),
row_a=log2_int(geom_settings["nrows"]),
col_a=log2_int(geom_settings["ncols"])
databits=geom_settings["nbits"],
bankbits=log2_int(geom_settings["nbanks"]),
rowbits=log2_int(geom_settings["nrows"]),
colbits=log2_int(geom_settings["ncols"]),
)
self.timing_settings = sdram.TimingSettings(
tRP=self.ns(timing_settings["tRP"]),
@ -46,6 +47,7 @@ class SDRAMModule:
# SDR
class IS42S16160(SDRAMModule):
geom_settings = {
"nbits": 16,
"nbanks": 4,
"nrows": 8192,
"ncols": 512
@ -65,6 +67,7 @@ class IS42S16160(SDRAMModule):
class MT48LC4M16(SDRAMModule):
geom_settings = {
"nbits": 16,
"nbanks": 4,
"nrows": 4096,
"ncols": 256
@ -83,6 +86,7 @@ class MT48LC4M16(SDRAMModule):
class AS4C16M16(SDRAMModule):
geom_settings = {
"nbits": 16,
"nbanks": 4,
"nrows": 8192,
"ncols": 512
@ -103,6 +107,7 @@ class AS4C16M16(SDRAMModule):
# DDR
class MT46V32M16(SDRAMModule):
geom_settings = {
"nbits": 16,
"nbanks": 4,
"nrows": 8192,
"ncols": 1024
@ -122,6 +127,7 @@ class MT46V32M16(SDRAMModule):
# LPDDR
class MT46H32M16(SDRAMModule):
geom_settings = {
"nbits": 16,
"nbanks": 4,
"nrows": 8192,
"ncols": 1024
@ -141,6 +147,7 @@ class MT46H32M16(SDRAMModule):
# DDR2
class MT47H128M8(SDRAMModule):
geom_settings = {
"nbits": 8,
"nbanks": 8,
"nrows": 16384,
"ncols": 1024
@ -160,6 +167,7 @@ class MT47H128M8(SDRAMModule):
# DDR3
class MT8JTF12864(SDRAMModule):
geom_settings = {
"nbits": 8,
"nbanks": 8,
"nrows": 65536,
"ncols": 1024

View file

@ -1,42 +1,42 @@
from migen.fhdl.std import *
from migen.genlib.record import *
def phase_cmd_description(a, ba):
def phase_cmd_description(addressbits, bankbits):
return [
("address", a, DIR_M_TO_S),
("bank", ba, DIR_M_TO_S),
("cas_n", 1, DIR_M_TO_S),
("cs_n", 1, DIR_M_TO_S),
("ras_n", 1, DIR_M_TO_S),
("we_n", 1, DIR_M_TO_S),
("cke", 1, DIR_M_TO_S),
("odt", 1, DIR_M_TO_S),
("reset_n", 1, DIR_M_TO_S)
("address", addressbits, DIR_M_TO_S),
("bank", bankbits, DIR_M_TO_S),
("cas_n", 1, DIR_M_TO_S),
("cs_n", 1, DIR_M_TO_S),
("ras_n", 1, DIR_M_TO_S),
("we_n", 1, DIR_M_TO_S),
("cke", 1, DIR_M_TO_S),
("odt", 1, DIR_M_TO_S),
("reset_n", 1, DIR_M_TO_S)
]
def phase_wrdata_description(d):
def phase_wrdata_description(databits):
return [
("wrdata", d, DIR_M_TO_S),
("wrdata_en", 1, DIR_M_TO_S),
("wrdata_mask", d//8, DIR_M_TO_S)
("wrdata", databits, DIR_M_TO_S),
("wrdata_en", 1, DIR_M_TO_S),
("wrdata_mask", databits//8, DIR_M_TO_S)
]
def phase_rddata_description(d):
def phase_rddata_description(databits):
return [
("rddata_en", 1, DIR_M_TO_S),
("rddata", d, DIR_S_TO_M),
("rddata_valid", 1, DIR_S_TO_M)
("rddata_en", 1, DIR_M_TO_S),
("rddata", databits, DIR_S_TO_M),
("rddata_valid", 1, DIR_S_TO_M)
]
def phase_description(a, ba, d):
r = phase_cmd_description(a, ba)
r += phase_wrdata_description(d)
r += phase_rddata_description(d)
def phase_description(addressbits, bankbits, databits):
r = phase_cmd_description(addressbits, bankbits)
r += phase_wrdata_description(databits)
r += phase_rddata_description(databits)
return r
class Interface(Record):
def __init__(self, a, ba, d, nphases=1):
layout = [("p"+str(i), phase_description(a, ba, d)) for i in range(nphases)]
def __init__(self, addressbits, bankbits, databits, nphases=1):
layout = [("p"+str(i), phase_description(addressbits, bankbits, databits)) for i in range(nphases)]
Record.__init__(self, layout)
self.phases = [getattr(self, "p"+str(i)) for i in range(nphases)]
for p in self.phases:

View file

@ -36,10 +36,10 @@ class PhaseInjector(Module, AutoCSR):
self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
class DFIInjector(Module, AutoCSR):
def __init__(self, a, ba, d, nphases=1):
inti = dfi.Interface(a, ba, d, nphases)
self.slave = dfi.Interface(a, ba, d, nphases)
self.master = dfi.Interface(a, ba, d, nphases)
def __init__(self, addressbits, bankbits, databits, nphases=1):
inti = dfi.Interface(addressbits, bankbits, databits, nphases)
self.slave = dfi.Interface(addressbits, bankbits, databits, nphases)
self.master = dfi.Interface(addressbits, bankbits, databits, nphases)
self._control = CSRStorage(4) # sel, cke, odt, reset_n

View file

@ -30,13 +30,13 @@ from misoclib.mem import sdram
class GENSDRPHY(Module):
def __init__(self, pads):
a = flen(pads.a)
ba = flen(pads.ba)
d = flen(pads.dq)
addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
self.settings = sdram.PhySettings(
memtype="SDR",
dfi_d=d,
dfi_databits=databits,
nphases=1,
rdphase=0,
wrphase=0,
@ -47,7 +47,7 @@ class GENSDRPHY(Module):
write_latency=0
)
self.dfi = Interface(a, ba, d)
self.dfi = Interface(addressbits, bankbits, databits)
###
@ -63,14 +63,14 @@ class GENSDRPHY(Module):
pads.we_n.eq(self.dfi.p0.we_n)
]
if hasattr(pads, "cs_n"):
self.sync += pads.cs_n.eq(self.dfi.p0.cs_n),
self.sync += pads.cs_n.eq(self.dfi.p0.cs_n)
#
# DQ/DQS/DM data
#
sd_dq_out = Signal(d)
sd_dq_out = Signal(databits)
drive_dq = Signal()
self.sync += sd_dq_out.eq(self.dfi.p0.wrdata),
self.sync += sd_dq_out.eq(self.dfi.p0.wrdata)
self.specials += Tristate(pads.dq, sd_dq_out, drive_dq)
self.sync += \
If(self.dfi.p0.wrdata_en,
@ -78,7 +78,7 @@ class GENSDRPHY(Module):
).Else(
pads.dm.eq(0)
)
sd_dq_in_ps = Signal(d)
sd_dq_in_ps = Signal(databits)
self.sync.sys_ps += sd_dq_in_ps.eq(pads.dq)
self.sync += self.dfi.p0.rddata.eq(sd_dq_in_ps)

View file

@ -8,14 +8,14 @@ from misoclib.mem import sdram
class K7DDRPHY(Module, AutoCSR):
def __init__(self, pads, memtype):
a = flen(pads.a)
ba = flen(pads.ba)
d = flen(pads.dq)
addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
nphases = 4
self._wlevel_en = CSRStorage()
self._wlevel_strobe = CSR()
self._dly_sel = CSRStorage(d//8)
self._dly_sel = CSRStorage(databits//8)
self._rdly_dq_rst = CSR()
self._rdly_dq_inc = CSR()
self._rdly_dq_bitslip = CSR()
@ -26,7 +26,7 @@ class K7DDRPHY(Module, AutoCSR):
self.settings = sdram.PhySettings(
memtype=memtype,
dfi_d=2*d,
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=2,
@ -38,7 +38,7 @@ class K7DDRPHY(Module, AutoCSR):
write_latency=2
)
self.dfi = Interface(a, ba, self.settings.dfi_d, nphases)
self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
###
@ -65,7 +65,7 @@ class K7DDRPHY(Module, AutoCSR):
]
# Addresses and commands
for i in range(a):
for i in range(addressbits):
self.specials += \
Instance("OSERDESE2",
p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
@ -81,7 +81,7 @@ class K7DDRPHY(Module, AutoCSR):
i_D5=self.dfi.phases[2].address[i], i_D6=self.dfi.phases[2].address[i],
i_D7=self.dfi.phases[3].address[i], i_D8=self.dfi.phases[3].address[i]
)
for i in range(ba):
for i in range(bankbits):
self.specials += \
Instance("OSERDESE2",
p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
@ -127,7 +127,7 @@ class K7DDRPHY(Module, AutoCSR):
).Else(
dqs_serdes_pattern.eq(0b01010101)
)
for i in range(d//8):
for i in range(databits//8):
dm_o_nodelay = Signal()
self.specials += \
Instance("OSERDESE2",
@ -139,10 +139,10 @@ class K7DDRPHY(Module, AutoCSR):
i_OCE=1,
i_RST=ResetSignal(),
i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
i_D1=self.dfi.phases[0].wrdata_mask[i], i_D2=self.dfi.phases[0].wrdata_mask[d//8+i],
i_D3=self.dfi.phases[1].wrdata_mask[i], i_D4=self.dfi.phases[1].wrdata_mask[d//8+i],
i_D5=self.dfi.phases[2].wrdata_mask[i], i_D6=self.dfi.phases[2].wrdata_mask[d//8+i],
i_D7=self.dfi.phases[3].wrdata_mask[i], i_D8=self.dfi.phases[3].wrdata_mask[d//8+i]
i_D1=self.dfi.phases[0].wrdata_mask[i], i_D2=self.dfi.phases[0].wrdata_mask[databits//8+i],
i_D3=self.dfi.phases[1].wrdata_mask[i], i_D4=self.dfi.phases[1].wrdata_mask[databits//8+i],
i_D5=self.dfi.phases[2].wrdata_mask[i], i_D6=self.dfi.phases[2].wrdata_mask[databits//8+i],
i_D7=self.dfi.phases[3].wrdata_mask[i], i_D8=self.dfi.phases[3].wrdata_mask[databits//8+i]
)
self.specials += \
Instance("ODELAYE2",
@ -197,7 +197,7 @@ class K7DDRPHY(Module, AutoCSR):
# DQ
oe_dq = Signal()
for i in range(d):
for i in range(databits):
dq_o_nodelay = Signal()
dq_o_delayed = Signal()
dq_i_nodelay = Signal()
@ -213,10 +213,10 @@ class K7DDRPHY(Module, AutoCSR):
i_OCE=1, i_TCE=1,
i_RST=ResetSignal(),
i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
i_D1=self.dfi.phases[0].wrdata[i], i_D2=self.dfi.phases[0].wrdata[d+i],
i_D3=self.dfi.phases[1].wrdata[i], i_D4=self.dfi.phases[1].wrdata[d+i],
i_D5=self.dfi.phases[2].wrdata[i], i_D6=self.dfi.phases[2].wrdata[d+i],
i_D7=self.dfi.phases[3].wrdata[i], i_D8=self.dfi.phases[3].wrdata[d+i],
i_D1=self.dfi.phases[0].wrdata[i], i_D2=self.dfi.phases[0].wrdata[databits+i],
i_D3=self.dfi.phases[1].wrdata[i], i_D4=self.dfi.phases[1].wrdata[databits+i],
i_D5=self.dfi.phases[2].wrdata[i], i_D6=self.dfi.phases[2].wrdata[databits+i],
i_D7=self.dfi.phases[3].wrdata[i], i_D8=self.dfi.phases[3].wrdata[databits+i],
i_T1=~oe_dq
),
Instance("ISERDESE2",
@ -229,10 +229,10 @@ class K7DDRPHY(Module, AutoCSR):
i_RST=ResetSignal() | (self._dly_sel.storage[i//8] & self._wdly_dq_rst.re),
i_CLK=ClockSignal("sys4x"), i_CLKB=~ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
i_BITSLIP=self._dly_sel.storage[i//8] & self._rdly_dq_bitslip.re,
o_Q8=self.dfi.phases[0].rddata[i], o_Q7=self.dfi.phases[0].rddata[d+i],
o_Q6=self.dfi.phases[1].rddata[i], o_Q5=self.dfi.phases[1].rddata[d+i],
o_Q4=self.dfi.phases[2].rddata[i], o_Q3=self.dfi.phases[2].rddata[d+i],
o_Q2=self.dfi.phases[3].rddata[i], o_Q1=self.dfi.phases[3].rddata[d+i]
o_Q8=self.dfi.phases[0].rddata[i], o_Q7=self.dfi.phases[0].rddata[databits+i],
o_Q6=self.dfi.phases[1].rddata[i], o_Q5=self.dfi.phases[1].rddata[databits+i],
o_Q4=self.dfi.phases[2].rddata[i], o_Q3=self.dfi.phases[2].rddata[databits+i],
o_Q2=self.dfi.phases[3].rddata[i], o_Q1=self.dfi.phases[3].rddata[databits+i]
),
Instance("ODELAYE2",
p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",

View file

@ -24,14 +24,14 @@ class S6DDRPHY(Module):
def __init__(self, pads, memtype, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
if memtype not in ["DDR", "LPDDR", "DDR2"]:
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
a = flen(pads.a)
ba = flen(pads.ba)
d = flen(pads.dq)
addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
nphases = 2
self.settings = sdram.PhySettings(
memtype=memtype,
dfi_d=2*d,
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=1,
@ -42,7 +42,7 @@ class S6DDRPHY(Module):
write_latency=0
)
self.dfi = Interface(a, ba, self.settings.dfi_d, nphases)
self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
self.clk4x_wr_strb = Signal()
self.clk4x_rd_strb = Signal()
@ -80,7 +80,7 @@ class S6DDRPHY(Module):
]
# register dfi cmds on half_rate clk
r_dfi = Array(Record(phase_cmd_description(a, ba)) for i in range(nphases))
r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
for n, phase in enumerate(self.dfi.phases):
sd_sdram_half +=[
r_dfi[n].address.eq(phase.address),
@ -130,15 +130,15 @@ class S6DDRPHY(Module):
dqs_t_d0 = Signal()
dqs_t_d1 = Signal()
dqs_o = Signal(d//8)
dqs_t = Signal(d//8)
dqs_o = Signal(databits//8)
dqs_t = Signal(databits//8)
self.comb += [
dqs_t_d0.eq(~(drive_dqs | postamble)),
dqs_t_d1.eq(~drive_dqs),
]
for i in range(d//8):
for i in range(databits//8):
# DQS output
self.specials += Instance("ODDR2",
p_DDR_ALIGNMENT=dqs_ddr_alignment,
@ -194,7 +194,7 @@ class S6DDRPHY(Module):
sd_sdram_half += postamble.eq(drive_dqs)
d_dfi = [Record(phase_wrdata_description(nphases*d)+phase_rddata_description(nphases*d))
d_dfi = [Record(phase_wrdata_description(nphases*databits)+phase_rddata_description(nphases*databits))
for i in range(2*nphases)]
for n, phase in enumerate(self.dfi.phases):
@ -215,17 +215,17 @@ class S6DDRPHY(Module):
self.comb += drive_dq_n[0].eq(~drive_dq)
sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
dq_t = Signal(d)
dq_o = Signal(d)
dq_i = Signal(d)
dq_t = Signal(databits)
dq_o = Signal(databits)
dq_i = Signal(databits)
dq_wrdata = []
for i in range(2):
for j in reversed(range(nphases)):
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:d])
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[d:])
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:databits])
dq_wrdata.append(d_dfi[i*nphases+j].wrdata[databits:])
for i in range(d):
for i in range(databits):
# Data serializer
self.specials += Instance("OSERDES2",
p_DATA_WIDTH=4,
@ -277,9 +277,9 @@ class S6DDRPHY(Module):
i_CLKDIV=sys_clk,
i_BITSLIP=bitslip_inc,
o_Q1=d_dfi[0*nphases+0].rddata[i+d],
o_Q1=d_dfi[0*nphases+0].rddata[i+databits],
o_Q2=d_dfi[0*nphases+0].rddata[i],
o_Q3=d_dfi[0*nphases+1].rddata[i+d],
o_Q3=d_dfi[0*nphases+1].rddata[i+databits],
o_Q4=d_dfi[0*nphases+1].rddata[i],
)
@ -294,10 +294,10 @@ class S6DDRPHY(Module):
dq_wrdata_mask = []
for i in range(2):
for j in reversed(range(nphases)):
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:d//8])
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[d//8:])
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:databits//8])
dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[databits//8:])
for i in range(d//8):
for i in range(databits//8):
# Mask serializer
self.specials += Instance("OSERDES2",
p_DATA_WIDTH=4,

View file

@ -16,7 +16,7 @@ def ns(t, margin=True):
sdram_phy = sdram.PhySettings(
memtype="DDR",
dfi_d=64,
dfi_databits=64,
nphases=2,
rdphase=0,
wrphase=1,
@ -28,9 +28,9 @@ sdram_phy = sdram.PhySettings(
)
sdram_geom = sdram.GeomSettings(
bank_a=2,
row_a=13,
col_a=10
bankbits=2,
rowbits=13,
colbits=10
)
sdram_timing = sdram.TimingSettings(
tRP=ns(15),

View file

@ -154,9 +154,9 @@ if __name__ == "__main__":
plat = board.Platform()
sdram_geom = sdram.GeomSettings(
bank_a=2,
row_a=12,
col_a=8
bankbits=2,
rowbits=12,
colbits=8
)
sdram_timing = sdram.TimingSettings(

View file

@ -63,7 +63,7 @@ class SDRAMSoC(SoC):
# MINICON frontend
elif isinstance(self.sdram_controller_settings, MiniconSettings):
sdram_width = flen(self.sdram.controller.bus.dat_r)
main_ram_size = 2**(geom_settings.bank_a+geom_settings.row_a+geom_settings.col_a)*sdram_width//8
main_ram_size = 2**(geom_settings.bankbits+geom_settings.rowbits+geom_settings.colbits)*sdram_width//8
if sdram_width == 32:
self.register_mem("main_ram", self.mem_map["main_ram"], self.sdram.controller.bus, main_ram_size)