377: pll: merge advance into update (like rpll) r=jordens a=jordens



Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
bors[bot] 2021-06-03 17:28:54 +00:00 committed by GitHub
commit f1b305e13c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 27 deletions

View File

@ -44,11 +44,11 @@ fn pll_bench() {
let mut dut = PLL::default(); let mut dut = PLL::default();
println!( println!(
"PLL::update(t, 12, 12): {}", "PLL::update(t, 12, 12): {}",
bench_env(0x241, |x| dut.update(*x, 12, 12)) bench_env(Some(0x241), |x| dut.update(*x, 12, 12))
); );
println!( println!(
"PLL::update(t, sf, sp): {}", "PLL::update(t, sf, sp): {}",
bench_env((0x241, 21, 20), |(x, p, q)| dut.update(*x, *p, *q)) bench_env((Some(0x241), 21, 20), |(x, p, q)| dut.update(*x, *p, *q))
); );
} }

View File

@ -45,7 +45,7 @@ impl PLL {
/// The signal's phase/frequency is reconstructed relative to the sampling period. /// The signal's phase/frequency is reconstructed relative to the sampling period.
/// ///
/// Args: /// Args:
/// * `x`: New input phase sample. /// * `x`: New input phase sample or None if a sample has been missed.
/// * `shift_frequency`: Frequency error scaling. The frequency gain per update is /// * `shift_frequency`: Frequency error scaling. The frequency gain per update is
/// `1/(1 << shift_frequency)`. /// `1/(1 << shift_frequency)`.
/// * `shift_phase`: Phase error scaling. The phase gain is `1/(1 << shift_phase)` /// * `shift_phase`: Phase error scaling. The phase gain is `1/(1 << shift_phase)`
@ -55,12 +55,13 @@ impl PLL {
/// A tuple of instantaneous phase and frequency (the current phase increment). /// A tuple of instantaneous phase and frequency (the current phase increment).
pub fn update( pub fn update(
&mut self, &mut self,
x: i32, x: Option<i32>,
shift_frequency: u8, shift_frequency: u8,
shift_phase: u8, shift_phase: u8,
) -> (i32, i32) { ) -> (i32, i32) {
debug_assert!((1..=30).contains(&shift_frequency)); debug_assert!((1..=30).contains(&shift_frequency));
debug_assert!((1..=30).contains(&shift_phase)); debug_assert!((1..=30).contains(&shift_phase));
let f = if let Some(x) = x {
let e = x.wrapping_sub(self.f); let e = x.wrapping_sub(self.f);
self.f = self.f.wrapping_add( self.f = self.f.wrapping_add(
(1i32 << (shift_frequency - 1)) (1i32 << (shift_frequency - 1))
@ -69,22 +70,19 @@ impl PLL {
>> shift_frequency, >> shift_frequency,
); );
self.x = x; self.x = x;
let f = self.f.wrapping_add( self.f.wrapping_add(
(1i32 << (shift_phase - 1)) (1i32 << (shift_phase - 1))
.wrapping_add(e) .wrapping_add(e)
.wrapping_sub(self.y) .wrapping_sub(self.y)
>> shift_phase, >> shift_phase,
); )
} else {
self.x = self.x.wrapping_add(self.f);
self.f
};
self.y = self.y.wrapping_add(f); self.y = self.y.wrapping_add(f);
(self.y, f) (self.y, f)
} }
/// Advance the PLL without providing a new timestamp.
pub fn advance(&mut self) -> (i32, i32) {
self.x = self.x.wrapping_add(self.f);
self.y = self.y.wrapping_add(self.f);
(self.y, self.f)
}
} }
#[cfg(test)] #[cfg(test)]
@ -93,7 +91,7 @@ mod tests {
#[test] #[test]
fn mini() { fn mini() {
let mut p = PLL::default(); let mut p = PLL::default();
let (y, f) = p.update(0x10000, 8, 4); let (y, f) = p.update(Some(0x10000), 8, 4);
assert_eq!(y, 0x1100); assert_eq!(y, 0x1100);
assert_eq!(f, y); assert_eq!(f, y);
} }
@ -107,7 +105,7 @@ mod tests {
let mut x = 0i32; let mut x = 0i32;
for i in 0..n { for i in 0..n {
x = x.wrapping_add(f0); x = x.wrapping_add(f0);
let (y, f) = p.update(x, shift.0, shift.1); let (y, f) = p.update(Some(x), shift.0, shift.1);
if i > n / 4 { if i > n / 4 {
assert_eq!(f.wrapping_sub(f0).abs() <= 1, true); assert_eq!(f.wrapping_sub(f0).abs() <= 1, true);
} }