From df9efa99db8f25402f4fe50f69e4d9f991e5d6c8 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 20 Feb 2022 00:00:01 +0000 Subject: [PATCH] add fake (sim) DRAM from gram library --- src/ls2.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/ls2.py b/src/ls2.py index 2d5807f..f564b46 100644 --- a/src/ls2.py +++ b/src/ls2.py @@ -25,8 +25,12 @@ from soc.bus.external_core import ExternalCore # external libresoc/microwatt from soc.bus.wb_downconvert import WishboneDownConvert from soc.bus.syscon import MicrowattSYSCON +from gram.common import (PhySettings, get_cl_cw, get_sys_latency, + get_sys_phases,) +from nmigen.utils import log2_int from gram.core import gramCore from gram.phy.ecp5ddrphy import ECP5DDRPHY +from gram.phy.fakephy import FakePHY, SDRAM_VERBOSE_STD, SDRAM_VERBOSE_DBG from gram.modules import MT41K256M16, MT41K64M16 from gram.frontend.wishbone import gramWishbone @@ -40,9 +44,41 @@ from crg import ECPIX5CRG import sys import os +def sim_ddr3_settings(clk_freq=100e6): + tck = 2/(2*2*clk_freq) + nphases = 2 + databits = 16 + nranks = 1 + addressbits = 14 + bankbits = 3 + cl, cwl = get_cl_cw("DDR3", tck) + cl_sys_latency = get_sys_latency(nphases, cl) + cwl_sys_latency = get_sys_latency(nphases, cwl) + rdcmdphase, rdphase = get_sys_phases(nphases, cl_sys_latency, cl) + wrcmdphase, wrphase = get_sys_phases(nphases, cwl_sys_latency, cwl) + return PhySettings( + phytype="ECP5DDRPHY", + memtype="DDR3", + databits=databits, + dfi_databits=4*databits, + nranks=nranks, + nphases=nphases, + rdphase=rdphase, + wrphase=wrphase, + rdcmdphase=rdcmdphase, + wrcmdphase=wrcmdphase, + cl=cl, + cwl=cwl, + read_latency=2 + cl_sys_latency + 2 + log2_int(4//nphases) + 4, + write_latency=cwl_sys_latency + ) + + + class DDR3SoC(SoC, Elaboratable): def __init__(self, *, + fpga, dram_cls, uart_pins, ddr_pins, ddrphy_addr, dramcore_addr, @@ -137,13 +173,18 @@ class DDR3SoC(SoC, Elaboratable): """ # DRAM Module - if ddr_pins is not None: - self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins, - sys_clk_freq=clk_freq)) - self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr) - + if ddr_pins is not None or fpga == 'sim': ddrmodule = MT41K256M16(clk_freq, "1:2") # match DDR3 ASIC P/N + if fpga == 'sim': + self.ddrphy = FakePHY(module=ddrmodule, + settings=sim_ddr3_settings(clk_freq), + verbosity=SDRAM_VERBOSE_DBG) + else: + self.ddrphy = DomainRenamer("dramsync")(ECP5DDRPHY(ddr_pins, + sys_clk_freq=clk_freq)) + self._decoder.add(self.ddrphy.bus, addr=ddrphy_addr) + drs = DomainRenamer("dramsync") dramcore = gramCore(phy=self.ddrphy, geom_settings=ddrmodule.geom_settings, @@ -244,7 +285,7 @@ class DDR3SoC(SoC, Elaboratable): # and at the moment that's just UART tx/rx. ports = [] ports += [self.uart.tx_o, self.uart.rx_i] - if hasattr(self, "ddrphy"): + if hasattr(self, "ddrphy") and hasattr(self.ddrphy, "pads"): ports += list(self.ddrphy.pads.fields.values()) return ports @@ -297,7 +338,7 @@ if __name__ == "__main__": "odt":4, "ras":4, "cas":4, "we":4}) # set up the SOC - soc = DDR3SoC(dram_cls=dram_cls, + soc = DDR3SoC(fpga=fpga, dram_cls=dram_cls, # check microwatt_soc.h for these ddrphy_addr=0xff000000, # DRAM_INIT_BASE firmware base dramcore_addr=0xc8000000, # DRAM_CTRL_BASE -- 2.30.2