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.
# 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)
# 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)
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
# 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
# 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)
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,
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"):
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
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
# 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.