2

I'm experimenting with filters for PDM-encoded signals and would like to simulate a variety of such bit-streams in LTspice for simple test signals such as sinewaves, combinations of multiple sinewaves, etc.

A refresher from Wikipedia: PDM means that the relative density of the pulses corresponds to the analog signal's amplitude, similar but not identical to how the relative width of the pulses corresponds to the analog signals' amplitude in PWM.

Synthesizing a PWM from an arbitrary waveform is easily done with a ramp and a comparator and I thought I could figure something out for the PDM, but failed.

Do I really have a simulate a complete delta-sigma modulator (which generates a PDM stream natively), or can anyone come up with a cheaper way?

pipe
  • 13,748
  • 5
  • 42
  • 72
  • "Cheaper" in what sense? Less complexity that the simulator has to deal with, thus making it faster to simulate? – Ste Kulov Aug 14 '23 at 15:53
  • @SteKulov Precisely. Since I don't care about that part of the simulation aspect, I don't mind if it's idealized. At the moment I built a little delta-sigma converter out of an opamp, integration capacitor, flip-flop for sampling etc. It works, but feels like a kludge and I don't think the bitstream is "optimal", if there even is one. – pipe Aug 14 '23 at 19:32
  • Besides maybe tweaking what you already have, the only other route I can think of is generating pre-defined waveforms in another program (maybe even Excel) and importing the datapoints as PWL sources. But it sounds like you might be trying to do encoding and decoding in the same simulation such that you can compare the decoded signal to the original? – Ste Kulov Aug 14 '23 at 20:05

1 Answers1

1

After studying this a bit I don't think it's so simple. There isn't any "ideal" or "normal form" PDM bitstream for any arbitrary analog input signal, so one really has to take the specific modulator into account when simulating.

The solution I ended up using was to pre-render the bitstream from my inputs (as Ste Kulov mentioned in a comment) using a python script and the python-deltasigma module. Here is an incomplete and shortened example of what I'm doing:

import numpy as np
import deltasigma as ds
import scipy.io.wavfile as wf

# ... define the order and sample rate etc

# Create the input to measure, at the oversampling rate
u = 0.5*np.sin(2*np.pi*1000/bitrate*np.arange(samples))

# Create a ΔΣ modulator and run the input signal through
ntf = ds.synthesizeNTF(order,oversample,1)
v, xn, xmax, y = ds.simulateDSM(u,ntf)

# Save it in a format compatible with LTspice
wf.write("analog.wav",bitrate,(2**31*u).astype(np.int32))
wf.write("bitstream.wav",bitrate,(127*v+128).astype(np.uint8))

Life would have been easier if LTspice simply supported floating point WAV-files, especially with an arbitrary range. WAV-files are linearly interpolated on playback in LTspice so I post-process it through a Schmitt-trigger to more accurately represent the output of a physical modulator IC, carefully selecting the levels to make sure there are no round-off errors and that ±1.0 equals ±1.0 all the way.

Importing and post-processing WAV files in LTspice

pipe
  • 13,748
  • 5
  • 42
  • 72