Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/misoc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4acab79987c6
Choose a base ref
...
head repository: m-labs/misoc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: de87d65f6847
Choose a head ref
  • 5 commits
  • 6 files changed
  • 1 contributor

Commits on Aug 22, 2015

  1. README: small update

    enjoy-digital committed Aug 22, 2015

    Verified

    This commit was signed with the committer’s verified signature. The key has expired.
    kalbasit Wael Nasreddine
    Copy the full SHA
    b8f3fd5 View commit details
  2. sdram/phy/s6ddrphy: rename S6DDRPHY to S6HalfRateDDRPHY and use ORed …

    …wrdata_en/rddata_en (the controller already manages that)
    enjoy-digital committed Aug 22, 2015
    Copy the full SHA
    158fbe4 View commit details
  3. 3
    Copy the full SHA
    8bb30a8 View commit details
  4. sdram/phy/s6ddrphy: add S6QuarterRateDDRPHY to run DDR3 at higher fre…

    …quencies.
    
    Built on top of S6HalfRateDDRPHY, exposes a 4 phases DFI interface to the controller with a 2x slower clock.
    Validated on the Numato Lab opsis board (50MHz sys_clk/ DDR400), should also work on the Novena laptop (same DDR3 module).
    enjoy-digital committed Aug 22, 2015
    Copy the full SHA
    50e857e View commit details
  5. Copy the full SHA
    de87d65 View commit details
Showing with 167 additions and 22 deletions.
  1. +3 −1 README
  2. +1 −1 misoclib/com/liteeth/phy/__init__.py
  3. +40 −0 misoclib/mem/sdram/module.py
  4. +113 −10 misoclib/mem/sdram/phy/s6ddrphy.py
  5. +5 −5 targets/mlabs_video.py
  6. +5 −5 targets/pipistrello.py
4 changes: 3 additions & 1 deletion README
Original file line number Diff line number Diff line change
@@ -28,7 +28,8 @@
* Design new peripherals using Migen and benefit from automatic CSR maps
and logic, etc.
* Possibility to encapsulate legacy Verilog/VHDL code.
* Complex FPGA cores that can be used integrated in MiSoC or in standalone:
* Complex FPGA cores that can be used integrated in MiSoC or standalone:
- LitePcie: a small footprint and configuragle PCIe core
- LiteEth: a small footprint and configurable Ethernet core
- LiteSATA: a small footprint and configurable SATA core
- LiteScope: a small footprint and configurable logic analyzer core
@@ -40,6 +41,7 @@ MiSoC comes with built-in support for the following boards:
* Pipistrello, a simple board with USB and HDMI [XC6SLX45]
* De0 Nano, a simple and low-cost development board [CYCLONEIV]
* KC705, a Kintex-7 devboard from Xilinx [XC7K325T]
* Versa, a low-cost Lattice development board [ECP3-35]
MiSoC is portable and support for other boards can easily be added as external
modules.

2 changes: 1 addition & 1 deletion misoclib/com/liteeth/phy/__init__.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@


def LiteEthPHY(clock_pads, pads, **kwargs):
clk_freq = kwargs.pop("clk_freq")
clk_freq = None if "clk_freq" not in kwargs else kwargs.pop("clk_freq")
# Autodetect PHY
if hasattr(pads, "source_stb"):
# This is a simulation PHY
40 changes: 40 additions & 0 deletions misoclib/mem/sdram/module.py
Original file line number Diff line number Diff line change
@@ -165,6 +165,26 @@ def __init__(self, clk_freq):
self.timing_settings)


class P3R1GE4JGF(SDRAMModule):
geom_settings = {
"nbanks": 8,
"nrows": 8192,
"ncols": 1024
}
timing_settings = {
"tRP": 12.5,
"tRCD": 12.5,
"tWR": 15,
"tWTR": 3,
"tREFI": 7800,
"tRFC": 127.5,
}

def __init__(self, clk_freq):
SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
self.timing_settings)


# DDR3
class MT8JTF12864(SDRAMModule):
geom_settings = {
@@ -183,3 +203,23 @@ class MT8JTF12864(SDRAMModule):
def __init__(self, clk_freq):
SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
self.timing_settings)


class MT41J128M16(SDRAMModule):
geom_settings = {
"nbanks": 8,
"nrows": 16384,
"ncols": 1024,
}
timing_settings = {
"tRP": 15,
"tRCD": 15,
"tWR": 15,
"tWTR": 3,
"tREFI": 64*1000*1000/16384,
"tRFC": 260,
}

def __init__(self, clk_freq):
SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
self.timing_settings)
123 changes: 113 additions & 10 deletions misoclib/mem/sdram/phy/s6ddrphy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 1:2 frequency-ratio DDR / LPDDR / DDR2 PHY for Spartan-6
# 1:2 and 1:4 frequency-ratio DDR / LPDDR / DDR2 / DDR3 PHYs for Spartan-6
#
# Assert dfi_wrdata_en and present the data
# on dfi_wrdata_mask/dfi_wrdata in the same
@@ -23,10 +23,10 @@
from misoclib.mem import sdram


class S6DDRPHY(Module):
class S6HalfRateDDRPHY(Module):
def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
if module.memtype not in ["DDR", "LPDDR", "DDR2", "DDR3"]:
raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
raise NotImplementedError("S6HalfRateDDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
@@ -358,30 +358,133 @@ def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
#
# DQ/DQS/DM control
#

# write
wrdata_en = Signal()
self.comb += wrdata_en.eq(optree("|", [d_dfi[p].wrdata_en for p in range(nphases)]))

if module.memtype == "DDR3":
r_drive_dq = Signal(self.settings.cwl-1)
sd_sdram_half += r_drive_dq.eq(Cat(d_dfi[self.settings.wrphase].wrdata_en, r_drive_dq))
sd_sdram_half += r_drive_dq.eq(Cat(wrdata_en, r_drive_dq))
self.comb += drive_dq.eq(r_drive_dq[self.settings.cwl-2])
else:
self.comb += drive_dq.eq(d_dfi[self.settings.wrphase].wrdata_en)
self.comb += drive_dq.eq(wrdata_en)

d_dfi_wrdata_en = Signal()
sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.settings.wrphase].wrdata_en)
wrdata_en_d = Signal()
sd_sys += wrdata_en_d.eq(wrdata_en)

r_dfi_wrdata_en = Signal(max(self.settings.cwl, self.settings.cl))
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en))
sd_sdram_half += r_dfi_wrdata_en.eq(Cat(wrdata_en_d, r_dfi_wrdata_en))

if module.memtype == "DDR3":
self.comb += drive_dqs.eq(r_dfi_wrdata_en[self.settings.cwl-1])
else:
self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])

# read
rddata_en = Signal()
self.comb += rddata_en.eq(optree("|", [d_dfi[p].rddata_en for p in range(nphases)]))

rddata_sr = Signal(self.settings.read_latency)
sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.settings.read_latency],
d_dfi[self.settings.rdphase].rddata_en))
sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.settings.read_latency], rddata_en))

for n, phase in enumerate(self.dfi.phases):
self.comb += [
phase.rddata.eq(d_dfi[n].rddata),
phase.rddata_valid.eq(rddata_sr[0]),
]


class S6QuarterRateDDRPHY(Module):
def __init__(self, pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
if module.memtype not in ["DDR3"]:
raise NotImplementedError("S6QuarterRateDDRPHY only supports DDR3")
half_rate_phy = S6HalfRateDDRPHY(pads, module, rd_bitslip, wr_bitslip, dqs_ddr_alignment)
self.submodules += RenameClockDomains(half_rate_phy, {"sys" : "sys2x"})

addressbits = flen(pads.a)
bankbits = flen(pads.ba)
databits = flen(pads.dq)
nphases = 4

self.settings = sdram.PhySettings(
memtype="DDR3",
dfi_databits=2*databits,
nphases=nphases,
rdphase=0,
wrphase=1,
rdcmdphase=1,
wrcmdphase=0,
cl=5,
cwl=6,
read_latency=6//2+1,
write_latency=2//2
)

self.module = module

self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
self.clk8x_wr_strb = half_rate_phy.clk4x_wr_strb
self.clk8x_rd_strb = half_rate_phy.clk4x_rd_strb

# sys_clk : system clk, used for dfi interface
# sys2x_clk : half rate sys clk
sd_sys = getattr(self.sync, "sys")
sd_sys2x = getattr(self.sync, "sys2x")

# select active sys2x phase
# sys_clk ----____----____
# phase_sel 0 1 0 1
phase_sel = Signal()
phase_sys2x = Signal.like(phase_sel)
phase_sys = Signal.like(phase_sys2x)

sd_sys += phase_sys.eq(phase_sys2x)

sd_sys2x += [
If(phase_sys2x == phase_sys,
phase_sel.eq(0),
).Else(
phase_sel.eq(~phase_sel)
),
phase_sys2x.eq(~phase_sel)
]

# DFI adaptation

# Commands and writes
dfi_leave_out = set(["rddata", "rddata_valid", "wrdata_en"])
self.comb += [
If(~phase_sel,
Record.connect(self.dfi.phases[0], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
Record.connect(self.dfi.phases[1], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
).Else(
Record.connect(self.dfi.phases[2], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
Record.connect(self.dfi.phases[3], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
),
]
wr_data_en = self.dfi.phases[self.settings.wrphase].wrdata_en & ~phase_sel
wr_data_en_d = Signal()
sd_sys2x += wr_data_en_d.eq(wr_data_en)
self.comb += half_rate_phy.dfi.phases[half_rate_phy.settings.wrphase].wrdata_en.eq(wr_data_en | wr_data_en_d)

# Reads
rddata = Array(Signal(2*databits) for i in range(2))
rddata_valid = Signal(2)

for i in range(2):
sd_sys2x += [
rddata_valid[i].eq(half_rate_phy.dfi.phases[i].rddata_valid),
rddata[i].eq(half_rate_phy.dfi.phases[i].rddata)
]

sd_sys += [
self.dfi.phases[0].rddata.eq(rddata[0]),
self.dfi.phases[0].rddata_valid.eq(rddata_valid[0]),
self.dfi.phases[1].rddata.eq(rddata[1]),
self.dfi.phases[1].rddata_valid.eq(rddata_valid[1]),
self.dfi.phases[2].rddata.eq(half_rate_phy.dfi.phases[0].rddata),
self.dfi.phases[2].rddata_valid.eq(half_rate_phy.dfi.phases[0].rddata_valid),
self.dfi.phases[3].rddata.eq(half_rate_phy.dfi.phases[1].rddata),
self.dfi.phases[3].rddata_valid.eq(half_rate_phy.dfi.phases[1].rddata_valid)
]
10 changes: 5 additions & 5 deletions targets/mlabs_video.py
Original file line number Diff line number Diff line change
@@ -82,11 +82,11 @@ def __init__(self, platform, sdram_controller_settings=LASMIconSettings(), **kwa
self.submodules.crg = _MXCRG(_MXClockPads(platform), self.clk_freq)

if not self.integrated_main_ram_size:
self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"),
MT46V32M16(self.clk_freq),
rd_bitslip=0,
wr_bitslip=3,
dqs_ddr_alignment="C1")
self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY(platform.request("ddram"),
MT46V32M16(self.clk_freq),
rd_bitslip=0,
wr_bitslip=3,
dqs_ddr_alignment="C1")
self.register_sdram_phy(self.ddrphy)
self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
10 changes: 5 additions & 5 deletions targets/pipistrello.py
Original file line number Diff line number Diff line change
@@ -108,11 +108,11 @@ def __init__(self, platform, sdram_controller_settings=LASMIconSettings(),
self.submodules.crg = _CRG(platform, clk_freq)

if not self.integrated_main_ram_size:
self.submodules.ddrphy = s6ddrphy.S6DDRPHY(platform.request("ddram"),
MT46H32M16(self.clk_freq),
rd_bitslip=1,
wr_bitslip=3,
dqs_ddr_alignment="C1")
self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY(platform.request("ddram"),
MT46H32M16(self.clk_freq),
rd_bitslip=1,
wr_bitslip=3,
dqs_ddr_alignment="C1")
self.comb += [
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb),