Skip to content

Commit eb271f3

Browse files
committed
wrpll: add DDMTD cores
1 parent 39d5ca1 commit eb271f3

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

artiq/firmware/libboard_artiq/wrpll.rs

+9
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ pub fn init() {
281281

282282
clock::spin_us(10_000); // Settling Time after FS Change
283283
unsafe { csr::wrpll::helper_reset_write(0); }
284+
285+
info!("DDMTD test:");
286+
for _ in 0..20 {
287+
unsafe {
288+
csr::wrpll::ddmtd_main_arm_write(1);
289+
while csr::wrpll::ddmtd_main_arm_read() != 0 {}
290+
info!("{}", csr::wrpll::ddmtd_main_tag_read());
291+
}
292+
}
284293
}
285294

286295
pub fn select_recovered_clock(rc: bool) {

artiq/gateware/drtio/wrpll/core.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
from misoc.interconnect.csr import *
44

55
from artiq.gateware.drtio.wrpll.si549 import Si549
6+
from artiq.gateware.drtio.wrpll.ddmtd import DDMTD
67

78

89
class WRPLL(Module, AutoCSR):
9-
def __init__(self, helper_clk_pads, main_dcxo_i2c, helper_dxco_i2c):
10+
def __init__(self, helper_clk_pads, main_dcxo_i2c, helper_dxco_i2c, ddmtd_inputs, N=15):
1011
self.helper_reset = CSRStorage(reset=1)
1112

1213
self.clock_domains.cd_helper = ClockDomain()
@@ -19,3 +20,6 @@ def __init__(self, helper_clk_pads, main_dcxo_i2c, helper_dxco_i2c):
1920

2021
self.submodules.main_dcxo = Si549(main_dcxo_i2c)
2122
self.submodules.helper_dcxo = Si549(helper_dxco_i2c)
23+
24+
self.submodules.ddmtd_helper = DDMTD(N, ddmtd_inputs.rec_clk)
25+
self.submodules.ddmtd_main = DDMTD(N, ddmtd_inputs.main_xo)

artiq/gateware/drtio/wrpll/ddmtd.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from migen import *
2+
from migen.genlib.cdc import PulseSynchronizer, MultiReg
3+
from misoc.interconnect.csr import *
4+
5+
6+
class DDMTDEdgeDetector(Module):
7+
def __init__(self, i):
8+
self.rising = Signal()
9+
10+
history = Signal(4)
11+
deglitched = Signal()
12+
self.sync.helper += history.eq(Cat(history[1:], i))
13+
self.comb += deglitched.eq(i | history[0] | history[1] | history[2] | history[3])
14+
15+
deglitched_r = Signal()
16+
self.sync.helper += [
17+
deglitched_r.eq(deglitched),
18+
self.rising.eq(deglitched & ~deglitched_r)
19+
]
20+
21+
22+
class DDMTD(Module, AutoCSR):
23+
def __init__(self, N, i):
24+
self.arm = CSR()
25+
self.tag = CSRStatus(N)
26+
27+
# in helper clock domain
28+
self.h_tag = Signal(N)
29+
self.h_tag_update = Signal()
30+
31+
# # #
32+
33+
ed = DDMTDEdgeDetector(i)
34+
self.submodules += ed
35+
36+
counter = Signal(N)
37+
self.sync.helper += [
38+
counter.eq(counter + 1),
39+
self.h_tag_update.eq(0),
40+
If(ed.rising,
41+
self.h_tag_update.eq(1),
42+
self.h_tag.eq(counter)
43+
)
44+
]
45+
46+
tag_update_ps = PulseSynchronizer("helper", "sys")
47+
self.submodules += tag_update_ps
48+
self.comb += tag_update_ps.i.eq(self.h_tag_update)
49+
tag_update = Signal()
50+
self.sync += tag_update.eq(tag_update_ps.o)
51+
52+
tag = Signal(N)
53+
self.h_tag.attr.add("no_retiming")
54+
self.specials += MultiReg(self.h_tag, tag)
55+
56+
self.sync += [
57+
If(self.arm.re & self.arm.r, self.arm.w.eq(1)),
58+
If(tag_update,
59+
If(self.arm.w, self.tag.status.eq(tag)),
60+
self.arm.w.eq(0),
61+
)
62+
]

artiq/gateware/targets/sayma_amc.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ def __init__(self, rtio_clk_freq=125e6, identifier_suffix="", *, with_wrpll, **k
139139
self.submodules.wrpll = WRPLL(
140140
helper_clk_pads=platform.request("ddmtd_helper_clk"),
141141
main_dcxo_i2c=platform.request("ddmtd_main_dcxo_i2c"),
142-
helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"))
142+
helper_dxco_i2c=platform.request("ddmtd_helper_dcxo_i2c"),
143+
ddmtd_inputs=platform.request("ddmtd_inputs"))
143144
self.csr_devices.append("wrpll")
144145
else:
145146
self.comb += platform.request("filtered_clk_sel").eq(1)

0 commit comments

Comments
 (0)