127 lines
4.2 KiB
Python
127 lines
4.2 KiB
Python
|
from migen import *
|
||
|
from migen.genlib.cdc import MultiReg, AsyncResetSynchronizer, PulseSynchronizer
|
||
|
from misoc.interconnect.csr import *
|
||
|
from misoc.interconnect.csr_eventmanager import *
|
||
|
|
||
|
from ddmtd import DDMTDSamplerGTX, DDMTD
|
||
|
|
||
|
|
||
|
class FrequencyCounter(Module, AutoCSR):
|
||
|
def __init__(self, counter_width=24, domains=["gtx0_rtio_rx", "sys", "helper"]):
|
||
|
for domain in domains:
|
||
|
name = "counter_" + domain
|
||
|
counter = CSRStatus(counter_width, name=name)
|
||
|
setattr(self, name, counter)
|
||
|
self.update_en = CSRStorage()
|
||
|
|
||
|
timer = Signal(counter_width)
|
||
|
timer_tick = Signal()
|
||
|
self.sync += Cat(timer, timer_tick).eq(timer + 1)
|
||
|
|
||
|
for domain in domains:
|
||
|
sync_domain = getattr(self.sync, domain)
|
||
|
divider = Signal(2)
|
||
|
sync_domain += divider.eq(divider + 1)
|
||
|
|
||
|
divided = Signal()
|
||
|
divided.attr.add("no_retiming")
|
||
|
sync_domain += divided.eq(divider[-1])
|
||
|
divided_sys = Signal()
|
||
|
self.specials += MultiReg(divided, divided_sys)
|
||
|
|
||
|
divided_sys_r = Signal()
|
||
|
divided_tick = Signal()
|
||
|
self.sync += divided_sys_r.eq(divided_sys)
|
||
|
self.comb += divided_tick.eq(divided_sys & ~divided_sys_r)
|
||
|
|
||
|
counter = Signal(counter_width)
|
||
|
counter_csr = getattr(self, "counter_" + domain)
|
||
|
self.sync += [
|
||
|
If(timer_tick,
|
||
|
If(self.update_en.storage, counter_csr.status.eq(counter)),
|
||
|
counter.eq(0),
|
||
|
).Else(
|
||
|
If(divided_tick, counter.eq(counter + 1))
|
||
|
)
|
||
|
]
|
||
|
|
||
|
|
||
|
class WRPLL(Module, AutoCSR):
|
||
|
def __init__(self, gtx, main_dcxo_pads, helper_dcxo_pads, COUNTER_BIT=32):
|
||
|
|
||
|
self.gtx_tag = CSRStatus(COUNTER_BIT)
|
||
|
self.main_tag = CSRStatus(COUNTER_BIT)
|
||
|
|
||
|
ddmtd_counter = Signal(COUNTER_BIT)
|
||
|
|
||
|
gtx_tag_sys = Signal(COUNTER_BIT)
|
||
|
main_tag_sys = Signal(COUNTER_BIT)
|
||
|
gtx_tag_stb_sys = Signal()
|
||
|
main_tag_stb_sys = Signal()
|
||
|
|
||
|
# # #
|
||
|
|
||
|
self.helper_reset = CSRStorage(reset=1)
|
||
|
self.clock_domains.cd_helper = ClockDomain()
|
||
|
self.helper_reset.storage.attr.add("no_retiming")
|
||
|
self.specials += [
|
||
|
Instance("IBUFGDS",
|
||
|
i_I=helper_dcxo_pads.p, i_IB=helper_dcxo_pads.n,
|
||
|
o_O=self.cd_helper.clk),
|
||
|
AsyncResetSynchronizer(self.cd_helper, self.helper_reset.storage)
|
||
|
]
|
||
|
|
||
|
self.submodules.frequency_counter = FrequencyCounter()
|
||
|
|
||
|
self.submodules.ddmtd_sampler = DDMTDSamplerGTX(gtx, main_dcxo_pads)
|
||
|
|
||
|
self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1)
|
||
|
self.submodules.ddmtd_gtx = DDMTD(ddmtd_counter, self.ddmtd_sampler.gtx_beating)
|
||
|
self.submodules.ddmtd_main = DDMTD(ddmtd_counter, self.ddmtd_sampler.main_beating)
|
||
|
|
||
|
# DDMTD tags collection
|
||
|
|
||
|
self.specials += [
|
||
|
MultiReg(self.ddmtd_gtx.h_tag, gtx_tag_sys),
|
||
|
MultiReg(self.ddmtd_main.h_tag, main_tag_sys)
|
||
|
]
|
||
|
|
||
|
gtx_tag_stb_ps = PulseSynchronizer("helper", "sys")
|
||
|
main_tag_stb_ps = PulseSynchronizer("helper", "sys")
|
||
|
self.submodules += [
|
||
|
gtx_tag_stb_ps,
|
||
|
main_tag_stb_ps
|
||
|
]
|
||
|
self.sync.helper += [
|
||
|
gtx_tag_stb_ps.i.eq(self.ddmtd_gtx.h_tag_update),
|
||
|
main_tag_stb_ps.i.eq(self.ddmtd_main.h_tag_update)
|
||
|
]
|
||
|
self.sync += [
|
||
|
gtx_tag_stb_sys.eq(gtx_tag_stb_ps.o),
|
||
|
main_tag_stb_sys.eq(main_tag_stb_ps.o)
|
||
|
]
|
||
|
|
||
|
self.sync += [
|
||
|
If(gtx_tag_stb_sys,
|
||
|
self.gtx_tag.status.eq(gtx_tag_sys),
|
||
|
),
|
||
|
If(main_tag_stb_sys,
|
||
|
self.main_tag.status.eq(main_tag_sys)
|
||
|
)
|
||
|
]
|
||
|
|
||
|
# PL-PS shared peripheral interrupt (SPI)
|
||
|
|
||
|
self.submodules.gtx_tag_ev = EventManager()
|
||
|
self.gtx_tag_ev.stb = EventSourcePulse()
|
||
|
self.gtx_tag_ev.finalize()
|
||
|
|
||
|
self.submodules.main_tag_ev = EventManager()
|
||
|
self.main_tag_ev.stb = EventSourcePulse()
|
||
|
self.main_tag_ev.finalize()
|
||
|
|
||
|
self.sync += [
|
||
|
self.gtx_tag_ev.stb.trigger.eq(gtx_tag_stb_sys),
|
||
|
self.main_tag_ev.stb.trigger.eq(main_tag_stb_sys)
|
||
|
]
|