Archive for February, 2010
A CPU in a CPLD
OK, the CPU design spark is back, sooner than I’d expected. I have an urge to implement a minimal CPU using a CPLD. If you’re not familiar with the term, a CPLD is a simple programmable logic chip, existing somewhere on the complexity scale between PALs (like the 22V10’s I used in BMOW) and FPGAs. Typically a CPLD has a similar internal structure to PALs, with macrocells containing a single flip-flop and some combinatorial logic for sum-of-products expressions. They are also non-volatile like PALs. Yet typical CPLDs contain 10x as many macrocells as a PAL, with some macrocells used for internal purposes and not connected to any pin. FPGAs are generally much larger and more complex, with thousands of macrocells and specialized hardware blocks for tasks like multiplication and clock synthesis. FPGAs also normally contain some built-in RAM, and are themselves RAM-based, requiring configuration by some other device whenever power is applied.
I’m attracted to CPLD’s because I’m hoping they’ll provide a good step up from PAL’s, without drowning me in FPGA complexity, as happened when I worked on 3D Graphics Thingy. I’m pretty confident I can figure out how to work with CPLD’s without driving myself crazy, increasing the chances that I might actually finish this project. Given the limited hardware resources of CPLD’s, fitting a CPU will also be an interesting challenge.
I’ve also been wanting to design my own custom PCB’s for quite some time, and this will give me an opportunity. The end goal of this project will be a single-board computer on a custom PCB, with my CPLD-CPU, RAM, ROM, some input buttons/switches, and some output LEDs/LCD. I need to limit myself to CPLD’s that come in a PLCC package, so I can use a through hole socket and solder it myself. Unfortunately that will limit my choices pretty severely. I think it’s theoretically possible to hand-solder the more common TQFP surface-mount package, but I’m not excited to try it. And for other package types, forget it.
Here’s some back-of-the envelope figuring to get the ball rolling. This is assuming an 8-bit CPU with a 10-bit address space (1K).
I/O pins needed:
- 8 data bus
- 10 address bus
- 1 clock
- 1 /reset
- 1 /irq
- 1 read-write
- ~4 chip selects for RAM, ROM, peripherals
That’s 26 I/Os. So a PLCC-44 package should be fine, as CPLDs in that package typically have about 34 I/Os.
Macrocells needed for holding CPU state:
- 10 program counter
- 10 stack pointer
- 10 scratch/address register
- 8 opcode register
- 3 opcode phase
- 8 accumulator
- 8 index register
- 3 ALU condition codes
That’s 60.
Then I’ll need some macrocells for combinatorial logic. This is a lot harder to predict, and in many cases I should be able to use the combinatorial logic resources and the flip-flop from a single macrocell. I’ll just pull some numbers out of thin air.
Macrocells needed for combinatorial logic:
- 16? arithmetic/logic unit (8-bit add, AND, OR, shift, etc)
- 16? control/sequencing logic
- ??? other stuff I forgot
So that’s a grand-total of 92 macrocells for everything.
If I shrunk the address space down, and maybe changed to a 4-bit word size, I might be able to fit it in a 64 macrocell CPLD. But more than likely, it seems I’ll be looking for a CPLD in the 100 to 128 macrocell range. Considering my requirement for PLCC packaging, that will limit the choices to two or three possibilities, but more on that later.
I think the most challenging part of this project will be the control/sequencing logic, and the assignment of opcodes. BMOW was microcoded, and used a separate microcode ROM to execute a 16-instruction microprogram to implement each CPU instruction. In this case, I’ll need to create dedicated combinatorial logic to drive all the enables, selects, and other inputs in the right sequence to ferry data around the CPU to execute the instructions. Doing this with minimal logic will be a real challenge, and undoubtedly I’ll be using the bits of the opcode itself to derive many of those control signals.
Read 12 comments and join the conversationRC Servo Signal Decoder, Part 2
It works! I’ve continued poking away at this circuit to decode an RC airplane servo signal and trigger a camera shutter during flight, and I’m happy to report success!Once I switched to using the CD4013 flip-flop with a positive logic clear input instead of negative logic, it was a piece of cake. I have to say, living just a mile from one of the USA’s largest electronics dealers (Jameco) is pretty sweet. I can hit their web site and place an order for practically any obscure electronic component I can think of, then cruise down to their offices and pick it up from the will-call desk an hour later. Nice!I rebuilt the decoder circuit that I discussed last time, soldering everything together “dead bug” style. This was necessary in order to keep everything as small as possible, so I could fit it inside the camera body. I forgot to take a photo before I closed everything up, but it looks very similar to this example from laureanno.com:When I first connected the servo, decoder, and camera, it didn’t work. Nothing happened when I toggled the switch on my RC transmitter. Setting up the oscilloscope again, I was able to see that the reference pulse width generated by the RC circuit I’d built was about twice as long as it should have been. I’m not sure how that happened, even with 20% tolerance components, but I was able to quickly swap in a different value resistor, and get it working perfectly. Then with a bit of creative packing, I managed to cram it all back inside the camera body.Today during my lunch hour, I was able to try it out for the first time. The shutter trigger worked fabulously! I wish I could say the same for the quality of the pictures, but unfortunately the focus wasn’t set quite right, and the photos are a little blurry. They’re still pretty fun to look at though. I was flying next to the headquarters of Oracle Corporation in Redwood City, California. Those are the clustered cylinder-shaped mirrored buildings you see in the photos. The plane looks like it was a little higher than the tallest building, which I think is 20 stories tall. See if you can find me in some of the photos!Click any of the thumbnails below to see the full-sized version. February 27 Edit: I corrected the focus problem, and tried again. Unfortunately I got the propeller in some of the shots, and this new set wasn’t from as high an altitude. But I did get some great shots of the bay, an aerial self-portrait, and a flock of Canada geese.
Read 2 comments and join the conversationRC Servo Signal Decoder for Camera Shutter Switch
Hey, I’m back. I think my oscilloscope made me do it. For the past six months I’ve been working with RC airplanes, not doing any electronics work. The oscilloscope has been taking up space on my desk while it sits untouched, gathering dust. Last week I finally decided I was never going to use it again, and packed it away in a closet. But that got me to thinking about electronics again, and about what kind of projects I could do related to RC. So after just a few days, the oscilloscope has returned from its closet banishment and is in use once more for a new project.
I recently bought an Aiptek SD 1.3 megapixel camera, with the idea to mount it on the fuselage of one of my planes, and do some aerial photography. The Aiptek weighs just 52 grams (about 2 ounces), and so it won’t weigh down the plane excessively. But the tricky part is finding a way to activate the shutter while the plane is in the air. It turns out that this is mostly a solved problem, and it’s possible to build a circuit to decode the servo signal from an unused receiver channel, creating a 0 or 1 pulse depending on the position of a transmitter switch or stick. Then by hacking into the camera guts and a bit of soldering, that pulse can be used to trigger the shutter.
Here’s one of my planes (a GWS Slow Stick), with three spare wires hooked into the receiver’s “gear” channel (which I don’t normally use), connected to the oscilloscope and a growing circuit on the protoboard. It turns out that these servo signals for the channels are ideal for hacking with digital logic. Of the three wires connected to the receiver, one is ground, one is a regulated +5 volts, and one is a modulated position signal that indicates the desired position for that channel (rudder, elevator, aileron, flaps, gear, whatever). The connectors are even standard 0.1 inch male headers. What could be easier?
I examined the servo signal with the oscilloscope. It’s a regular pulse train with a 22ms period. The width of the pulse varies depending on the desired position for the channel. The width is about 1.2ms at the minimum position, and 2ms at the maximum position. Taking 1.6ms as the midpoint, what’s needed is a circuit that outputs 0 if the pulse width is less than 1.6ms, and 1 if it’s greater than 1.6ms. This could be done many different ways: the first two that come to mind are a small microcontroller, or a low-pass filter that turns the servo signal into a DC voltage, and compares it to a reference voltage.
I’ve decided to follow another example I found, which I thought was especially clever. It uses just two flip-flops and a couple of passive components. You can check out the circuit schematic for the details. The servo signal pulse train is used to clock the first flip-flop. It’s D input is tied high. When it’s clocked, its Q output goes high, which begins to charge an RC circuit. When the capacitor voltage gets high enough, it activates the asynchronous reset, clearing the Q output. The complementary /Q output is used to clock the second flip-flop, whose D input is the servo signal. If the RC time constant is chosen correctly, then the second flip-flop will be clocked 1.6ms after the first one, sampling the servo signal at that time. If the pulse width is less than 1.6ms it will sample a 0, otherwise it will sample a 1. Pretty neat!
My only headache is that I don’t have the 4013 CMOS flip-flop called for in the circuit. I do have lots of 74LS74 flip-flops, which are similar, but are TTL designs with an active low asynchronous reset instead of active high. I’d thought it would be simple to modify the circuit to work with an active low reset, but after a couple of hours of futzing around with it, I concluded that it’s either not possible, or I’m just not smart enough. I started by swapping the positions of the resistor and capacitor, but the circuit initializes in the reset state and never exits it. And even if I found a solution to that, the input current on this LS series chip is so high, that with a 10K resistor to ground, the voltage at the input pin is actually pulled up to 2 volts! Ack! I decided I’ll just buy a 4013 for a few cents, and stop banging my head.
Read 5 comments and join the conversationFail
OK, it’s time to admit defeat. 3D Graphics Thingy is not going to happen. It’s been six months since I worked on it. Heck, I even let my web hosting account expire due to neglect.
So what happened? I ran hard into the memory interface wall. Getting a decent DRAM controller working proved to be far, far more difficult than I’d expected, even with the assistance of Xilinx wizards and prebuilt controller packages. And since getting a working memory interface is a precondition to actually doing any of the 3D stuff, well, that sure put a damper on things.
A second reason for failure is that I found working with FPGAs to be abstract and unsatisfying, and the tool software to be a nightmare. When I built BMOW, I was constantly wiring things, debugging with the oscilloscope, buying new chips, soldering switches, and generally being hands-on. In contrast, 3DGT development ended up being nothing but writing Verilog in a text editor, and wondering why the Xilinx synthesis tools never did what I expected them to. The FPGA hardware itself just sat, untouched.
So what’s next? Since last summer, I haven’t done any electronics work at all, except building a light saber from a string of Christmas lights and a flourescent tube cover. I’ve gotten pretty involved in remote control vehicles, primarily RC planes, which give a few excuses to solder and build simple circuits. I have half an idea to use an Arduino with my Slow Stick somehow, to collect acceleration data in flight, or automate aerial photography or something.
Maybe I’ll come back to the CPU design thing again at some point. I still have a 68008 and some other parts I bought last year that I never got to use, so those are still waiting for me. For all those who contacted me asking if they could build something like BMOW or 3DGT, or asking for advice, send me a note and let me know how your projects are progressing now.
Happy hacking wishes to you all!
Read 8 comments and join the conversation