I just got back from my client’s product launch party, where I had entirely too much excellent food and drink, so I’m not actually taking advantage of the parts being early.
Late last night I finished the schematic and PCB layout, and ordered boards. As soon as I woke up this morning I realized that I forgot to deal with the 5V CMOS output of the TIA-232-F receiver feeding the non-5V-tolerant FPGA input. There needs to be either a series resistor or a pair of resistors as a voltage divider. I’ll have to cut that trace and bodge one or two resistors.
I ordered parts from Digi-Key to build two units. Of course, shortly after placing the order I realized that I’d forgotten to order power supplies. It doesn’t require anything too special, just regulated 5V 2A with a 2.1/5.5mm coax plug.
I expect most of the Digi-Key order to arrive on Friday, and the PCBs will likely be here on Monday.
Other stuff I ordered to build the project arrived today:
I have two soldering stations at home, but I’m not there so I had to order a Hakko FX-888D to use here. I also expect to breadboard a few more things, so I ordered five more solderless breadboards, and (not shown) more precut breadboard wires.
Although I got the LTP-305HR dot-matrix LED multiplexing working, it doesn’t look anywhere near as nice as the original HP 5082-7340 or TI TIL311 hexadecimal displays. I’ve decided to drop my original plan to use the LTP-305HR displays, and use the hexadecimal displays instead. Broadcom (previously Avago, previously Agilent, previously HP) does still make similar hexadecimal displays, though without the red filter. They are quite pricey.
I’ve focused on getting the schematic and PCB layout done so that I can order PCBs this week. The switch PCB and switch bezel PCB are only minor tweaks to some I made last year, so those are ready. I’ve got the main board layout nearly completed; I need to add one electrolytic capacitor for bulk bypass, and one 14-pin header for configuration and/or expansion. Here’s an image of the not-quite-complete layout:
The board will accept either the HP 5082-7340 or TI TIL311 displays, using interleaved footprints. The board can be stuffed with just the traditional two digit data display, or can additionally have a four digit address display.
The I/O ports are a USB port (providing JTAG programming and a virtual UART) on the Cmod-A7 FPGA board, a MicroSD card, a TIA-232-F serial port, and an RCA jack for monochrome composite video.
I’ve now got full multiplexed display operating on the breadboard prototype for my RC2017/10 project:
I also shot a brief video showing chaning hexadecimal values.
There are six 5×7 displays, physically all in one column to fit the breadboard, but logically arranged as two rows of three columns. The code running on the Microblaze configures a timer to get a 15 kHz interrupt, and each invocation of the interrupt handler outputs 32 bits via the SPI port to the display drivers. 15 bits are the column data, with only one bit set at a time. 14 bits are the row data. The remaining three bits are unused.
Each successive interrupt advances to the next column. Since there are 15 columns, the entire display is refreshed at a 1 kHz rate.
While I’m glad to have it working, it does not work as well as I would have liked. The pixel intensity varies more than I’d hoped, and pixels that should be off are dimly illuminated. (This shows up worse in the photo and video than looking at it in-person.)
I think the pixel intensity variation occurs because I don’t really have enough voltage. There’s nominally 5V from USB Vbus, but the Cmod-A7 has a schottky diode between Vbus and the header pin. At the supply pins of the display driver ICs, the measured supply voltage ranges from 4.27 to 4.4 volts. The source drivers can drop up to 2.5V, and the LED forward drop is around 2V, leaving insufficient voltage range for the current-controlled LED sink drivers to actually achieve good current control
The variation between 4.27 and 4.4V is due to variation in the load. I was lazy and didn’t put any decoupling capacitors on the breadboard. Adding typical 0.1uF decoupling capacitors is probably nowhere near enough to filter this out; I probably need 1.0 or even 10 uF ceramic capacitors paralleled with much higher capacitance electrolytics, as close to the driver chips as possible.
The problem with off pixels being dimly illuminated seems to be due to the source drivers turning off very slowly. Here are the SPI waveforms along with one representative column drive waveform:
When the column driver is enabled, 1/15 of the time, its voltage is about 2.43V. When it is disabled, there is a small immediate drop, but it takes it quite a while to drop to its minimum of 51mV. At a 15 kHz rate, a 32 bit word is shifted out the SPI port of the processor into the display drivers. Channel 02 shown is the SPI “slave select” which acts as the latch signal to the drivers. Channel 04 is the analog waveform of one of the column source drivers.
When the column driver is enabled, 1/15 of the time, its voltage is about 2.43V. When it is disabled, there is a small immediate drop, but it takes it quite a while to drop to its minimum of 51mV. Because of the slow drop, the row drivers that are active during the next few columns will sink a lesser amount of current from this column.
I will have to make a decision soon as to whether to continue with this design for the RC2017/10 project, or to revert to using the traditional 5082-7340 or TIL311 hexadecimal displays.
I finally finished wiring the LED displays on the breadboard prototype. What a mess!
The LTP-305HR displays are still being driven basically statically, with only one column of LEDs (on both logical rows) being illuminated at a time, and only changing at a very low rate. I still need to write Microblaze code to set up the timer for a 15 kHz interrupt and drive it from that for proper multiplexing.
After that, it will be time to write the VHDL to control the display entirely in hardware.
Since I’m confident that the display drivers work, I can start laying out the PCB now.
There is more variation in display intensity than I’d hoped, dependent on the number of LEDs illuminated in in a column. This is probably due to not really having enough voltage to work with. It’s not ideal, but the only practical alternative would be to require an additional power supply. A 6V supply would probably be fine. The higher the voltage, the more power the sink drivers have to dissipate.
I’ve added a second breadboard to prototype with all six LTP-705HR displays, and the additional sink and source driver needed. The matrix is wired, but not all of the drivers are hooked up.
For my previous FPGA-Elf, I used actual hexadecimal displays as per the Popular Electronics construction article. The only hexadecimal LED displays still made are from Broadcom/Avago, don’t have the integral red filter, and cost around $40 each. Used or NOS HP and TI displays are also rather expensive, so I’ve now chosen to use the LiteOn LTP-305HR 5×7 dot matrix LED display, available for $3.67 each in quantity one from Digi-Key. It is based on the TI TIL305, which in turn was based on the Monsanto MAN2A. The packaging is nearly identical to the TIL311 hexadecimal display.
Unlike the hexadecimal displays, the LTP-305HR contains only 36 bare LEDs (including one decimal point, which I won’t use), with no drivers. Since they are in a matrix, with anodes connected to five column lines, and cathodes connected to seven row lines, they require multiplexed drive. I want to have up to six digits (to display both address and data), so the most efficient organization will require 15 anode drivers and 14 cathode drivers. Electrically this is an arrangement of two rows of displays by three columns, although physically they will be mounted on the PCB with all six in a single row.
While the Digilent Cmod-A7 FPGA module has 44 digital GPIOs available, I don’t want to dedicate 29 of them to the display, so I prefer to use driver chips controlled by an SPI synchronous serial interface. In the past I’ve used Allegro drivers such as the A6275 octal LED sink driver and the UCN5891A or UCN5895A octal source driver, but unfortunately these have all been discontinued.
The A6275 sink driver was quite convenient in that it used internal current mirrors, so it controlled the current on all outputs based on a single external resistor, avoiding the need for current-limiting resistors for each LED cathode line. Allegro also made a 16-bit version, the A6276.
It is not easy to find suitable parts still made in DIP (through-hole) packages, since so much of the world has moved to SMD. As it happens, Microchip, which acquired Micrel a few years back, still offers the MIC5891 source driver in a DIP package, though the saturation voltage specs is slightly worse than the Allegro UCN5891A, and much worse than the Allegro UCN5895A.
I wasn’t quite so lucky with the A6275. Toshiba made a pin-compatible part, the TB62705, but they’ve discontinued it. On Semiconductor offers the CAT4008, which is pin-compatible, but not available in through-hole. Finally I found the TI TLC5916, which is not pin-compatible, but is still offered in DIP. The TLC5916 actually has increased functionality compared to the A6275 et al., including programmable intensity compensation and fault detection, but I have no plan to use those features.
The board will run on nominally 5V from USB, provided through the MicroUSB connector of the Cmod-A7 module. However, the Vbus voltage at a USB device may be as low as 4V, and the Cmod-A7 has a schottky diode in series from the USB Vbus to its header pin, dropping another few hundred millivolts. The LEDs have a forward voltage of around 2V, and the saturation voltage of the MIC5891 can be as high as 2.5V when sourcing 350mA. The TIL5916 sink driver controls the current by varying its output voltage. After adding this all up, it’s unclear whether there’s enough voltage to drive the LEDs. The MIC5891 saturation voltage is lower when the current is lower, so I need to determine what LED current is needed at 15:1 multiplexing.
I’ve put a Cmod-A7-15T, TLC5916, MIC5891, and LTP-305HR on a breadboard for testing, along with a TIL311 hexadecimal display for comparison:
I used a MicroBlaze soft-core processor in the FPGA to control everything for test purposes. I am using PWM to control the enable of the source driver, so I can test running at 1/15 duty cycle, even though I don’t yet have the actual display multiplexing running.
I’ve found that with approximately 1/15 duty cycle and with a 1.5K ohm resistor on the sink drivers, I get LTP-305HR display intensity that seems comparable to the TIL311. The TLC5916 sink driver will sink current at 18.75/Rext A, so with a 1.5K resistor that’s about 12.5mA per LED. For the full matrix, a maximum of 14 LEDs will be on simultaneously, so the maximum source driver current will be 175mA, so the MIC5891 source driver saturation voltage should be under 2.4V, though I haven’t actually measured it.
The hexadecimal font to look like the traditional displays will never have more than three LEDs on in any single column of the center three columns of a character, so if I electrically stagger the two logical rows of displays, so that the left and right edge columns of the top row displays are not coincident with the edge columns of the bottom row displays, then no more than 10 LEDs will be illuminated simultaneously, which will further reduce the peak current to 125mA. I may also put some higher value capacitors next to the decoupling capacitors for the drivers, to further average the overall display current.
The FPGA output pins have Voh below 3.3V, while the display drivers, which run on 5V, have Vih(min) of 3.5V. I’m cheating on my breadboard, counting on the drivers to actually have a threshold somewhat below 3.3V, which in practice at they typically do, at least at room temperature. On the real FPGA-Elf board, I will use an SN74AHCT245 to act as a level translator for various signals. One channel of the ’245 will be used with a voltage divider to shift the data output of the last driver chip down to 3.3V level for input back to the FPGA.
One issue with the LTP-305HR compared to the older HP and TI hexadecimal displays is that it uses 635nm “high efficiency red” LEDs, rather than 650nm LEDs which were much more common in the past. To me, 635nm looks orange-red rather than red, but then, I have partial red-green color blindness, so the frequency response of the green pigment in my eyes is shifted closer to red, and I see some colors differently than people with normal color vision. I need to show the TIL311 and LTP-305HR to someone with normal color vision, and see whether they perceive as much difference in the hue.
For the RC2017/10 RetroChallenge, I will update my FPGA-Elf to run on a relatively inexpensive FPGA board, and make PCBs to provide the necessary I/O interfaces. I plan to add the equivalent of the CDP1861 “PIXIE” graphics. At the conclusion of the RetroChallenge, I will offer the bare PCBs for sale, so that others can build an FPGA-Elf.
In 2008 I developed a soft CPU core equivalent to the RCA CDP1802, and in July of 2010 used it in a RetroChallenge project as the basis for an FPGA-Elf, functionally equivalent to the Popular Electronics COSMAC Elf from 1976. Since then I have made a few minor updates to it, migrating it to a Xilinx Artix-7 FPGA, and making PCB-based front panel switch and bezel boards. Unfortunately the FPGA board I used is not commercially available, and would be extremely expensive if it were.
For this project, I’ll migrate it to a Digilent Cmod-A7-15T (or -35T), which is an inexpensive ($75 or $89) FPGA board with the Artix-7 FPGA, a USB interface, SPI flash, static RAM, and headers providing a 48-pin DIP footprint, suitable for use on a solderless breadboard.
I will lay out a base PCB, into which the CMOD-A7 can be plugged, which, combined with the switch and bezel boards, will form a complete Elf. The CMOD-A7 is sold fully assembled, and my own boards with be through-hole only, with no SMD components, so the Elf will be easily assembled by anyone with only modest soldering experience.
In order to keep costs down, instead of the obsolete HP 5082-7340 hexadecimal displays used in the original Elf (which were expensive even when new), or the also-obsolete TI TIL311 hexadecimal displays that have been more commonly used in recent years, I will use current production LiteOn LTP-305HR displays. These are 5×7 dot matrix displays that look similar to the TIL311, but still being manufactured, and cost only $3.67 each from Digi-Key. The PCB will be designed to support either two displays for data only, like the original Elf, or six displays to have address and data.
The board will also support a MicroSD card for mass storage, using an Adafruit MicroSD card breakout board, but I don’t plan to write any software for that until after the RetroChallenge.
There’s a Python 3 program I’ve been developing off-and-on for three years now. The program takes an XML file as input, does some processing, and outputs a binary file. After some recent changes, I find that the program hangs. If I hit control-C, I get a traceback. I added a print in one of the loops to tell me which object it is processing, and was astounded to find that if I run the program multiple times with the same input, it processes the objects in different orders. There is no (intentional) non-determinism in my program.
Python has as one of its basic data types a dictionary, which is a key to value mapping. Internally it is implemented as a hash table, so the key can be of any data type that can be hashed, including numbers and strings. If you enumerate the keys that are present in a dictionary, you will get them in an unpredictable order. Historically it was unpredictable but deterministic, based on the hash values.
For my purposes, the dictionary enumeration order being unpredictable is fine, but I want it to be deterministic, so that multiple runs of the program with identical input will produce identical output.
It turns out that starting with Python 3.3, by default the hash function used is randomized, so the same program with the same dictionary contents will result in different enumeration orders on different runs:
The hash randomization is claimed to be a security feature. I’m unclear on what security it provides. It is possible to disable hash randomization using an environment variable passed to the Python interpreter.
I’m using Python 3.5. Starting with Python 3.6, the implementation of dictionaries is different, so even though hash randomization is still the default, the dictionary enumeration order is no longer based on the hash, and is once again deterministic.
At some point, Python added support for a new dictionary type OrderedDict, which enumerates in the order of element insertion, which happens to be the same thing that Python 3.6 does with normal dictionaries. After changing one line in my program to initialize a particular variable as an OrderedDict rather than a “plain” dictionary, my program is once again deterministic, even with hash randomization enabled.
A list of electrical engineering maxims by DEC Engineer Don Vonada:
- There is no such thing as ground.
- Digital circuits are made from analog parts.
- Prototype designs always work.
- Asserted timing conditions are designed first; unasserted timing conditions are found later.
- When all but one wire in a group of wires switch, that one will switch also.
- When all but one gate in a module switches, that one will switch also.
- Every little picofarad has a nanohenry all its own.
- Capacitors convert voltage glitches to current glitches (conservation of energy).
- Interconnecting wires are probably transmission lines.
- Synchronizing circuits may take forever to make a decision.
- Worse-case tolerances never add — but when they do, they are found in the best customer’s machine.
- Diagnostics are highly efficient in finding solved problems.
- Processing systems are only partially tested since it is impractical to simulate all possible machine states.
- Murphy’s Laws apply 95 percent of the time. The other 5 percent of the time is a coffee break.
Source: Computer Engineering: A DEC View of Hardware Systems Design, 1978, Digital Press, Chapter 1, “Seven Views of Computer Systems”, by C. Gorgon Bell, J. Craig Mudge, and John E. McNamara, Table 5