Introduction
My transistorized computer has now a CPU and RAM (well, core memory, but potato-potato). Many, if not most computers of the technology area where this design belongs to (mid-’60-s) didn’t have any ROM memory. This is the reason for the large control panels and rows of toggle switches: every time you turned the machine on, you either started running from core memory (which is non-volatile) or you “toggled in” a boot-loader to load your program from paper tape or some other medium.

This cannot stand in the modern era. I cannot stand that idea. I want to have at least some ROM. Something that can jump-start the machine. So, in this chapter I will describe my plans for a small ROM for this machine.
Photonic ROM
There are many many ways of making ROM memory. I guess in the ’60s, you would most likely follow the route the Apollo Guidance Computer took and build a core rope memory. That is not only very tedious to build, something that cannot be automated away but next to impossible to fix if something goes wrong in the process. On top of that, it looks like a nightmare to drive. (Large inductive loads with all sorts of couplings between one another, needing very large and quick switching currents. No, thanks!)
So, instead I came up with an optical way of implementing the ROM. Here is the basic idea: imagine a table that has a bunch of rows that can be individually illuminated.

Now, imagine a lid, you can put on top of this, containing column-shaped light-detectors. These detectors output a ‘1’ if they sense light anywhere in their column-shaped sensors

In between the table and its lid, you can place a piece of transparent foil, on which you print some black squares:

Now, by selecting a single row to illuminate and a column to sense with, you can detect whether a particular square is filled or not. You have a ROM memory.
The beauty of this idea is that I have to construct the row illuminators and the column sensors only once. After that, I can generate new memory content on my PC using a script (essentially compiling into an image file), which then I can print on a transparency. Very quick turn-around and fully automated.
In terms of actual implementation, I think I will have to design some light guides for both the rows and the columns.

Essentially, custom-cut acrylic sheets. Loads of them.
What could possibly go wrong?
Well, a lot of things, actually. There would be a single LED at the end of each row and a photo-diode (or photo-transistor) at the end of each column; I have to construct the light-guides that distribute and focus the light as the case may be. This will take some trial and error for sure.
There is also cross-talk to deal with, in other words, light leaking between rows and columns. I think I can keep that in check, but there might be dragons there.
Then there is alignment. I think that is going to be biggest issue: I have to line up the rows and columns pretty well between each other and then perpendicular to one another. Finally, I have to have some way of aligning the transparency in the middle with both. I wouldn’t be surprised if this latest thing turned out to be the limiting factor.
Still, I’m thinking I should be able to fit a 64×64 matrix on a letter-sized transparency. Maybe even 128×128. The first one would give me 512 Bytes of storage, the latter 2 kBytes. Divide each by two to get the number of words, as my machine uses 16-bit words. Even with the smaller size, that is 256 words, something that should fit a simple boot-loader. Of course I would have to actually code it up to be certain.
Building blocks
So, here is what I need:
I need to drive LEDs (I looked into this, actually. LEDs first came to market in 1963, so I don’t think there’s anything that’s outside of being period-accurate here).
I will need sense amplifiers that can detect the small electrical signals coming from the photo sensors, being photo-transistors or diodes. I will need to multiplex the many columns (64 or 128) into the 16 sense amplifiers in some clever way without destroying the signal or introducing cross-talk.
Finally, I’ll need some bus interface logic, address decoders, the usual jazz.
So let’s go one-by-one
LED drivers
For driving the LEDs, I’ll need to create a similar matrix-drive scheme to what the core memory line drivers use. Luckily, LEDs are much less picky about their operating currents, so simple resistor-based current control should suffice. I won’t have to do level-shifting either. Overall, this doesn’t look horribly complicated. Here is how one drives a single LED:

To make this into a matrix, one can try something like this:

This works, but there are problems:

The fact that both high- and low- levels, as well as the diode forward voltage are temperature-dependent make our diode current highly temperature-dependent as well.
The other are the transients. They are mostly generated by the LED capacitor getting charged and discharged. This can be verified by hooking the same LED up to a voltage source:


This explains the turn-on and off transients, but what about the ones where the current stays zero before and after? Let’s chart the diode voltage and current in the original matrix setup next to each other:

This explains everything: the LED is kept in reverse-biased configuration of course, but the amount of reverse bias changes. That means that the LEDs intrinsic capacitance will need to be charged up and down, generating transients.
What I don’t know is if these transients actually generate light as well. If you know, let me know.
I think for now, I’m going to keep this setup as-is and only change things if experiments show, I have to.
Light detectors
There are two types of light detectors on the market: photo-diodes and photo-transistors. There are many sub-types as well, but let’s keep it simple. These devices are obviously different, but I believe a photo-transistor is constructed by essentially making their base-collector junction light-sensitive.
Now, to play around with these things in LTSpice, one would need to model some sort of optical connection between the LED and the photo detector, be it a diode or a transistor. That’s beyond my abilities, so I did something simpler: use an opto-coupler:

These things contain an (infra-red) LED and a photo-transistor. The transistor has all three terminals exposed so it can be hooked up as a photo-diode as well (by shorting its base and emitter). Yes, the optical path is not what I would have, but better – much better – than nothing.
My initial guess is that in my system I will lose on the order of 99.9% of the light coming from the diode. The opto-coupler on the other hand is very efficient in that regard. Probably.
Let’s play around with the opto-coupler to get some sense of the orders of magnitude we’re dealing with here.
To start things out, let’s see how much current do I get out of the photo-diode, if I pump 20mA current through the diode!

I got 35uA on R82, which translates to 3.5mV drop. Now, if I assume my setup will lose 99.9% of the light, that would mean 35nA of current in my case. That is compared to the 5nA (typical) dark current of this particular photo-diode. In other words, really, really low.
Looking at a reasonable true photodiode, one sees 5pF capacitance, 6ns rise and fall times and 10nA (max) dark currents. The documented light current is between 0.5 and 3uA (a rather large variation!).
Either way, none of these devices seem to have a dynamic range for me to reduce input light by three orders of magnitude. That means either high-power LEDs, more LEDs or sharpening the pencil on losses. Or all of the above.
At any rate, instead of trying to guess what the light current is going to be, here’s another approach: let’s assume that we have reasonable signal-to-noise ratio on the output. That is to say that the light current for me is at least an order of magnitude higher than the dark current. If dark current is 10nA, that would mean 100nA minimum light current.
To get an idea of how much or how little this current is, let’s look at the following: if we want reasonable rise and fall-times, we need a relatively low load resistance. Say 1kOhm. The 100nA current would drop 0.1mV of voltage on that resistor. We would need to reliably detect that much voltage in – say – 100ns or so. A formidable challenge.
Light reference
In order to reliably detect such low voltages (even if it’s an order of magnitude higher in reality), I need a precise reference. Any amount of ambient light will compete and destroy the measurements. Here is the approach, I came up with:
I will have pair of extra detectors in my ROM. Each foil that I print will contain an all-dark strip over one and an all-transparent strip over the other. This way, these two detectors are guaranteed to give me the known high and low currents for 0’s and 1’s every time the ROM reads anything. I will create and average value of the two by summing their currents and dropping them on a half-sized resistor compared to the other detectors. This will create a reference voltage that I can use in my differential comparators to differentiate 0’s and 1’s. The rough schematic of the idea is as follows:

Obviously, I’ll have to construct the sense amplifier out of discrete components, this is just a block diagram. There would be 16 sense amplifiers and 64 or 128 column read diodes. This needs multiplexing and it adds a ton of extra load on the reference diodes. I will probably need to buffer those voltages, something that will not be easy with such low voltage levels.
Why not photo-transistors?
Indeed, why not? Let’s hook up our opto-coupler as a photo-transistor and look at its output!

Measuring the voltage cross the resistor we get the following response (after the power-on transient):

A mere 30mV swing. Of course that’s still much better than the 3.5mV I got with the photo-diode setup. The trouble is in the response time: what you see here is pretty much a triangle wave. Compare it to the waveform I got on the photo-diode:

Excuse the negative sign, that’s just a side-effect of the way I have things hooked up.
If I reduced the light intensity to the point where the photo-diode output is 100nA, I get the following response from the photo-transistor setup:

That’s a mere 4.4uV of output, even less than the raw photo-diode would give me (10uV). Pathetic! At least the edges look better though.
So, where does it leave us? I think I can draw the following conclusions:
- I need a lot of light. I can’t afford to operate the photo-detectors at such a low current level
- I don’t like photo-transistors, they are slow
- I’ll need to get pretty clever with the sense amplifier design. It needs to be very precise over temperature and component variation, something that’s going to be hard to control
- I need to do experiments: LTSpice simply doesn’t give me enough to understand the operating point of the circuit. And that matters. A lot.
Ganging up
If sensitivity is a problem, I can always do:
- As many series LEDs per row as needed to get the appropriate brightness
- As many parallel (current-summed) photo diodes as needed to get the losses under control
This becomes annoying to assemble and expensive too, but, on the plus side, it simplifies (potentially greatly) the light guide design.
Sense amplifier
Either way, the better sense amplifier I can come up with, the lower the number of LEDs/photo-diodes I’ll need. So let’s get cranking!
The starting point is going to be the sense amp I have for the core matrix. Let’s rip out all the digital logic and the summing node and make it into a simple diffamp first:
For now, I’m going to leave it on a symmetrical power supply and bias the inputs to ~0V. The gain seems to be around 200 (100 for each of the outputs) with pretty good temperature tolerance. The input bias voltage seems to vary only about +/-0.5mV across -25 and 125C. That’s a bit too high, but maybe tolerable?

At any rate, the next step would be to add some positive feedback. The idea is the following: when we want to detect the input, we send the output of the sense amp back to its input, but in a positive, reinforcing way. That will create an “avalanche” and pretty quickly saturate the outputs one way or another. The direction depends on the minute difference between the inputs when we turned on the feedback path. Which reminds me: the feedback of course needs to be turned off after detection so that output can reset to following the input.
For my first trial, I even removed the second stage diff amp, mostly because it has a very high common-mode output, something, that, when fed back to the input overwhelms the input stage. So, the fed-back design as as follows:
Q31 and Q32 can force the output to a negative voltage when ‘EN’, the enable signal is low. This disables the feedback as well. When ‘EN’ goes high, the outputs are fed back to the input through Q29 and Q30, creating positive feedback: the amplifier will rail one way or another depending on the differential input at the time of the rising edge of EN. It will stay in that railed position until ‘EN’ transitions low again.
I fed the input with a low (10mV) sine wave, and here’s what the (differential) output looks like:

This thing really acts like a sense amp! Except of course, you have to take a closer look at the time axis: it’s very very slow. The rising edge of the output is actually reasonably fast, around 90ns. However the recovery from the saturation is not so much. So, how to make it scream?
After playing around with the simulation parameters, I managed to get a diagram that shows the recovery time (this time you see temperature dependence as well):

About 750ns, worst case. That’s way to long, I can’t afford that (without doing wait-states, which I would prefer not to). So what is causing it? It appears that something goes into saturation. Can I figure out what that is? It must be a transistor where the B-C diode opens up. And it opens up during the hold operation (thus needing to wait for the recovery during sample). During hold Q31 and Q32 are off, so it can’t be that. This leaves Q29 and Q30. Indeed: when we saturate the diff-amp, one of the feedback transistors go to saturation. The one corresponding to the ‘high’ output. Can we prevent that? Yes, maybe. First, I needed to add some clamping diodes and then rearrange the base-resistors to limit base current while achieving reasonable output swing:
This arrangement has some rather borderline behavior at temperature extremes, but still functional:

Here you see the cycle time on enable being 500ns (target 2MHz) while ‘EN’ is pulled high for 300ns.
Let’s try a different setup: slowly increase the differential input and see where the detection gets fuzzy. Now, let’s sweep temperature to get an understanding of the ‘fuzziness window’.
So, this is interesting. The worst offset is actually at 100C. At that temperature, we need 170uV differential input to get a reliable detection:

Limiting myself to 0-50C (which is where the core memory is specified to operate), the minimum input voltage threshold ranges from 50uV to 100uV.
Now, let’s consider that component variations will add another wrinkle to this. In PSpice, all transistors are identical, but in reality they are not. Do I believe that this circuit can detect 110uV differential inputs? Maybe. But this certainly needs to be validated.
Adding photons
To get better understanding of the system let’s drive it with a “real” photo-diode!
I needed to add an emitter-follower input stage to de-couple the sensitive photo diodes, but other than that, things seem to be working. From now in, my inputs are the LED currents, but you can see that the output changes polarity as it should.

Now, let’s see this over temperature and zoom in at the cross-over point:

There is some sensitivity, but it’s hard to say how much. Let’s slow the ramp down and try again!

It’s not easy to see on the screen-capture, but the ambiguous region is between -50 and 200uA. Make it symmetrical and call out the larger: +/-200uA.
It’s hard to relate this back to illumination as I’m using a “black box” model for an enclosed opto-coupler. However, assuming that the optical coupling is rather good within the package, 200uA of a 20mA LED is 1%. If that holds true for the real system as well, I can lose about 99% of the light and get a reliable reading out of this circuit (dynamics of the input is still to be checked). I estimated 99.9% loss previously, so I need to improve things by an order of magnitude. At least.
Most photo-diodes like IR light in the 800-900nm wavelength range. IR LEDs apparently have a rather high operating current, 50mA seems typical. Even the opto-coupler I’m using here is rated up to 60mA (albeit the typical datasheet spec is 10mA). So, taking the 50mA LED current and same brightness curves as an assumption, one would get a factor of 2.5x improvement. Using 2 LEDs per row and two photo-diodes per column, one gets another factor of 4, giving me the needed order of magnitude improvement.
Dynamic performance
Let’s drive now the LED with a current that’s slightly off frequency with the 2MHz readout (EN) clock. This will shift the rising edge of the LED input current relative to the rising edge of the EN signal. With this setup one can see how much setup time we need for a reliable detection. At 10mA, it seems we need ~125ns:

Now, this time should increase as the differential input reduces. So, let’s reduce the (differential) LED current to 200uA:

Well, turns out that’s not the case; it’s actually somewhat faster (maybe not by enough to make a difference).
Either way, since the setup time is non-zero, we need to introduce some timing (similar to what’s going on in the core memory control) to the ROM as well. There the timing resolution was 62.5ns, so taking two ticks of that making a 125ns delay seems to be safe.
Conclusions
Let me stop writing now. What I have here is a reasonable plan going forward. I have a serviceable sense amplifier and some idea of what the control logic would look like.
To finalize things, experimentation is needed. I’ll have to figure out light guide losses, true LED brightness curves and how they related to photo diode sensitivities. In the end, I need to establish an LED current –> photo diode current relationship for my system. There’s nothing that can replace that work.
From the hand-wavy numbers here it seems that maybe a couple LEDs and a couple of photo-diodes per row/column can make the design close. That’s not terrible, but that leads me to this final note: the LED driver needs to change. The LED current will have to be more stable and much higher (~50mA, well controlled over temperature). The series LEDs have a higher forward drop too, so I can’t operate the drive circuit from 3.3V (minus losses) anymore. I’ll have to come back to that problem at a later point.
There’s also the input and output multiplexing logic, the control plane as well that needs to be figured out.
All that I think will have to wait until after I have more idea of the number of LEDs and photo-diodes I need. That’s going to be the next step.


