wrpll: new frequency meter

As per Mattermost discussion with Tom.
This commit is contained in:
Sebastien Bourdeauducq 2019-12-30 19:47:57 +08:00
parent 9e15ff7e6a
commit f57f235dca
2 changed files with 56 additions and 30 deletions

View File

@ -264,12 +264,25 @@ mod si549 {
} }
} }
fn get_helper_frequency() -> u32 { fn get_frequencies() -> (u32, u32, u32) {
unsafe { csr::wrpll::helper_frequency_start_write(1); } unsafe {
clock::spin_us(10_000); csr::wrpll::frequency_counter_update_en_write(1);
unsafe { csr::wrpll::helper_frequency_stop_write(1); } clock::spin_us(200_000); // wait for at least one update
csr::wrpll::frequency_counter_update_en_write(0);
clock::spin_us(1); clock::spin_us(1);
unsafe { csr::wrpll::helper_frequency_counter_read() } let helper = csr::wrpll::frequency_counter_counter_helper_read();
let main = csr::wrpll::frequency_counter_counter_rtio_read();
let cdr = csr::wrpll::frequency_counter_counter_rtio_rx0_read();
(helper, main, cdr)
}
}
fn log_frequencies() {
let (f_helper, f_main, f_cdr) = get_frequencies();
let conv_khz = |f| 4*(f as u64)*(csr::CONFIG_CLOCK_FREQUENCY as u64)/(1000*(1 << 23));
info!("helper clock frequency: {}kHz ({})", conv_khz(f_helper), f_helper);
info!("main clock frequency: {}kHz ({})", conv_khz(f_main), f_main);
info!("CDR clock frequency: {}kHz ({})", conv_khz(f_cdr), f_cdr);
} }
fn get_ddmtd_main_tag() -> u16 { fn get_ddmtd_main_tag() -> u16 {
@ -309,7 +322,7 @@ pub fn init() {
unsafe { csr::wrpll::helper_reset_write(0); } unsafe { csr::wrpll::helper_reset_write(0); }
clock::spin_us(1); clock::spin_us(1);
info!("helper clock frequency: {}MHz", get_helper_frequency()/10000); log_frequencies();
let mut tags = [0; 10]; let mut tags = [0; 10];
for i in 0..tags.len() { for i in 0..tags.len() {
tags[i] = get_ddmtd_main_tag(); tags[i] = get_ddmtd_main_tag();
@ -319,6 +332,7 @@ pub fn init() {
pub fn select_recovered_clock(rc: bool) { pub fn select_recovered_clock(rc: bool) {
info!("select_recovered_clock: {}", rc); info!("select_recovered_clock: {}", rc);
log_frequencies();
if rc { if rc {
let mut tags = [0; 10]; let mut tags = [0; 10];
for i in 0..tags.len() { for i in 0..tags.len() {

View File

@ -9,31 +9,42 @@ from artiq.gateware.drtio.wrpll import thls, filters
class FrequencyCounter(Module, AutoCSR): class FrequencyCounter(Module, AutoCSR):
def __init__(self): def __init__(self, timer_width=23, counter_width=23, domains=["helper", "rtio", "rtio_rx0"]):
self.counter = CSRStatus(32) for domain in domains:
self.start = CSR() name = "counter_" + domain
self.stop = CSR() counter = CSRStatus(counter_width, name=name)
setattr(self, name, counter)
self.update_en = CSRStorage()
ps_start = PulseSynchronizer("sys", "helper") timer = Signal(timer_width)
ps_stop = PulseSynchronizer("sys", "helper") timer_tick = Signal()
self.submodules += ps_start, ps_stop self.sync += Cat(timer, timer_tick).eq(timer + 1)
self.comb += [ for domain in domains:
ps_start.i.eq(self.start.re & self.start.r), sync_domain = getattr(self.sync, domain)
ps_stop.i.eq(self.stop.re & self.stop.r) divider = Signal(2)
] sync_domain += divider.eq(divider + 1)
counter = Signal(32) divided = Signal()
self.specials += MultiReg(counter, self.counter.status) divided.attr.add("no_retiming")
sync_domain += divided.eq(divider[-1])
divided_sys = Signal()
self.specials += MultiReg(divided, divided_sys)
counting = Signal() divided_sys_r = Signal()
self.sync.helper += [ divided_tick = Signal()
If(counting, counter.eq(counter + 1)), self.sync += divided_sys_r.eq(divided_sys)
If(ps_start.o, 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), counter.eq(0),
counting.eq(1) ).Else(
), If(divided_tick, counter.eq(counter + 1))
If(ps_stop.o, counting.eq(0)) )
] ]
@ -52,7 +63,8 @@ class WRPLL(Module, AutoCSR):
self.submodules.helper_dcxo = Si549(helper_dxco_i2c) self.submodules.helper_dcxo = Si549(helper_dxco_i2c)
self.submodules.main_dcxo = Si549(main_dcxo_i2c) self.submodules.main_dcxo = Si549(main_dcxo_i2c)
self.submodules.helper_frequency = FrequencyCounter() # for diagnostics # for diagnostics and PLL initialization
self.submodules.frequency_counter = FrequencyCounter()
ddmtd_counter = Signal(N) ddmtd_counter = Signal(N)
self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1) self.sync.helper += ddmtd_counter.eq(ddmtd_counter + 1)