Introduction
I wish life was simple. I have written up a bunch of words, complete chapters in fact on today’s topic: how the current sources and the various switches inside my core memory implementation are going to work. I was almost done with all the design when I hit a bump – namely that the compensation network was highly temperature-dependent which is no good – started to poke around and ended up throwing almost everything out, starting from scratch.
I wish life was simple, but it isn’t so let’s call it a learning opportunity. At any rate, if you happen to have come across these pages before, please try to expunge all that information from your memory and I’m terribly sorry to stuff your brain with false information.
So, second time a charm. Maybe?
A (very) short intro into core memories
In the last chapter, I started detailing how addressing in a core memory works and what the required line drivers (essentially somewhat modified half-bridges) are. Previously, also described in detail how core memories work, at least in theory.
To quickly recap: the cores in this type of memory are organized into a 2D matrix with wires running through them in both the X and Y direction. These wires (through the complicated ways described before) are switched in as loads to current sources. These current sources are tuned in such a way that neither of them alone is capable of causing a permanent magnetic field flip in the cores, but the two of them combined can. Since they only join forces in the intersection of the selected X and Y wires, any core can be flipped in this setup. Fore multi-bit memories, inhibit wires and their corresponding current sources can be used to prevent a flip from happening even in these intersections. Reads are controlled by driving currents in one direction through the X and Y lines, while writes put current on the same wires in the reverse direction. The inhibit wires always conduct current in one direction only. Reading is done by flipping bits from ‘1’ to ‘0’ (or not if they were already ‘0’) and writing is done by selectively flipping bits from ‘0’ to ‘1’. During reads, a flipping core generates a larger and more delayed voltage spike in a sense wire than a non-flipping one. This difference is detected by a sense amplifier, connected to the sense wire.
As you can see, all control boils down to switching currents onto various wires, so in this chapter, we’re going to get deep into how to generate those currents.
The original current source of the PDP-11
The PDP-11 memory system that my core mat is from is quite well documented. As such, I know what drive currents they’ve used:
The half-current was set to 410mA, which is what the X and Y line drivers use. The inhibit current was set to 370mA. The way they achieved this was by creating a single 740mA source and connecting the two sides of the inhibit wire in parallel. This is not elegant. I’m also not quite sure why they trimmed the inhibit current lower; theoretically it should be the same half-current that the X and Y lines see. Maybe they do this because of the potential for asymmetric current splitting between the two halves of the inhibit loop?
These current numbers are only nominal though and the circuit from DEC includes a thermistor to adjust them for the temperature of the core matrix:
This is the sanitized version, the one in the actual schematic is harder to read, but contains actual component values. And of course they screwed the above drawing up, R2 should connect to the emitter of Q12, not to the 5V supply (we need feedback!). I re-drew the relevant portions in LTSpice to do some experiments. Unfortunately some component values were unreadable on the scans, so some guess-work is involved:
The load on this circuit was not exactly the memory matrix. This current source drove a set of saturating transformers which they’ve used as switches to turn loads on and off. That’s why my load here is largely inductive.
As a side-note: it’s so interesting reading these old documents. They have solutions to problems so out of place for the modern eye! No one would think of using the saturating nature of transformer cores as switches these days. Now everything is silicon. Back then it was simpler to get a custom transformer made then to add five more transistors to the design. Apparently. If you are curious about the strange and fascinating world of ferrites, transformers and their applications, this book from 1962 is a good read.
Even with this model though we can test at the DC performance over temperature:

Decent, up until about 75C, after which things go haywire. Not sure what’s causing it, and not all that interested in finding it out to be honest. The datasheet for the module specifies ambient temperatures between 0 and 50C, so I guess it’s OK.
This model doesn’t yet incorporate the change of the thermistor value though. The thermistor is rated 300 ohms at room temperature, but it’s temperature dependence (it’s beta value) is not documented. Looking at Digikey, I’ve found thermistors with beta values ranging from 3100 to 3972. I can do some measurements on mine, but let’s see if it even matters!
I can run through a range of beta values, type up the relevant formulas in spice to make RT temperature dependent, and draw the full temperature-compensated current curves:

Pretty neat! A few things of note:
The absolute current value is not interesting only the relative changes. Even though I think it’s fairly close what reality must have been, this is just a reference current, the actual ones are set by other components that I didn’t simulate.
It’s also interesting that the beta value doesn’t really impact things all that much. The crude methods I have in my disposal would not be able to differentiate it better, so I guess I will call it good, at least for now. Alternatively, I can replace the thermistor on the board with a new one, one that I know the beta value of.
Last comment: the current decreases with temperature. The reason for this is that as temperature increases, the hysteresis opening of the ferrite material shrinks. This means that the current needed to flip it, also decreases. If we kept the current constant over temperature, the half-current that doesn’t cause a flip at cold might delete the information at high temperatures. Or the other way around: the current that flips a bit at high temperatures is insufficient to cause a flip in cold.
This also explains the limited operating temperature range at least on the high side: you want to stay well clear of the Curie temperature of the cores where the hysteresis curve completely closes and we lose our permanent magnets. It’s also unlikely that we want to chill a data-center below freezing if for nothing else, due to fear of condensation. So yeah, 0-50C is fair.
Because of this though, my solution, whatever it turns out to be, will have to mimic a similar temperature response.
Now, to the meat of the experiment: the current is 740mA at room temperature, decreasing to about 820mA at 0C and increasing to about 650mA at 0C. Scaling these numbers up to the real half-current values, we get:
- 465mA at 0C
- 410mA at 25C
- 348mA at 50C
Power supply voltage
The original DEC current sources used a 20V supply, which I will keep. The reason for that is this: to push 410mA over a 25ohm load (which is what I measured the X wires to be), one needs to be ready to drop about 10V across the load. The current regulator transistor (Q4 above) also needs a few volts to do it’s job. Then there are the half-bridges and several diodes along the path each adding a few hundred mV drop. Overall, I would be nervous with even 16V supply being sufficient. DEC seems to be comfortable with 20, so let’s start there.
Designing a current source
There are two problems with DECs circuit. The first is that it uses an op-amp, which I can’t, because I swore off of integrated circuits in this design. The second, as I’ve mentioned, is that this is not the whole circuit. It’s just a reference current source, the actual half-currents are generated through saturating transformers and more transistors. This setup is strange and fabulous and foreign and impossible to replicate.
But how is a current source built? Usually, if you want a current source, you achieve that by having a voltage reference, then a sense resistor, through which your current flows. Some control circuit ensures that the voltage drop across your sense resistor matches your reference, and (through Ohms law) you’ve arrived.
So, let’s start by creating a voltage reference! The simplest thing to do is to grab a Zenner diode and use its breakdown voltage as the reference. The best Zenner for this purpose is a 6.2V one because that’s the most stable across temperature.
By the way: so far, this is exactly what DEC did. Here’s where the differences start:
in order to make sure that the Zenner sees a relatively constant current through it, I want to de-couple any loads from it, using an emitter follower. This will – at first glance – drop the same voltage across its emitter resistor (R1) as there is on its base. So, 6.2V:
Only at first glance though. In reality the emitter voltage will be about 0.6V (one Vbe) higher than the base-voltage. Worse, this voltage difference is highly temperature dependent. To compensate for that, we need to add another forward-biased diode drop into our reference, in series with the zener:
This works, but only if the diode drop is really the same as the one on Q1s base-emitter junction. The best way to ensure that is to use the same transistor but make it into a diode, by connecting its collector and base together:
Now we have a temperature compensated voltage reference in the form of the voltage drop on R1. The problem is that this reference is 6.2V. That’s not something we can directly compare to the voltage drop on a sense resistor, which should be significantly less then 1V (for power consumption reasons if for nothing else). Of course we can make R1 into a resistor divider and create whatever reference we want, but now we face another problem: such a reference is very weak: it can’t really drive any significant load. To solve that, we can replicate this same circuit one more time, buffering (and temperature compensating said buffering) of this voltage dividers voltage:
Finally, on R5, we have the voltage reference we want (one that is adjustable by the ratio of R1 and R3) and in a form that can drive relatively low impedance sinks. Such as the base of a common-collector power stage:
Let’s investigate how Q5 works: ignoring Vbe and the base current for a moment, we see that it’s base and emitter must be at the same potential (relative to VCC). This in turn means that the voltage drop across R5 (our reference voltage) must be the same as the drop on R_SENSE. In other words, Q5 will open up as much as needed to ensure that the current through R_SENSE is whatever is needed to satisfy this condition. Finally, the current through R_SENSE has nowhere else to go than through the LOAD. Which means, we’ve arrived: we have a current source.
Except! Of course Vbe is non-0. We need to compensate for that and we can do it the same way as before: add another Vbe drop somewhere in our reference:

Q6 is now compensating the Vbe drop of Q5. The base current is not all that problematic: we can adjust R5 such that the current through it is much higher than the base current of Q5 and at any rate, it’s usually less then 1% of the emitter current. It’s more of a precision issue if anything else and 1% precision is plenty good for now.
There is yet another problem to deal with though: the situation when there is no load on the current source. What happens in that case is that Q5, the power transistor does it’s best to drop enough voltage on the sense resistor, but fails. It opens up as much as it can, goes to saturation, and just hangs around. Now, when the load appears (because we want to do a read or a write), Q5 would need to very quickly start regulating the current. However, it can’t; we have to wait for all its minority carriers to vacate the base, in other words, recover from saturation. That takes a long time and results in an unacceptable current spike on the load. To prevent this from happening, I’ve added D2, a diode, which acts as an artificial load if you wish: while it doesn’t draw enough current to stabilize the source, it prevents Q4 from going into saturation.

OK, we’re almost there. The last thing to explain is the temperature compensation:

RT is the thermistor that DEC mounted on the memory board. It measures the temperature of the cores. R3 and R6 are there (similarly to what DEC did) to control how much the thermistor is allowed to change the current of the current source. Roughly speaking, one acts as the offset, the other as the slope setting. Finally, the voltage divider is completed by R1. There is some interaction between these three resistors, normally all three values would need to be touched for any desired current setting, but it’s not that difficult to tune them.
Counting to many
The above schematic works relatively well for a single current source (one would need to add a current-limiting resistor to the base of Q2 otherwise the current through D2 would be too high), but there is a bigger issue still: I need multiple current sources. One for the X lines, one for the Y ones and 32 for the sense lines (as I intend to drive the two halves independently). Technically, one could just replicate the power stage (Q5, D2, R_SENSE) several times, but this surfaces a problem: you see, the schottky diodes I’ve added to combat saturation draw significant current, enough to add considerable cross-talk between the sources. Some de-coupling is needed. The way I dealt with that is to add an emitter follower stage before every power stage. Now, this emitter follower needs temperature compensation too, plus even with that, I’ve seen some cross-talk: the drive strength of the Q4 stage wasn’t enough to completely remove the channel interference. I ended up adding yet another emitter follower stage in-between, this time an NPN one. This has reverse Vbe offset than the PNP one, so the two naturally cancel each other out. The resulting circuit looks like this:
I know, it’s an eye-chart and I apologize for the renaming of all the components. This one is in LTSpice for simulation purposes.
A few explainers: the loads are replaced by something resembling the real loads, or at least my best guess at the real load of the X, Y and inhibit lines. There are switches added to simulate transient responses (and cross-talk). The resistor values are tuned to their expected values and the sense resistors are set so that the nominal currents are what they should be: 410 and 370mA respectively.
This is 14 transistors (5 power transistors, the rest are small-signal ones), not a hugely complex design. Heat is going to be a problem: the power transistors might drop as much as 10V while conducting ~0.4A of current. That’s 4W dissipated. For reads, only 2 are active (the X and Y ones), for writes however all 34 might be used. Reads and writes always come in pairs, and on average only half of the bits are set to 1 during a write, so the long-term average is only 10 current sources being active. So, if all we do are memory accesses, our power consumption on the power transistors would be 40W. The instruction set lowers it further: there’s at least 1 cycle out of 5 where there is no memory activity, and for some instructions, it could be as high 3 out of 5. At the same time, SWAP instructions do a memory access in all of their 6 cycles, so one could write a program that reaches this 40W number. The temperature compensation only works if the relevant transistors are at the same temperature. So a common heat-sink is going to be needed.
Static behavior
Let’s look at the performance of this source over temperature (this time with RT, the thermistor replaced by a constant, 300 ohm resistor):

There is some residual temperature dependency, and all the currents are about 5mA higher then the expectation. The latter can be easily adjusted and the actual dependency on temperature is about 8mA over a 50C range, or about 2.1% accuracy. That I think should be acceptable.
This is not bad at all, the current stays about 1% within the expected range for temperatures between 0 and 50C, the temperature range DEC specified for the core. It of course works from -25 to 125, but with some loss of precision.
It’s important to note that the two (nominally) 410mA sources are off by about 4mA from one another. This is due to the load begin different: one is loaded by a 19ohm resistor, the other with a 25ohm one. These are the resistances I measured on the X and Y lines in my memory matrix. So, the load variability contributed about 1% error as well.
Now, lets look at the effect of supply voltage:
This isn’t stellar either. Every volt of change in VCC results in ~6mA of change in current, or about 1.5%. While VCC is going to be imperfect, still it is a regulated supply, it should be within +/-5% (Which is 1V for a 20V supply).
Finally, let’s look at how closely I can match the temperature response of the DEC current source. Here are my previous results from the PDP-11 current source in line with mine:
- 465mA for PDP-11, 467mA for mine at 0C
- 410mA for PDP-11, 414mA for mine at 25C
- 348mA for PDP-11, 354mA for mine at 50C
It seems, all points are set a bit too high, something that can be adjusted further. Even with the current setpoint though, the error is about 1% (a bit higher at high temperatures). Taking it together: 1.5% from VCC, 1% from temperature, and another 1% or so from load regulation. Overall, 3.5% accuracy, some of which can be somewhat lowered by some fine-tuning. I will take this. Not fabulous, but given how precisely I know what the currents should be in the first place, acceptable.
Modelling the load
There is previous little I have found in concrete numbers what the load on this current source is going to look like. In essence, it’s a piece of wire threaded through a bunch of ferrite cores. 2048 cores for the X and Y lines and 8,192 for the sense/inhibit (half) lines. The documentation states the following about the individual cores:
Using this online calculator gives 11nH as the individual core inductance:
That would add up to 22.5uH for the X and Y lines and about 90uH for the half inhibit lines. We also know their resistance: 25, 19 and 15 ohms respectively. From these, we can calculate their current step response to a 20V voltage step. (Remember, our current source is non-ideal, it rails to about 20V, so it can’t regulate current until the voltage drop on the load falls below 20V). The time constants for the load is given by L/R and it is 0.9us, 1.18us and 6us respectively.
This cannot be right: we need to be able to induce a current change of 370mA on the inhibit lines in about 300ns or less. a 6us time constant is 20x higher than that. That’s not going to work. Ever. Still, DEC somehow made it work. So what gives?
Another curious fact is the suspicious lack of kick-back protection on the drive circuits in the PDP-11: you see a large inductive load, like these would produce significant voltage spikes, when turned off. This voltage spike needs to be dealt with, usually in the form of diodes that provide a path for the current that’s built up in the inductance during the on period to safely ring down. This particular design consideration is not relevant to the current sources (it comes up in the switches). Still the fact that DEC didn’t include them there shows that they somehow thought that the load is largely resistive.
I have also tried to measure the inductance: I have an inductance meter, that can measure (if not terribly precisely) a 2.7uH inductor that I have in my drawer. Surely, it would show a 90uH inductance. Yet, it measures nothing. I’ve tried another gadget with impedance measurement capability, it also recognized the loads as resistive. The plot thickens…
My best guess is the following: each core has three wires going through them: one X, one Y line and one sense/inhibit line. These lines however go through several cores. In other words, the create transformers; they create coupling between the cores. Furthermore, looking carefully the the weaving pattern (that’s another term you don’t often here used these days regarding electronics), these couplings are organized in such a way that they cancel each other out. The induced voltage in one core is opposite to another one. If you look at the loads I’ve put on the simulation model of the current source, you see these coupled inductances. No matter though: since these cancel each other out, the end result is a largely resistive load.
Dynamic behavior
So far, I’ve only looked at static behavior and temperature dependence. Of course, the current source will have to behave nicely with load changes. We haven’t talked about how we will switch the loads (that’s coming in a later chapter), so for now, I just put an ideal switch in line with the load in the simulation model. This is good enough for initial transient behavior analysis.
I also set up the turn off and on times offset from one another, such that cross-talk can be investigated.
Here’s the result:
The first thing to notice is that there is enormous overshoot at the front edge. I’m not paying too much attention to it, because – with an ideal switch and a resistive load – that’s unavoidable. I will have to see how much a real switch implementation dampens this.
The next thing to note is the lack of any cross-talk: the current in one channel is not influenced by the switching load on another current source. This is good and of course somewhat idealized: the 20V supply is an ideal voltage source here, which is unrealistic. A real power supply will droop a little which in turn will generate some cross-talk. However, that’s a power supply design issue, not a current source design issue.
The third thing is (apart from the initial transient, the settling time: the current reaches 90% of the nominal value within 50ns. The pulse with for these current pulses is on the order of 200-300ns, a 50ns settling time is very much acceptable. In fact, I might have to slow it down a bit if it turns out the induced noise of the rising edge is too high.
Of course, this too will be influenced by the real load switch that is idealized in this model. Another thing that I can’t even test here is the turn-off transient: the idealized nature of the switch simply doesn’t allow for any measurements of that.
All this means that I will have to come back to the current source and re-analyze it with a real load-switch hanging off of it, but that will have to wait for another chapter.
Fine tuning
After adding the true loads (which I will describe in the next chapter), several problems reared their heads. Namely, I couldn’t get rid of the initial spike and the current response in general was rather slow. Much slower in fact, than what the above experiments would make you believe. The read and write pulses need to be around 300ns long, yet the current source couldn’t even get through its transient phase in that time.
This prompted several changes. The most important one was to change the power transistor to something way more snappy: the TIP42C that I intended to initially use had a transition frequency of only 3MHz. I’ve changed it to the 2DB1182Q, which is much faster at 110MHz. I’ve also added several tuning elements to the current source: a base-resistor in front of the power BJTs, and both a positive and negative feedback capacitors from its emitter and collector to the base. The right tuning of the values of these elements seem to depend on the load somewhat and I expect that real-world parasitics will impact their values as well. So I will include them on the PCB, but plan for easy ways to change, if necessary.
This is what this updated power-stage looks like:

The step-response on the inhibit wires looks like this:

The three colors correspond to 0, 25 and 50C respectively. You see how the current more or less reaches it stead-state in about 100ns, while it has a 50ns turn-on delay (this later has nothing to do with the current source and more with the switch drive logic).
The same can be said about the X and Y lines:

Heat management
There is a new problem though: these new transistors are surface-mount devices. I can’t attach them (easily) to a common heat-sink. There is a good white-paper from Rohm on how this particular package works with various PCB heat-sinks. With minimal effort, the thermal coefficient is on the order of 100C/W. That is to say, if the ambient temperature is at 25C, I can’t really expect to dissipate more than 1W on these transistors (their junction would be 100C higher then ambient, at 125C). In general, this is how they think the thermal coefficient changes with copper area:

To get to 4W, I would need this curve to reach 25C/W, which it doesn’t. So, what can I do? The idea is the following: first, figure out what the minimum voltage drop the current source needs to operate properly. It’s certainly less than 2V, but let’s use 2V as a reference. Then, add artificial (series) load resistors to each current source such that the overall voltage drop on every load is 18V. This is not as easy as to make sure that the load resistance is 36 ohms total, as the load contains a number of series diodes as well, but still, it can be done. If we limit the voltage drop on the power BJTs to 2V and (allowing for some overhead) assume a 0.5A current flowing through them, that is a peak power dissipation of 1W. That is manageable in this package. Unfortunately thermal coupling is not going to be ideal as a common copper heat-sink for all power transistors is not possible (the exposed pad is the collector, but the collectors are not tied together in my circuit).

There are techniques to improve the coupling, but it’s going to be somewhat impaired for sure.
The rest of the power dissipation will happen on the artificial load resistors: these need to be high-power resistors (5W or so to have some headroom), but that’s OK. I just have to be careful not to touch them.
Parting words
For now, let’s take stock of where we are: we have a 34-output current source, with about 3.5% static accuracy, which can probably be lowered to 3, maybe even 2.5% and a 100ns settling time. These parameters are good enough to move forward with the design, which is to say, this is all I have for today’s installment. I’ll leave you with this though again: theory gets you only so far. I don’t expect these circuits to perform without issues once I build them. I in fact expect to have a few rounds of changes before I settle on the solution. Hopefully these preparations get me to a point where a whole rip-up is not going to be needed and only small changes and tuning is going to be necessary.
But before we get there, there’s lot more ground to cover, so let’s continue marching forward!











