From 2f66f4b1d22a5d3d30ff4a7d56f4fe0feb4dd9e6 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 16 Apr 2022 13:31:55 +0100 Subject: [PATCH] add in extra delay-for-core in ECP5CRG actually, it is a separate delay for everything-else-except-the-init domain which is run at a really slow 25 mhz --- src/ecp5_crg.py | 26 ++++++++++++++++++++------ src/ls2.py | 23 ++++++++++++----------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/ecp5_crg.py b/src/ecp5_crg.py index 980e62d..403ff7d 100644 --- a/src/ecp5_crg.py +++ b/src/ecp5_crg.py @@ -169,13 +169,18 @@ class PLL(Elaboratable): class ECP5CRG(Elaboratable): - def __init__(self, sys_clk_freq=100e6, dram_clk_freq=None, pod_bits=25): + def __init__(self, sys_clk_freq=100e6, dram_clk_freq=None, + pod_bits=25, sync_bits=26): """when dram_clk_freq=None, a dramsync domain is still created but it is an alias of sync domain. likewise the 2x """ self.sys_clk_freq = sys_clk_freq self.dram_clk_freq = dram_clk_freq - self.pod_bits = pod_bits + self.pod_bits = pod_bits # for init domain + self.sync_bits = sync_bits # for all other domains + assert pod_bits <= sync_bits, \ + "power-on-delay bits %d should " \ + " be less than sync_bits %d" % (pod_bits, sync_bits) def phase2_domain(self, m, pll, name, freq, esyncb): """creates a domain that can be used with xdr=4 platform resources. @@ -251,14 +256,21 @@ class ECP5CRG(Elaboratable): # Power-on delay (655us) podcnt = Signal(self.pod_bits, reset=-1) + synccnt = Signal(self.sync_bits, reset=-1) pod_done = Signal() + sync_done = Signal() + with m.If((synccnt != 0) & pll.locked): + m.d.rawclk += synccnt.eq(synccnt-1) with m.If((podcnt != 0) & pll.locked): m.d.rawclk += podcnt.eq(podcnt-1) m.d.rawclk += pod_done.eq(podcnt == 0) + m.d.rawclk += sync_done.eq(synccnt == 0) # and reset which only drops when the PLL is done and pod completes reset_ok = Signal(reset_less=True) + sync_reset_ok = Signal(reset_less=True) m.d.comb += reset_ok.eq(~pll.locked|~pod_done) + m.d.comb += sync_reset_ok.eq(~pll.locked|~sync_done) # create PLL input clock from platform default frequency pll.set_clkin_freq(platform.default_clk_frequency) @@ -275,8 +287,8 @@ class ECP5CRG(Elaboratable): # xdr=4 can be requested on the sync domain. also do not request # an edge-clock-stop self.phase2_domain(m, pll, "sync", self.sys_clk_freq, True) - m.d.comb += ResetSignal("sync2x").eq(reset_ok) - m.d.comb += ResetSignal("sync").eq(reset_ok) + m.d.comb += ResetSignal("sync2x").eq(sync_reset_ok) + m.d.comb += ResetSignal("sync").eq(sync_reset_ok) # DRAM clock: if not requested set to sync, otherwise create with # a CLKESYNCB (which is set to no-stop at the moment) @@ -292,10 +304,12 @@ class ECP5CRG(Elaboratable): m.domains += cd_dramsync2x m.d.comb += ClockSignal("dramsync2x").eq(ClockSignal("sync2x")) # resets for the dram domains - m.d.comb += ResetSignal("dramsync2x").eq(reset_ok) - m.d.comb += ResetSignal("dramsync").eq(reset_ok) + m.d.comb += ResetSignal("dramsync2x").eq(sync_reset_ok) + m.d.comb += ResetSignal("dramsync").eq(sync_reset_ok) # create 25 mhz "init" clock, straight (no 2x phase stuff) + # this domain can be used before all others, has its own delay + # (sync_bits) cd_init = ClockDomain("init", local=False) pll.create_clkout(ClockSignal("init"), 25e6) m.domains += cd_init diff --git a/src/ls2.py b/src/ls2.py index 514b724..bb91881 100644 --- a/src/ls2.py +++ b/src/ls2.py @@ -9,7 +9,8 @@ # under EU Grants 871528 and 957073, under the LGPLv3+ License from nmigen import (Module, Elaboratable, DomainRenamer, Record, - Signal, Cat, Const, ClockSignal, ResetSignal) + Signal, Cat, Const, ClockSignal, ResetSignal, + ) from nmigen.build.dsl import Attrs from nmigen.cli import verilog from nmigen.lib.cdc import ResetSynchronizer @@ -288,12 +289,14 @@ class DDR3SoC(SoC, Elaboratable): # set up clock request generator pod_bits = 25 + sync_bits = 26 if fpga in ['versa_ecp5', 'versa_ecp5_85', 'isim', 'ulx3s', 'orangecrab']: if fpga in ['isim']: - pod_bits = 6 + pod_bits = 5 + sync_bits = 6 self.crg = ECP5CRG(clk_freq, dram_clk_freq=dram_clk_freq, - pod_bits=pod_bits) + pod_bits=pod_bits, sync_bits=sync_bits) if fpga in ['arty_a7']: self.crg = ArtyA7CRG(clk_freq) @@ -301,9 +304,10 @@ class DDR3SoC(SoC, Elaboratable): if self.dram_clk_freq is None: self.dram_clk_freq = clk_freq - # set up CPU, with 64-to-32-bit downconverters + # set up CPU, with 64-to-32-bit downconverters, and a delayed Reset if add_cpu: self.cpu = ExternalCore(name="ext_core") + cvtdbus = wishbone.Interface(addr_width=30, data_width=32, granularity=8, features={'stall'}) cvtibus = wishbone.Interface(addr_width=30, data_width=32, @@ -602,7 +606,7 @@ class DDR3SoC(SoC, Elaboratable): def elaborate(self, platform): m = Module() - comb = m.d.comb + comb, sync = m.d.comb, m.d.sync # add the peripherals and clock-reset-generator if platform is not None and hasattr(self, "crg"): @@ -641,10 +645,6 @@ class DDR3SoC(SoC, Elaboratable): m.submodules.extcore = self.cpu m.submodules.dbuscvt = self.dbusdowncvt m.submodules.ibuscvt = self.ibusdowncvt - # create stall sigs, assume wishbone classic - #ibus, dbus = self.cvtibus, self.cvtdbus - #comb += ibus.stall.eq(ibus.stb & ~ibus.ack) - #comb += dbus.stall.eq(dbus.stb & ~dbus.ack) m.submodules.arbiter = self._arbiter m.submodules.decoder = self._decoder @@ -856,7 +856,8 @@ def build_platform(fpga, firmware): dram_clk_freq = clk_freq if fpga == 'isim': clk_freq = 50e6 # below 50 mhz, stops DRAM being enabled - dram_clk_freq = 100e6 + dram_clk_freq = clk_freq + #dram_clk_freq = 100e6 if fpga == 'versa_ecp5': clk_freq = 50e6 # crank right down to test hyperram #dram_clk_freq = 100e6 @@ -908,7 +909,7 @@ def build_platform(fpga, firmware): # Get SPI resource pins spi_0_pins = None - if False and platform is not None and \ + if platform is not None and \ fpga in ['versa_ecp5', 'versa_ecp5_85', 'isim']: # Override here to get FlashResource out of the way and enable Tercel # direct access to the SPI flash. -- 2.30.2