From 7cb3e51d2d2c7e1d71fc9c991697e1270f60358b Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Sat, 9 Apr 2022 15:00:47 -0500 Subject: [PATCH] Wire up missing CRG / DDR3 clock control / reset signals Swap DELAYF for DELAYG on DQ lines --- examples/ecp5_crg.py | 26 +++++++++++++++----------- gram/phy/ecp5ddrphy.py | 26 ++++++++++++-------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/examples/ecp5_crg.py b/examples/ecp5_crg.py index 5c975d6..82ff66d 100644 --- a/examples/ecp5_crg.py +++ b/examples/ecp5_crg.py @@ -169,10 +169,14 @@ class PLL(Elaboratable): class ECP5CRG(Elaboratable): - def __init__(self, sys_clk_freq=100e6, pod_bits=25): + def __init__(self, sys_clk_freq=100e6, pod_bits=16): self.sys_clk_freq = sys_clk_freq self.pod_bits = pod_bits + # DDR clock control signals + self.ddr_clk_stop = Signal() + self.ddr_clk_reset = Signal() + def elaborate(self, platform): m = Module() @@ -204,18 +208,18 @@ class ECP5CRG(Elaboratable): i_GSR=gsr1), ] - # PLL - m.submodules.pll = pll = PLL(ClockSignal("rawclk"), reset=~reset) - - # Power-on delay (655us) + # Power-on delay podcnt = Signal(self.pod_bits, reset=-1) pod_done = Signal() - with m.If((podcnt != 0) & pll.locked): + with m.If(podcnt != 0): m.d.rawclk += podcnt.eq(podcnt-1) m.d.rawclk += pod_done.eq(podcnt == 0) + # PLL + m.submodules.pll = pll = PLL(ClockSignal("rawclk"), reset=~pod_done|~reset) + # Generating sync2x (200Mhz) and init (25Mhz) from extclk - cd_sync2x = ClockDomain("sync2x", local=False) + cd_sync2x = ClockDomain("sync2x", local=False, reset_less=True) cd_sync2x_unbuf = ClockDomain("sync2x_unbuf", local=False, reset_less=True) cd_init = ClockDomain("init", local=False) @@ -228,7 +232,7 @@ class ECP5CRG(Elaboratable): pll.create_clkout(ClockSignal("init"), 25e6) m.submodules += Instance("ECLKSYNCB", i_ECLKI = ClockSignal("sync2x_unbuf"), - i_STOP = 0, + i_STOP = self.ddr_clk_stop, o_ECLKO = ClockSignal("sync2x")) m.domains += cd_sync2x_unbuf m.domains += cd_sync2x @@ -238,8 +242,8 @@ class ECP5CRG(Elaboratable): reset_ok = Signal(reset_less=True) m.d.comb += reset_ok.eq(~pll.locked|~pod_done) m.d.comb += ResetSignal("init").eq(reset_ok) - m.d.comb += ResetSignal("sync").eq(reset_ok) - m.d.comb += ResetSignal("dramsync").eq(reset_ok) + m.d.comb += ResetSignal("sync").eq(reset_ok|self.ddr_clk_reset) + m.d.comb += ResetSignal("dramsync").eq(reset_ok|self.ddr_clk_reset) # # Generating sync (100Mhz) from sync2x @@ -247,7 +251,7 @@ class ECP5CRG(Elaboratable): p_DIV="2.0", i_ALIGNWD=0, i_CLKI=ClockSignal("sync2x"), - i_RST=0, + i_RST=ResetSignal("dramsync"), o_CDIVX=ClockSignal("sync")) # temporarily set dram sync clock exactly equal to main sync diff --git a/gram/phy/ecp5ddrphy.py b/gram/phy/ecp5ddrphy.py index 585031d..32a6792 100644 --- a/gram/phy/ecp5ddrphy.py +++ b/gram/phy/ecp5ddrphy.py @@ -52,15 +52,15 @@ class ECP5DDRPHYInit(Elaboratable): # DDRDLLA/DDQBUFM/ECLK initialization sequence --------------------------------------------- t = 8 # in cycles tl = Timeline([ - (1*t, [freeze.eq(1)]), # Freeze DDRDLLA - (2*t, [self.stop.eq(1)]), # Stop ECLK domain + (1*t, [ freeze.eq(1)]), # Freeze DDRDLLA + (2*t, [ self.stop.eq(1)]), # Stop ECLK domain (3*t, [self.reset.eq(1)]), # Reset ECLK domain (4*t, [self.reset.eq(0)]), # Release ECLK domain reset - (5*t, [self.stop.eq(0)]), # Release ECLK domain stop - (6*t, [freeze.eq(0)]), # Release DDRDLLA freeze + (5*t, [ self.stop.eq(0)]), # Release ECLK domain stop + (6*t, [ freeze.eq(0)]), # Release DDRDLLA freeze (7*t, [self.pause.eq(1)]), # Pause DQSBUFM - (8*t, [update.eq(1)]), # Update DDRDLLA - (9*t, [update.eq(0)]), # Release DDRDMMA update + (8*t, [ update.eq(1)]), # Update DDRDLLA + (9*t, [ update.eq(0)]), # Release DDRDMMA update (10*t, [self.pause.eq(0)]), # Release DQSBUFM pause ]) m.d.comb += tl.trigger.eq(lock & ~lock_d) # Trigger timeline on lock rising edge @@ -120,6 +120,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable): self.pads = pads self._sys_clk_freq = sys_clk_freq + self.init = ECP5DDRPHYInit() databits = len(self.pads.dq.io) if databits % 8 != 0: @@ -190,7 +191,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable): m.d.sync += burstdet_reg.eq(0) # Init ------------------------------------------------------------------------------------- - m.submodules.init = init = ECP5DDRPHYInit() + m.submodules.init = init = self.init # Parameters ------------------------------------------------------------------------------- cl, cwl = get_cl_cw("DDR3", tck) @@ -460,13 +461,10 @@ class ECP5DDRPHY(Peripheral, Elaboratable): i_D2=dq_o_data_muxed[2], i_D3=dq_o_data_muxed[3], o_Q=dq_o), - Instance("DELAYF", - p_DEL_MODE="DQS_ALIGNED_X2", - i_LOADN=1, - i_MOVE=0, - i_DIRECTION=0, - i_A=dq_i, - o_Z=dq_i_delayed), + Instance("DELAYG", + p_DEL_MODE = "DQS_ALIGNED_X2", + i_A = dq_i, + o_Z = dq_i_delayed), Instance("IDDRX2DQA", i_RST=ResetSignal("dramsync"), i_ECLK=ClockSignal("sync2x"), -- 2.30.2