Previous Thread
Next Thread
Print Thread
Page 2 of 7 1 2 3 4 5 6 7
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117215 04/17/20 11:45 AM
Joined: Mar 2001
Posts: 16,539
R
R. Belmont Online Content
Very Senior Member
Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,539
1050% sounds plenty fast, to be honest. 280ZZAP isn't a very demanding driver otherwise.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117217 04/17/20 12:32 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Well, there are three oscillators of this kind and some more LM3900 :-( Getting this to perform is a challenge, but manageable.
In the worst case we need to add some frontier statements and as a last resort use some function controlled voltage sources as replacements for the oscillators. We will get there. The nice thing is you can do that with a couple of #ifdefs. Basically with that one can always run the slow and complete/detail netlist to have a reference.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117285 04/29/20 07:22 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
After much trial and error and many false starts, I've come up with a somewhat faster model for the LM3900 Norton opamp that may help. This same technique should work for other Norton opamps, should they appear in MAME systems.

The idea is based on LM3900 model 2 in mame/src/lib/netlist/macro/nlm_opamp.cpp, and follows the same basic idea of converting the LM3900 inputs to a form acceptable to the standard voltage-based opamp model, but with some modifications to make it work better. (Hence the name "LM3900_2M" I've given it here; feel free to change it if you prefer.) An ideal current mirror, based on a CCCS, is used so that the .PLUS input current can be subtracted from the .MINUS input current. The resulting difference current is then converted into a voltage with a CCVS, using a very high gain parameter of 200000. This voltage difference is then fed to a standard voltage-based opamp using a model appropriate for the LM3900's behavior.

The high CCVS gain was chosen so that the final result would have an open-loop gain consistent with datasheet figures. It's not as unreasonably high as you might think: the LM3900 works with small voltage differences (on the order of millivolts) which then pass through high-value external resistors (in the hundreds of kiloohms to several megaohms), so the current differences it sees are tiny, as low as a few nanoamps. Thus, getting the final open-loop voltage-to-voltage gain of a few thousand requires a corresponding inverse multiplication on top of the gain already provided by the voltage-based opamp model.

Each input also has a corresponding diode to ensure that its voltage level is one diode drop above ground (550 mV at 10 µA current for the LM3900, according to one source I found). This is needed to make sure that the input currents are correct; with a current generated from a source of a few volts, a half-volt difference in the voltage drop matters. To ensure that the .MINUS input is consistently at this level even with a minimal difference current, as it would be in the real device, I use a bias current source (CS_BIAS) to bias the diode; having that current enter the diode at the exit point of the CCVS input keeps the bias current distinct from the input difference current.

Code
static NETLIST_START(LM3900_2M)
	OPAMP(A, "LM3900")

	DIODE(D1, "D(IS=6e-15 N=1)")
	DIODE(D2, "D(IS=6e-15 N=1)")
	CCCS(CS1, 1) // Current Mirror
	// NOTE: unlike an ordinary CS (current source), which takes
	// in positive current from .P and outputs it from .N, the
	// positive output current of a CCCS (current-controlled
	// current source) is taken in from *.ON* and output from
	// *.OP*.

	ALIAS(VCC, A.VCC)
	ALIAS(GND, A.GND)
	ALIAS(OUT, A.OUT)

	ALIAS(PLUS, CS1.IP)
	NET_C(D1.A, CS1.IN)
	NET_C(A.GND, D1.K)

	CS(CS_BIAS, 10e-6)
	NET_C(A.VCC, CS_BIAS.P)

	ALIAS(MINUS, CS1.ON)
	NET_C(CS1.OP, A.GND)

	CCVS(VS1, 200000) // current-to-voltage gain
	NET_C(CS1.ON, VS1.IP)
	NET_C(VS1.IN, CS_BIAS.N, D2.A)
	NET_C(D2.K, A.GND)
	NET_C(VS1.OP, A.MINUS)
	NET_C(VS1.ON, A.PLUS, A.GND)
NETLIST_END()


I also tweaked the LM3900's OPAMP model a bit:

Code
OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=2k DAB=0.0015)


I lowered VLH (National Semiconductor, who created the LM3900, proudly claimed that it can raise its output to just one diode drop below the positive rail—again, this matters when that rail is only 5 volts), lowered the unity-gain frequency (2.5 MHz according to National Semiconductor), and reduced the slew rate (the LM3900 has a rising slew rate of only half a volt per microsecond, so 1 volt per microsecond better fits a cycle-time average).

Though I haven't tried this model with the full 280-ZZZAP emulation yet, I have tested it with a couple of its subcircuits and various other trial circuits. It seems to work well and performs faster than the 6-BJT version. The gain is actually higher than that version, closer to the actual device, and its falloff with frequency also better matches the device.

However, the higher gain does cause a potential problem. 280-ZZZAP's oscillator circuits turn out to be quite sensitive to this gain, with more gain increasing the numerical instability and requiring shorter timesteps to get a stable solution. The good news is that you can simply adjust the gain downward to eliminate this by tweaking the CCVS gain, thus making the model *easier* to stabilize—and this can be done on a case-by-case basis by using multiple models (crude) or parameterizing the model (better, though I'm not sure how). The only downside here is that reducing the gain also seems to reduce the oscillation period, so that this approach may require tweaking the resistor values (or other components) to maintain an accurate oscillation frequency.

Last edited by Colin Howell; 04/29/20 07:26 PM. Reason: Minor tweak for accuracy.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117287 05/01/20 02:03 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Hi Colin,
thanks a lot. Really looks great! The big test will be the monymony sound.
Regarding the numerical instability: I have changes ready here which significantly improve the solution off Newton-Raphson not converging. This usually happens if the timestep is too big. In this case the new code will do a couple of solver iterations with a very small timestep before trying the computed one again. If this fails, same procedure. Works actually well.
But it needs some structural changes and time stepping devices now need "backstep" functionality. Hope to have that ready soon.

Update: Great, the model seems to work well with monymony and jackrabt.

Last edited by couriersud; 05/01/20 02:25 PM.
Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117288 05/01/20 03:49 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Hi Colin,
thanks a lot for spotting the current controlled current source issue (CCCS). I will fix this now. It is definitely not implemented according to general SPICE conventions.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117289 05/01/20 04:09 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
One comment: last night I found one place in 280-ZZZAP where I needed to adjust the OPAMP model I used a bit more, reducing RO to 100:

Code
OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=100 DAB=0.0015)


I needed to do this because RO controls the output current gain, and with 2k the amplifier simply couldn't produce enough output current for the noise generator circuit to work. That circuit includes a 1 kiloohm resistor from the output to ground as well as about 100 kiloohms of feedback resistance, so the LM3900 must generate 2.5 mA of total output current to get 25 µA of matching feedback current to the inverting input. For the actual LM3900, National Semiconductor's original datasheet says that it typically can source 10 mA of output current (and an accompanying graph gives 20 mA, even with 5 V power), so this should be well within its capability.

I know 100 ohms is a long way from the stated "output resistance" of 8 kiloohms given in the datasheet, but I notice that is listed under "Open Loop", so I'm not sure whether that's an inherent output resistance or just the value of the external output resistor used for measuring the open-loop gain.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117290 05/01/20 04:11 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
and the updated netlist:

Code
static NETLIST_START(LM3900)
	OPAMP(A, "OPAMP(TYPE=3 VLH=0.5 VLL=0.03 FPF=2k UGF=2.5M SLEW=1M RI=10M RO=2k DAB=0.0015)")

	DIODE(D1, "D(IS=6e-15 N=1)")
	DIODE(D2, "D(IS=6e-15 N=1)")
	CCCS(CS1, 1) // Current Mirror

	ALIAS(VCC, A.VCC)
	ALIAS(GND, A.GND)
	ALIAS(OUT, A.OUT)

	ALIAS(PLUS, CS1.IP)
	NET_C(D1.A, CS1.IN)
	NET_C(A.GND, D1.K)

	CS(CS_BIAS, 10e-6)
	NET_C(A.VCC, CS_BIAS.P)

	ALIAS(MINUS, CS1.OP)
	NET_C(CS1.ON, A.GND)

	CCVS(VS1, 200000) // current-to-voltage gain
	NET_C(CS1.OP, VS1.IP)
	NET_C(VS1.IN, CS_BIAS.N, D2.A)
	NET_C(D2.K, A.GND)
	NET_C(VS1.OP, A.MINUS)
	NET_C(VS1.ON, A.PLUS, A.GND)
NETLIST_END()

Re: Netlist: 280-ZZZAP sound problems [Re: couriersud] #117291 05/01/20 04:19 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
Whoops, our posts crossed, I think. smile Anyway, thanks for your quick help on this.

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117292 05/01/20 04:48 PM
Joined: Feb 2007
Posts: 505
C
couriersud Offline
Senior Member
Offline
Senior Member
C
Joined: Feb 2007
Posts: 505
Looking at the datasheet there seems to be a disparity between the sourcing ability (just C-E) and the sinking ability. According to the datasheet it constantly sinks 1mA (current source). The C-E should be able to deliver 20mA. Which at 5V translates to 250 ohms with 1V output drop. So 100 ohms looks reasonable.
Changed this now. I have added this now to nlm_opamps.cpp and plan to commit over the weenkend after some more tests. Is it ok to be credited as Colin Howell or do you prefer something else?

Re: Netlist: 280-ZZZAP sound problems [Re: Colin Howell] #117293 05/01/20 05:05 PM
Joined: Jun 2003
Posts: 58
C
Colin Howell Online Content OP
Member
OP Online Content
Member
C
Joined: Jun 2003
Posts: 58
No, Colin Howell is fine.

I have a question about your timestep proposal. How would this (and how do timesteps in general) affect random white noise sources like those in cheekyms and gunfight which generate their value by calling rand()? I'm using a similar source in 280-ZZZAP, and it seems to be re-evaluated every timestep, regardless of its size. (As I suppose it should; if it's really a white noise source it should look random at all timescales.) That would affect convergence, would it not?

Incidentally, I have another question regarding your rand() implementation. If I understand right, it seems to be based on an LFSR which is only 16 bits. This is noticeable if you listen to or look at the output, because the 16-bit size means it repeats every 65536 timesteps—just over a second at 48 kHz, and much shorter if timesteps are shortened by dynamic timestepping. Why did you abandon the native random number generator, and why is the LFSR so short?

Page 2 of 7 1 2 3 4 5 6 7

Who's Online Now
2 registered members (Dorando, 1 invisible), 67 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
ShoutChat Box
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,792
Posts115,722
Members4,908
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3