[Libre-soc-bugs] [Bug 806] Nest should be able to run at different clock rate than main CPU

bugzilla-daemon at libre-soc.org bugzilla-daemon at libre-soc.org
Thu Apr 14 10:32:41 BST 2022


https://bugs.libre-soc.org/show_bug.cgi?id=806

Luke Kenneth Casson Leighton <lkcl at lkcl.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
    NLnet milestone|---                         |NLNet.2019.10.Wishbone
   budget (EUR) for|0                           |2000
         this task,|                            |
          excluding|                            |
   subtasks' budget|                            |
 total budget (EUR)|0                           |2000
  for completion of|                            |
       task and all|                            |
           subtasks|                            |

--- Comment #12 from Luke Kenneth Casson Leighton <lkcl at lkcl.net> ---
rrright.  i think i know what's going on here.

* the original crg has dramsync hard-coded to sync.  this is nice and simple

* dramsync therefore, being an alias for sync, is misleading

* DRAM (DDR3) pads need the 4x IO spec (xdr=4) which is why you get
  platform.request(xdr={'dqs': 4"})

* this causes the 4-phase clock thing to be REQUIRED - eclk, sclk -
  to be set up by the PLL, which in turn needs a 2x clock to be set
  up i.e. an Instance("ECLKSYNCB") and an Instance("CLKDIVF")

* in the current ecp5_crg.py - totally undocumented and without any comments -
  this is done for the ***SYNC*** domain ***NOT*** the ***dramsync*** domain

to move DDR3 to its own synchronous domain, a function will be needed
which calls pll.create_clkout, that does the:

* creation of an ECLKSYNCB,
* creation of a CLKDIVF,
* creation of a {%s}2x_unbuf,
* creation of a {%s}2x
* creation of a {%s} domain

and wires them all together in a non-hardwired-way.

   def do_2x_phase_clock_create(name):

        # Generating sync2x (200Mhz) and init (25Mhz) from extclk
        cd_2x = ClockDomain("%s2x" % name, local=False)
        cd_2x_unbuf = ClockDomain("%s2x_unbuf" % name,
                                      local=False, reset_less=True)
        cd_ = ClockDomain("%s" % name, local=False)

        # create PLL clocks
        pll.create_clkout(ClockSignal("%s2x_unbuf" % name), 2*freq)
        m.submodules += Instance("ECLKSYNCB",
                i_ECLKI = ClockSignal("%s2x_unbuf" % name),
                i_STOP  = 0,
                o_ECLKO = ClockSignal("2x" % name))
        m.domains["%s2x_unbuf" % name] += cd_2x_unbuf
        m.domains["%s2x" % name] += cd_2x_unbuf
        m.domains["%s" % name] += cd

        # # Generating sync (100Mhz) from sync2x

        m.submodules += Instance("CLKDIVF",
            p_DIV="2.0",
            i_ALIGNWD=0,
            i_CLKI=ClockSignal("%s2x" % name),
            i_RST=0,
            o_CDIVX=ClockSignal("%s" % name))

and then call that **TWICE**

* once for "sync"
* once for "dramsync"

now, actually, bizarrely, if there are no other peripherals that are
going to be using 4x xdr in the "sync" domain, i suspect it will *not*
be necessary to call do_2x_phase_clock_create("sync") but instead just
do a straight, boring, 1x (just like the "init" domain)

i'll add that function and commit it, along with some comments.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the libre-soc-bugs mailing list