Game of Life with CMOS logic

Device description

Main blocks

Schematic

So, system time is counted this way:

0,1,2,…16,
0,1,2,…16,

and then eventually

0,1,2,…16,17…127,128…255

and then

0,1,2,…16.

U21 is configured to count on negative system clock edges. All other system is clocked by positive edges. This way, by the time system clock goes high system time is established for half a clock period.

T7-T0 signals mean something system-wide:

System time summary is in this table: Game of Life timing.

Operation of this block

This schematic worked fine when simulated in LTSpice.  You can run it yourself, here is the LTSpice asc file. You’ll also need to install additional libraries for 74HC and CD4000, which are available in the Files zone of LTSpice yahoo group (registration is needed). Only difference btween simuation and real schematic is that T5 is used to trigger monostable instead of T7 – but it’s only to reduce simulation time.

In reality, I made it work, although I had hard time with half-monostable.

Half-monostable

Using half-monostable to measure long time intervals wasn’t the best design decision. I had problems with running monostable with 10uF capacitor, because U21′s output is just not strong enough to recharge capacitor during T7==1 time. Practical C20 value is under 1uF, which leads to several hundred kOhm resistors. In my case it was 235kOhm, and it gave about 3steps per second.

I also could not find suitable variable resistor to adjust time (it would be 470k or so), so I’ve shorted it out.

Having no threshold in U20.4 lead to a lot of oscillations when voltage on it’s input crosses the half of supply. It leads to heavy timing problems. Timing given by this monostable is also very imprecise.

I ended up with an additional board with 555 timer, which worked fairly well. Files: 555 diptrace source555 schematic.pdf. This schematic also allows to change game step time with common 10k variable resistor.

555 monostable schematicAdding 555 as monostable

RC oscillator

This oscillator worked more or less fine, although with jitter visible on oscilloscope. I noticed that it changes frequency when I move my hand closer to the circuit, by up to 2-3 kHz. Not that it is so critical for this design, but in next design I’d probably use 32768Hz quartz oscillator for system clock.

Matrix and Display blocks

Matrix is made of eight 74HC595 SIPO registers.
The Matrix - Game of Life
Their parallel outputs form row data bus C7-C0 (‘C’ stands for ‘column’). U9 (74HC138), demultiplexer with active-low output, enables output of only one register at a time depending on T2-T0.

Registers are also connected in series, input of row 0 (U1) being connected to system-wide SDI line, output of row 7 (U7) – to SDO line.

Data from serial part of ’595 to the parallel part is latched on the falling edge of T7, after whole matrix update is finished. This is very important feature for game of life logic, because generally, until all new data is not loaded into the matrix, data from the previous turn should persist.

Display block is very simple. Foryard ultra-green 8×8 LED matrix with common anode is used. Columns are driven directly with ’595 outputs – their 4mA rated output is enough to drive LED matrix with comfortable brightness. Rows are driven with PNP pull-up transistors.

Display - Game of Life

Both matrix and display worked fine when soldered – there’s just nothing to break. Only pinout of the matrix I bought differs from that in the schematic – I had to make different wiring.

Game of Life logic block

This is probably the main block in the device. Let’s see how it works.
Next Alive logic - Game of Life Operation of this block is done in 8 stages, each completed in two phases. Each stage processes one row of cells and serially loads next step cell values into the matrix. Stage number is T6-T4.

First phase completes in 8 cycles, when T3 is 0. During this phase, data of every row in a matrix appears on C7-C0 bus (selected by T2-T0 lines of time bus).

Registers U16, U17, U18 (HCF4021) latch data of adjacent rows:

U13, U14, U15 select which row to latch – those are demultiplexers with 3-state outputs. Time lines T6-T4 tell those multiplexers which stage is currently running and demultiplexer connects it’s output to one of R7-R0 row selects. When right data to be latched is on the C7-C0 data bus, corresponding Rx signal appears on the inverting output and is latched into the register by the pulse on P/S input. To make pulse on P/S input more precise, it is only active during first half of system clock cycle.

Second phase is completed when T3==1. During this stage P/S inputs of U16-U18 is held low and they operate in serial mode. Serial input of those registers is connected to Q8 output to make data rotate in the registers when clock is applied. And it ticks 8 times during second phase, sequentially showing all 8 updated cells and their neighbours during second stage. As you can see, there are only 3 outputs on these magic registers – perfect for our game of life application.

In the second phase cell state and neighbor states for 8 cells in a row sequentially show up on U16-U18 Q6-Q8 outputs.

Because first data to be loaded into the matrix should be (C7,R7) data, during the first stage (T6..T4==0), row 7 is fetched as the current row, row 6 as previous row, and row 0 as the next row (remember, we create torus topology).

Because we have only Q6,Q7,Q8 outputs, and not Q0,Q7,Q8, data is latched into U16-U18 pre-rotated, so that when the first cell is updated, Q6,Q7,Q8 show state of C6,C7,C0. Which row is latched when is summed in this table: data-selector-truth-table.xls.

Quite easy schematic allows us to determine next cell state:

Two problems popped out when debugging this block.

Otherwise, this block operates quite well.

States block

This block controls operation of the whole system. It is operated by four buttons, implementing finite state machine (FSM) with 6 states.

Game of Life State Diagram
For simplicity, each state is designated by four bits corresponding to distinct actions: Edit, Random, Read, Write, which are outputs of U21.

Random state is split into 2 states, but to detect that random pattern should be inserted, only Random bit needs to be polled.

U21 is a clocked quad D-type latch with normal and inverting outputs, providing a lot of usefu signal which other system blocks may use. Data on U21′s inputs are latched on positive edge of T7. Each next state is defined by previous state, keys pressed and AllOnesDet input from the control block. As all bits of U21 have specific meaning, creating FSM is very easy.

Let’s write down the rules for state transition:

Edit bit: D3 = Q3 ^ (Edit/Run button)

Random bit: D4 = (!Q4 & !Q3 & AllOnesDet) | (!Q4 & Q3 & (Random button))

Read bit: D1 = Q3 & (Read button) & !(Write button)

Write bit: D2 = Q3 & (Write button) & !(Read button)

Read and Write buttons are made mutually exclusive, otherwise Flash access conflict may happen. User may press Random button simultaneously with Read or Write button, but it is not a problem – Random and Read/Write operations are not in conflict.

Some simulations in LTSpice IV for this state machine.

Button presses are debounced with U20 quad R-S latch. It is a clocked debouncer with a rate equal to game rate: when button is pressed, it’s press is remembered until T7 goes high.

Edit block

This block takes data from SDI, knowing how it’s clocked, and outputs it to Edit net. It can invert, edit or randomize data bits as they pass.

Let’s look how data is edited. There are 8 push-buttons for rows and 8 push-buttons for columns. To edit data, user presses one or more column buttons and one or more row buttons. All cells on laying on the crossing of selected rows and columns are toggled once per game step.

Here’s the schematic.

Edit - Game of Life
It is known (or, forethought) that serial clock coming to the Matrix in Edit mode is gated so that it is only active when T3=1. Bits T2-T0 designate column of current bit, and bits T6-T4 designate row. Column bits select one of the inputs of U13 multiplexer, and row bits select U14 multiplexer inputs. Common pin of U13 is connected to VCC, common pin of U14 is pulled to the ground with resistor. When multiplexers select row and column where both buttons are pressed, current flows through resistor and logic one comes to U9.3 XOR gate, making it invert data coming from the Matrix.

Additional clear button changes all bits to 1′s when pressed.

Flash block

Flash block operates AT45DB011D SPI flash, and can operate any flash chip from AT45DB family. This flash was chosen because it’s write operation can be implemented very easy, comparing to other flash memories.

Data is written with the following sequence:

Read is even more complex:

Atmel flash has very small page size (256-512 bytes), and all pages can be written independently, without erasing anything in advance. In this device, one matrix image is written per flash page, starting with address 0, utilizing AT45DB’s fine internal page write and small page size.

Let’s see how write in implemented:

Read is implemented nearly the same:

Flash read/write cycles are summed in this table: gol-flash-working-mode.xls

Address is 8-bit and it is selected with a DIP-switch. Initially, I’ve designed electronic address selector with 2 buttons and two 7-segment LED indicators, but then threw them out of the project not to complicate things. This schematic is here.

It seems that accompanying logic is not completely right in current schematic, so I will recheck it in the next revision.

I did not solder flash block because other blocks worked not very good.

Control block

This block interconnects serial signals from matrix, flash, random generator and editing block. It does little more than that.
Control - Game of Life
It has the following clock inputs:

And it has following data inputs:

Of all these inputs control block generates SDI and SCK signal for the Matrix. You can see whan clock and data is generated in different modes of operation in this table gol-game-working-mode.xls.

Current implementation of control block is buggy. It generates SCK when T7==0, when no update should be done, effectively pushing away valuable data from the Matrix.

Another block on this page detects when all ones were clocked into the matrix during T7==1 state. It is created with two D-triggers (U24). All ones correspond to all dead cells, so it’s nice to detect this state. You can see how this schematic simulates in LTSpice IV here gol-allones-ltspice.xls.

First trigger is set to one when T7 is 0. When T7 is one, data for this trigger is set as it’s previous state logically AND’ed with next data. Upon the falling edge of T7 this information is lathed in the second register. If any 0 was clocked with SCK (alive cell), AllOnesDet will become zero for the next game period.

Random generator

This is a hardware random generator:
Random - Game of Life
It’s idea is flowing in the Internet, but I didn’t solder it and do not know yet if it will work.

I’ve also placed DIP-switch address selector here.

Conclusion

Even not having success with making it running, it was a great experience. I’ve carried out a lot of knowledge. Not only I’ve better understanding of how logic chips work, but I’ve learned the hard way how good PCB and good flux could make my life a lot easier.

I read “CMOS cookbook” by Don Lancaster, which was really great reading, no matter it’s 25+ years old.

I’ve learned to never use half-monostables described in “CMOS cookbook” again. At least, never use them to generate long delays and also to use it with extra caution with a clocked logic. I’d better go for 555 timer, or make a delay with long counters.

I also learned things about PCB fabrication. My project is 2 PCB’s with about 500 pins each, which is more than I’ve done before. Some chips were not available in DIP packages, so I went for SOIC. I should have stayed with DIP where available to make my life easier!

I carefully placed components and then let autorouter to make a layout. I have had selected 0.2 mm traces with 0.2 mm spacing between traces – it’s my board manufacturer’s standard rules. I wanted to make a board with solder mask, but in the end I understood that my mask won’t pass manufacturer’s DRC. So I made boards without mask. It was a great mistake! Debugging this board in really… er… debugging. Any small piece of solder ends in between two traces and creates a short strong enough to make circuit misbehave, but weak enough to find it with a tester.

And last, I will buy good and expensive flux now. I will never use that Chinese “Soldering paste” again. It looks like flux, but it is only good to solder copper cookware. I’ve never notice this before, but a bit of this flux in 0.2 mm gap between traces will create you less than 100k resistance between them. You can never delete this flux from under the chip and without solder mask it was the main disaster for my two boards. In the end I desoldered chips one after another, removed residual flux and soldered them back again – and it basically started working.

Anyway, I’m going to make version 2 and make it really rock!

bd9703 step-down converter

This entry is about power supply based on ROHM Semiconductor’s bd9703 step-down converter.

My experience with this IC started with a failure. First time I tried using this converter resulted in the whole PCB being dead. Shortly after applying power, the power supply started screaming and whistling, as I discovered later – due to horrendous layout, and in some quarter an hour killed most other IC’s on PCB. Such a fail made me dig into the design and layout of this buck converter and make a PCB suitable for evaluating power supplies based on all IC’s in the family: bd9701-bd9703. Finally, I’ve found good layout which I’m planning to use now in all my projects.

The bd9703 is a fully integrated step-down (or buck) converter, similar to lots of other chips present on the market.

It’s main parameters:

Input and output voltages, as well as output current of this chip makes a good replacement for industry standard LM317 series of linear step-down converters, with a benefit of dissipating far less heat (it is switching, not linear). Besides, bd9703 is available in industrial temperature range.

This chip has also two sisters: bd9701 (100 kHz switching frequency) and bd9702 (current up to 3A). Evaluation board described here will suit all those chips, but you’ll have to adjust component values – this is as usual.

Why this chip? It is very popular, used in a plethora of DVD-players, and it makes it available on stock of many component suppliers, even in Russia. Price is also attractive: I’ve bought bd9703 in TO220FP-5 case for $0.78 retail price. But it was before 2011′ Japan earthquake, and now availability may be less and price may be higher – ROHM is Japan company.

Despite popularity and low price tag, one will unlikely find any reasonable documentation for bd9703. There is only a manufacturer’s datasheet, quite messy and incomplete. For example, there are no recommendations on choke and capacitor selection, they give only several criptyc examples. There were also no application notes on the Internet.

Well, you have no docs – will cheat against you. Application schematic is similar to Linear’s famous LT1070 and Simple Switcher series of National Semiconductor (for example, LM2575, LM2586):

Compare it to LM2575 application:

Last year I’ve read through the AN-19 “LT1070 Design Manual” provided by Linear Technology, which describes in great detail the design and calculation of step-down converter – a must-read for everyone. Math is easy to understand, but I was too lazy to compute myself. That’s why I went to National’s website, found similar converter from their portfolio and used their great online tool to calculate choke and capacitor values. Thanks, National Semiconductor! In the end, all step-down converters rely on the same principle and choke, output cap values are calculated with the same formulas.

First version

After initial disaster, I’ve drafted this schematic:

bd9703 evaluation schematic v1

Comments:

Next step was to find good layout. It is very important for a good SMPS layout to trace power and feedback separately.

In this specific case, we have two high-current loops: input loop (C1+C4 – U1.VCC – U1.GND) and output loop (D2 – L1 – C3 – GND, plus U1 to L1 and D2 connection). High-current loops should be made as short as possible. Small-signal nets should be laid out so that high-current nets do not influence them.

Proper ground connection and ground separation is even more important. GND pin of bd9703 is used as both power return (for input and output currents) and signal ground (reference point for feedback). It would be a great mistake to just connect this pin to a ground layer and then connect to this layer all other grounded componets. Current from input and output capacitors to the GND pin will flow through the ground plane in an uncontrollable manner, creating rather unpredictable voltage drop. Ground plane will then have different potentials in different places, and these potentials will depend on the current flow through the high-current loops. Suppose, for example, that grounded pin of R2 will have potential higher than converter’s GND – this will certainly break voltage feedback. Consider also that this voltage will be modulated with the switching current – this will probably introduce positive feedback and unneeded oscillations.

This is my first layout attempt:

Three different traces are connected to the GND(3) pin – one from input loop, another one from the output loop and finally one for feedback loop – this is the small-signal one. The U1-D2-L1-L2-C3-C5 loop is length- and area-minimized. Feedback loop is placed aside from poer loops. Only one net is wierd due to D10 protection diode.

I made this PCB with toner-transfer method, assembled and tested.

Input voltage was 24V, output was 3.3V. I tested with 15 Ohm load and without load. Basically, it works and voltage is fairly constant.

But looking with an ocilloscope I could see big spikes on the output. They appeared with the switching frequency. After an hour of fiddling with capacitors and inductor I finally understtod that it is D10 that breaks everything. Each time the embedded MOSFET of bd9703 closes, current from C1-C2-C4 flows through this diode, and this has several drawbacks:

It happens that this diode stands on the way of switching current and disturbs normal energy transfter from input capacitance to L1-L2. Well, I understand that it is not the description of the underlying physics, but right after I have shorted D10, wierd spikes disappeared from the output. Only normal ripple voltage remained. I have added one more ceramic capacitor in parallel to C4 (same value) and output voltage became even cleaner.

It is clear that low impedance of input capacitors is essential for proper SMPS operation. Ceramic capacitors improve impedance of this group on high frequencies, that’s why they improve converter operation. D10 diode made the opposite – it introduced delay, effectively cutting high frequency response.

Second version

I disassembled v1 after tests and made the second PCB. Here is the schematic:

bd9703 evaluation schematic v2

D10 is removed, and there are 2 ceramic caps on input. Layout looks more elegant:

This PCB is approximately 25×40 mm.

Assembled and tested in the same conditions:

This time everything works great, spikes are gone. I did not measure efficiency, but the converter is cool without heatsink. By the way – this package is entirely plastic, which makes heatsink attachment very easy – you do not need isolate the chip from heatsink.

Third version

After testing the second version, third, more elegant, layout came to my mind (schematic is the same):

But I am lazy already to assemble and test this layout. It looks like everything will work well. If you assemble it – drop me a note.

UPD:  Schematic and PCB for versions 2 and 3 in Diptrace format are here:  ev_bd9703_sch_pcb.zip.

May the Power be with you!

About me and my blog