After seeing this fascinating blog post from Ken Shirriff about restoring a Xerox Alto computer, I realized much to my surprise, that my homebrew CPU project was, more or less, identical to the internal architecture of the Alto. This doesn't mean I'm some kind of super genius on par with the PARC elite, but rather that by limiting myself to 7400-series logic as the basis for my CPU, and by deciding to use a 16-bit data/memory bus, that ultimately the most practical design was one centered around the 74181 ALU.
After reading about how the Alto is designed, I think I'm going to use it for further inspiration for how to design my own CPU.
As you can see from the dearth of posts to my blog, however, development has basically stalled indefinitely. I'm hoping to start over yet again, this time by designing the whole CPU in Verilog/VHDL and uploading it to an FPGA. That way I can validate the design and have a much better way to test and validate each component of the system: by interfacing my own boards with the FPGA core, I can confirm that the physical components behave identically to the verified and correct design as implemented in software. One by one, I can reimplement the FPGA core's functional units in hardware, and eventually discard the FPGA all together.
This approach could end up being a bit more fun as well, since it means I can start by implementing some I/O devices, without having to have the whole CPU up and running first. That way I can write some sample software for the CPU, to make sure I've got sufficient functionality built into the design. Then when I actually do build the physical boards, I'll know that I'm not missing some critical functionality that will be difficult or impossible to hack in later.
Saturday, July 2, 2016
Saturday, October 20, 2012
BusBoard backplane
I went ahead and purchased a couple pieces of BusBoard (from Amazon; free shipping since I have Prime!) and a pile of DIN-41612 VME-style connectors. The connectors have three rows of 32 pins, but due to the BusBoard design, two of the rows are bound to the same bus. Thus the net is 64 wires on the bus. I got the DIN-41612 connectors from Phoenix Enterprises.
Here's what the finished backplane looks like:
There are 7 ports on top for component cards. I also put right-angle male and female connectors on either side so I could daisy-chain backplanes together if needed for more component boards.
I will likely use a setup like this so that I can have the board I'm currently "interested" in be presented face-up instead of stuffed sideways. For example, my first component card will be power, clock and control, and will likely live in this position for a while. In the future, when there are, perhaps, I/O devices like an LCD or keypad, I can chain boards together like this to make a nice tidy system.
When cards are installed vertically, they'll look like this. There's plenty of space between boards for any oversize components.
Here's a close-up of the BusBoard traces. It's really well thought-out: one side of the bus is denoted with the "skinny" traces, while the other side is noted with the "thick" traces. Thus it's simple to position components on the board to ensure you're connecting to the right pins on the bus.
Of course, the bus traces run the entire length of the board, so I'll need to invest in a battery-powered dremel tool or something so I can selectively break traces. I can also stack a non-bussed protoboard over the BusBoard and connect them with standard DIN connectors if I end up in a situation where cutting traces is too much development effort.
Here's what the finished backplane looks like:
There are 7 ports on top for component cards. I also put right-angle male and female connectors on either side so I could daisy-chain backplanes together if needed for more component boards.
I will likely use a setup like this so that I can have the board I'm currently "interested" in be presented face-up instead of stuffed sideways. For example, my first component card will be power, clock and control, and will likely live in this position for a while. In the future, when there are, perhaps, I/O devices like an LCD or keypad, I can chain boards together like this to make a nice tidy system.
When cards are installed vertically, they'll look like this. There's plenty of space between boards for any oversize components.
Here's a close-up of the BusBoard traces. It's really well thought-out: one side of the bus is denoted with the "skinny" traces, while the other side is noted with the "thick" traces. Thus it's simple to position components on the board to ensure you're connecting to the right pins on the bus.
Of course, the bus traces run the entire length of the board, so I'll need to invest in a battery-powered dremel tool or something so I can selectively break traces. I can also stack a non-bussed protoboard over the BusBoard and connect them with standard DIN connectors if I end up in a situation where cutting traces is too much development effort.
Sunday, October 14, 2012
Reboot!
Hi, folks. Been a while since I've posed anything here. As you can imagine based on my lack of updates, I haven't been giving this project much attention. So this weekend, I gave it some thought: "why am I not working on this project more?"
The answer was that while I have the design for everything ready to go, the sheer quantity of labor in soldering everything together was turning me off in favor of other avocations.
So how does one avoid having to do so much soldering, without giving up the project goal of using 7400-series logic? After some searching, I came across BusBoard: http://www.busboard.us/pdfs/BPS-MAR-BB3U-001.pdf This stuff is awesome -- it provides a set of zig-zag traces that make connecting DIN-style connectors to other components WAY easier. And the boards are compatible with DIN-41512 VME-style backplane connectors.
So I've decided to reboot the project, based on these boards. I'll first build a backplane with 7x DIN-41512 female connectors on top, a male right angle connector on the right, and a female right angle connector on the left. That way I'll be able to daisy-chain the backplanes together to add more cards if I need them. Each card will have a right-angle male connector on the end that mates with the backplane.
This arrangement gives me a 64-wire bus, which reduces the amount of point-to-point soldering substantially, and should also improve reliability and the looks of the finished product.
Since I'll be starting fresh with a new backplane design, this also gave me an opportunity to revisit my architecture and tweak it a bit. I've made the following changes:
Here's the updated architecture:
The answer was that while I have the design for everything ready to go, the sheer quantity of labor in soldering everything together was turning me off in favor of other avocations.
So how does one avoid having to do so much soldering, without giving up the project goal of using 7400-series logic? After some searching, I came across BusBoard: http://www.busboard.us/pdfs/BPS-MAR-BB3U-001.pdf This stuff is awesome -- it provides a set of zig-zag traces that make connecting DIN-style connectors to other components WAY easier. And the boards are compatible with DIN-41512 VME-style backplane connectors.
So I've decided to reboot the project, based on these boards. I'll first build a backplane with 7x DIN-41512 female connectors on top, a male right angle connector on the right, and a female right angle connector on the left. That way I'll be able to daisy-chain the backplanes together to add more cards if I need them. Each card will have a right-angle male connector on the end that mates with the backplane.
This arrangement gives me a 64-wire bus, which reduces the amount of point-to-point soldering substantially, and should also improve reliability and the looks of the finished product.
Since I'll be starting fresh with a new backplane design, this also gave me an opportunity to revisit my architecture and tweak it a bit. I've made the following changes:
- Fixed 24-bit instruction format:
- 5 bit instruction opcode
- 2 bit "A" register address
- 2 bit "B" register address
- 15 bit data field
- Instruction opcodes no longer directly map to control signals on component boards. Instead, I'll use EEPROMs or (cough) a microcontroller on each board to issue control signals. Since instructions are only 5 bits, I can use a simple 512 byte (256x16) EEPROM and generate up to 16 control signals on each card. If I go the microcontroller route, I can use cheapo MSP430s: 8 GPIO pins; 5 input (opcode), 3 output (shift register for arbitrary number of control signals). The EEPROM would be best, but availability may be slim for such small ones.
- The old architecture required a "C" register bus, which has been removed; ALU instructions will write back to register A (A [op] B => A)
- I've added a couple interrupt lines to the architecture, since I have a feeling that it'll get annoying really fast to have to poll for things like keyboard input. Having the ability to have a hardware module interrupt the CPU and run one of two service routines would be very helpful.
- The new design will be based exclusively on 74HC series chips; I made the mistake of mixing 74LS, 74HC, and 74HCT parts in various places in my current boards, which I believe contributed to a very poor reliability.
Here's the updated architecture:
- Harvard architecture system with 64k (16 bits) instructions and 64kbyte (15 bits addr. x 16 bit words) RAM
- 16-bit data words, little-endian
- 24-bit instructions
- 23-19: opcode
- 18-17: register A select
- 16-15: register B select
- 14-0: 15 bits of data
- Single-cycle design; falling clock signal triggers a new instruction on the bus; rising clock signal commits data to memory and registers
- 64-wire bus:
- 0-15: register A data
- 16-31: register B data
- 32-55: 24 bit instruction
- 56: register A write/!read
- 57: register B write/!read
- 58: CLK
- 59: !RST
- 60: INT0
- 61: INT1
- 62: +3.3V
- 63: GND
- Instructions (more will be added later when I/O devices begin to appear)
- NOP
- LD RAM@[data] into A
- LDR RAM@[B] into A
- MOV A into B
- MOVD [data] into B
- ST [data] into RAM@[B]
- STR A into RAM@[B]
- STD A into RAM@[data]
- ALU A [op] B into A (ALU opcode in [data] field)
- SR shift A right one bit
- SL shift A left one bit
- JMP jump to [data]
- JMPR jump to [A]
- JMPZ jump to [data] if [B] == 0
- JMPRZ jump to [A] if [B] == 0
- JMPNZ jump to [data] if [B] != 0
- JMPRNZ jump to [A] if [B] != 0
The trick now is to start rebuilding the various components. To that end, I've gone ahead and ordered some busboards and DIN-41512 connectors. I'll get the backplane put together and tested, then build a new clock/control unit, which will be driven by a microcontroller -- this will give me WAY more control over the clock and reset signals without having to fiddle with DIP switches. I will also be able to display the clock speed on a 7-segment display right on the clock unit. I'll then rebuild the instruction counter, and probably pony up for some ZIF sockets for the EEPROMs that contain the machine code. After that, it should be much more simple to build boards that implement different instructions (and serve as the register file and RAM), since the bulk of the soldering will be avoidable with careful placement of the components on each board to intercept the various buses.
I'll of course keep the blog up to date as I make progress...
Saturday, November 12, 2011
Shift/Jump control board finished!
After a long hiatus, I finally got the last bits of wiring finished on the Shift/Jump unit control board. I haven't actually powered it up yet to see if it works (even if I did, I wouldn't know for sure, since I still don't have a reasonable way to get a signal onto the A/B buses). But at least it's all wired up and ready for the (comparatively simple) transfer boards, which move a 16-bit signal from one bus to another.
Front of the control board |
Yay point-to-point wiring! |
Installed in the Shift/Jump unit backplane |
Monday, September 26, 2011
Nice guide to 74LS vs 74HC vs 74HCT
I've been tinkering recently with my Launchpad, with the goal of developing a 32-bit I/O expander that I can use to simulate traffic on my CPU's buses without having to run an actual program. This will allow me to debug individual modules without having to wire up the entire system, upload test software into the EEPROMs, and trace the signals across a half dozen boards.
Along the way I've had to start taking a hard look at signal voltages for various stuff, because the TI MSP430 is a 3.6V part, and I need to drive my 5V TTL and CMOS logic with it. This requires some logic level conversion, and as it turns out, some deeper knowledge about the differences in the chips I'm plugging into my breadboard.
I was under the mistaken impression that 74LS (TTL) logic was effectively identical to 74HC (CMOS) logic except for maximum frequency capability. Turns out I was way off, and in fact you cannot mix these components in a system without performing logic level conversions. I also thought that the 74LS series was the "most preferred" for new projects; but it looks like I'm wrong there too -- the 74HC series is the "best" these days.
I found this very helpful link that describes the differences in the series and notes the interoperability of them. It also has a really nice breakdown of the basic 74 series chips, their pinouts, and how to do basic daisy-chaining of things like counters. An excellent page to have bookmarked so that you're not constantly digging up datasheets just to see what the pinout is for a chip...
http://www.kpsec.freeuk.com/components/74series.htm
Along the way I've had to start taking a hard look at signal voltages for various stuff, because the TI MSP430 is a 3.6V part, and I need to drive my 5V TTL and CMOS logic with it. This requires some logic level conversion, and as it turns out, some deeper knowledge about the differences in the chips I'm plugging into my breadboard.
I was under the mistaken impression that 74LS (TTL) logic was effectively identical to 74HC (CMOS) logic except for maximum frequency capability. Turns out I was way off, and in fact you cannot mix these components in a system without performing logic level conversions. I also thought that the 74LS series was the "most preferred" for new projects; but it looks like I'm wrong there too -- the 74HC series is the "best" these days.
I found this very helpful link that describes the differences in the series and notes the interoperability of them. It also has a really nice breakdown of the basic 74 series chips, their pinouts, and how to do basic daisy-chaining of things like counters. An excellent page to have bookmarked so that you're not constantly digging up datasheets just to see what the pinout is for a chip...
http://www.kpsec.freeuk.com/components/74series.htm
Tuesday, August 2, 2011
Launchpad!
Hey! Believe it or not, I'm still here, and still working on this project. Just not a whole lot of spare time these days :-)
This weekend I purchased something that I swore in my first post that I wouldn't -- a microcontroller. I got myself a TI Launchpad development board. It was only $4.30 with free shipping. How could I pass that up?!
But don't fret -- I'm not planning to use it to take the easy route on any parts of the CPU. I will, however, be using it to simulate certain components (primarily the register file) while I work on the other CPU components. I'm finding that it's quite difficult to properly test the various units when I don't actually have registers with which to put data on the bus...
Once the Launchpad comes in I'll get familiarized with the interface, write a few "hello world" programs for the MSP430 and then get crackin' on the register file simulator...
This weekend I purchased something that I swore in my first post that I wouldn't -- a microcontroller. I got myself a TI Launchpad development board. It was only $4.30 with free shipping. How could I pass that up?!
But don't fret -- I'm not planning to use it to take the easy route on any parts of the CPU. I will, however, be using it to simulate certain components (primarily the register file) while I work on the other CPU components. I'm finding that it's quite difficult to properly test the various units when I don't actually have registers with which to put data on the bus...
Once the Launchpad comes in I'll get familiarized with the interface, write a few "hello world" programs for the MSP430 and then get crackin' on the register file simulator...
Sunday, May 8, 2011
Xprotolab
I recently took delivery of a Gabotronics Xprotolab device. For less than $50 I now have a fully functional 2-channel oscilloscope, 8-channel logic analyzer, arbitrary waveform generator, frequency counter, and spectrum analyzer, all in a tiny matchbox-sized little package. Very very cool.
Here's the device as it was shipped to me:
One of the reasons I wanted an oscilloscope was to investigate why my control board doesn't seem to function properly at 32kHz but does fine at 16kHz. So I wired it up to my control board:
Here's the device as it was shipped to me:
Out of the box |
Sitting on keyboard for scale |
I have channel one hooked to the output clock that goes to the other boards, and channel two hooked to the output of the inverter where the clock signal comes right off the crystal.
What I found was interesting. Here are the signals while in 16kHz mode:
CH1 (top): 16kHz output clock CH2 (bottom): 32kHz input clock |
Notice that the 32kHz signal coming from the crystal/inverter is nice and square, with equal time spent at high and low. Then I switch into 32kHz mode (which causes the output from the clock to skip the ripple counter and simply feed directly into the output buffers:
CH1 (top): 32kHz output clock CH2 (bottom) 32kHz input clock |
Yikes! The resulting clock (top signal) is heavily skewed toward high, with barely any time at all spent at low. The input clock clearly shows why: what was once a neat square wave has turned into a badly squished sine wave. I suspect this is due to excessive current draw out of the inverter circuit. Since I'm using a basic clock circuit using a crystal, two capacitors, and an inverter, the current sink into the output stage of the inverter can have very dramatic effects on how the resulting signal looks.
Since in 32kHz mode the output is going through a different (presumably higher draw and/or capacitance) path, the crystal is not able to generate the even periodic pulses that it's supposed to.
While it's unlikely that I'm going to rework my control board just to fix this one issue, it was very interesting being able to finally see down into the actual signals being generated, instead of having to infer this behavior from traces on the logic analyzer.
Subscribe to:
Posts (Atom)