Wednesday, May 13, 2020

An MCS-4 Digital Clock

Who needs yet another digital clock? Haven't we all done this before?


I did something like this in PIC-16 assembly language when I first connected my Microchip PICDEM-2 reference board to an LCD in 1999. (Anyone need a UV EPROM eraser?) I did it again in Verilog when I bought this Digilent Spartan-3E Starter board in 2009. But this digital clock is special: it's written in Intel MCS-4 Assembly language, and it's running on my emulation of an Intel 4004 CPU.

In this project I instantiated one i4004 CPU, one i4002 RAM, and one i4001 ROM. The RAM's output ports are connected to the LCD's upper four data pins, and the ROM's I/O ports are connected to the LCD's three control pins.

Aside from this basic plumbing, the Verilog top module generates the required 2-phase clock signals with a 1.4 µs cycle time, or about 714 KHz . This gives an instruction cycle time of 11.2 µs; it will run much faster, but this is compatible with the original i4004 timing. The Verilog also drives a 1 Hz signal on the i4004's "test" input for timekeeping. Everything else is done in the software executed by the i4004 CPU.

The software uses a sizeable subset of the i4004 instruction set. Of the basic group I didn't use the JIN (Jump Indirect) instruction but used all the others. I only needed WMP and WRR from the I/O and RAM group, and DAA from the Accumulator group. It's been a year or two since I've written programs in any assembly language, and I kept the MCS-4 Assembly Language Programming Manual open to look up details. I briefly thought I might have found a bug in the ADD instruction, then found in the documentation that it always adds the carry bit rather than having separate Add and Add-with-carry instructions.

The Digilent S3E Starter board I'm using has a Xilinx XC3S500E Spartan-3E on it, rather than the XC6SLX9 Spartan-6 I'm using in my P170-DH replacement. I found that XST is a lot pickier when building for the Spartan-3E than for the Spartan-6. I had to make several changes to correct reported errors that appear to synthesize properly for the S6; most of these are probably improvements.

Resource utilization was nothing unexpected. Here's some numbers for those who are interested (i.e. me):

Resource Used Available Utilization
Occupied slices 442 4,656 9%
4-input LUTs 614 9,312 6%
  as RAM 32
Slice Registers 340 9,312 3%
  as Flip-Flops 43
  as Latches 297
16 Kbit Block RAMs 1 20 5%


Eventually this design, including the assembly source code, will find its way to my OpenCores project site. The Digilent Spartan-3E Starter board is now retired, but this should run on any FPGA that natively supports latches in hardware and has or can be connected to a 4-bit parallel LCD.

Before I release it, though, I have some enhancements to make. The first ROM was 78% full so I'm adding a second ROM. I also want to use the I/O port on the second ROM to allow setting the time and to allow the clock to run at 60x speed to make it easier to demonstrate things like the hour roll-over from 23 to 00. I may even move the timekeeping counters from scratchpad registers to the i4002 RAM to demonstrate the use of RAM.

No comments:

Post a Comment