StanfordVLSI / dragonphy2

Open Source PHY v2
Apache License 2.0
22 stars 2 forks source link

Add noise and jitter to emulation models #108

Closed sgherbst closed 4 years ago

sgherbst commented 4 years ago

Summary

This PR adds noise and jitter to both the high-level and low-level emulator implementations, as well as to the CPU-based models used for throughput comparison. This demonstrates new pseudorandom number generation (PRNG) features added to msdsl that enable us to emulate random effects with a few lines of code, like this: https://github.com/StanfordVLSI/dragonphy2/blob/3b3c1c583008ae6fdab49414a400f34b34f8291c/dragonphy/fpga_models/rx_adc_core.py#L49-L52 The user can adjust the standard deviations of these noise sources using Python-based commands; there is no need to rebuild the bitstream.

Key Files

Although there are ~1k lines of code in this PR, a lot of that is coming from updates to the testing infrastructure to verify the new features. The features themselves are implemented in three msdsl models, and the changes to those models are relatively small:

  1. dragonphy/fpga_models/analog_slice.py: High-level model that combines ADC+PI behaviors and therefore includes both a jitter source and a voltage noise source.
  2. dragonphy/fpga_models/clk_delay_core.py: Digitally-control delay used in low-level PI model. Jitter is added here.
  3. dragonphy/fpga_models/rx_adc_core.py: Used in the low-level ADC model; noise is added here.

Other Comments

  1. FPGA-based CI testing now uses a smaller channel model so that the resource utilization is not so close to the limits of the ZC702 board. My experiments are still run on the larger ZC706 board using the full channel model.
  2. Added pytest options --jitter_rms, --noise_rms, and --flatten_hierarchy. The first two are the standard deviations of noise sources while the last one is a debugging feature; occasionally it is useful to set --flatten_hierarchy to none when investigating synthesis issues.
  3. The low-level emulator previously used a 32-bit fixed-point format for analog signals; this has been reduced to 25 to fit better within available FPGA resources (particularly for the ZC702 board used in CI testing). The key change needed to support this was reducing the width of timestep requests from 32 to 25; this is OK because the exponent used for timestep requests is still -46. In other words, we kept 0.01ps resolution but reduced the maximum timestep from 30us to 200ns. In our system, timesteps are usually 1ns or smaller, so this poses no problem. As a side note, the reason 25 works so well is that our FPGA DSP blocks have 25x18 multipliers; constants are typically represented using 18 bit values, so dropping down to 25-bit signals provided a 2-3x reduction in DSP-related resource utilization. (The high-level emulator is already using 25-bit fixed-point values)
  4. tests/fpga_system_tests/emu/tb.sv (low-level emulator) has two somewhat messy additions, due to Vivado limitations:
    1. defparam is used to set unique seeds for PRNGs, since that would otherwise not be possible without modifying the real analog_core.sv code used in synthesizing the chip. Unfortunately, defparam doesn't seem to work properly in a generate loop, so the defparams had to be unrolled. Also note that functions like $urandom are not synthesizable, so the seed values have to be explicitly provided.
    2. The signals controlling standard deviation of noise and jitter have to be wired down into individual ADC and PI slices. Unfortunately, due to a different generate loop synthesis bug, these assign statements had to be unrolled.
sgherbst commented 4 years ago

@zamyers thanks for the feedback & interesting point about sinusoidal deterministic jitter. I think that should be possible, although since it is deterministic, it would be using the existing set_from_sync_func feature rather than the new pseudorandom number generation features. Is there a particular frequency or range of frequencies that is typical for sinusoidal jitter? (I ask since that might affect how I would implement it)

zamyers commented 4 years ago

Yeah, I made sure to go clarify what encompasses DJ.

For sinusoidal jitter/periodic jitter, I assume there are probably key tones (60 Hz, 400 KHz, 250 MHz- Wall AC, Typ. buck converter frequency, on board crystal) that should be important to consider but otherwise I am not sure.

There is a lump category in DJ for any remaining noise that is treated like a bounded random process. As long as that’s supported, then we are untouchable :).

We can talk about it on Friday.

-Zach Sent from my iPhone

On Jul 20, 2020, at 2:44 PM, Steven Herbst notifications@github.com wrote:

 @zamyers thanks for the feedback & interesting point about sinusoidal deterministic jitter. I think that should be possible, although since it is deterministic, it would be using the existing set_from_sync_func feature rather than the new pseudorandom number generation features. Is there a particular frequency or range of frequencies that is typical for sinusoidal jitter? (I ask since that might affect how I would implement it)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

sgherbst commented 4 years ago

@zamyers if the bounded noise happens to be uniformly distributed, you could use the uniform_signal function from msdsl instead of set_gaussian_noise. For arbitrary bounded noise, you can use arbitrary_noise(inv_cdf, ...), with inv_cdf set to the inverse cumulative distribution function of the noise. These both produce sequences of uncorrelated values (i.e., white noise), but you could color the noise by filtering with set_tf (set transfer function).