Wednesday 31 May 2017

Clock design log #3 - time decoders

With the time module built and tested, I need a way to display that time in a more human friendly format, or at least the intermediary step towards that. Interfacing between the binary coded decimal (BCD) values that the time module puts out and the 7 segment displays requires a series of decoders that I covered in one of my very first posts, since what the time module outputs is not directly useable to drive a display - unless I wanted to build a clock that reads in binary.

This is where all of the earlier work with k-maps comes in to play. The decoders are not much more than combinational logic, taking the binary values as inputs, and turning the right outputs on to light up individual segments to produce the required display. There are no counters or SR latches or reset circuits as the decoders are completely stateless.

The time decoder board will have 6 decoders on it, one for each 7 segment display required to show the time in 24 hour format: HH MM SS

One of these decoders, the tens decoder for the hours (left hand most display) is a 2 bit decoder since it only needs to display values 0, 1 and 2. It will still decode a value of 3, because I'll re-use the same design in the day of month decoder when it comes time to build the decoders for the calendar module, but the time module never outputs a value of 3, so that should never appear on the display.

The tens decoders for minutes and seconds are both 3 bit decoders able to show values from 0 to 5, permitting the display of numbers up in to the 50's.

And the units decoders for hours, minutes and seconds are all 4 bit decoders which can show values from 0 to 9.

Put them all together and that gives the decoders the ability to display any combination of hours, minutes and seconds from 00:00:00 through to 23:59:59.

Rev B decoders

During the course of posting on my blog I've been conversing with one particular person on a reasonably regular basis, I believe his name is Matthias. In response to my post about designing 7 segment decoders he posted that he was able to reduce the gate/transistor count of some of them by not decoding digits 6 and 7 for the 3 bit counter. I'd kind of deliberately not bothered to do that, but it did get me thinking that perhaps I should. And having built the time module and realising how complicated and time consuming the construction process can be, reducing the number of gates and transistors is probably a good thing for my sanity. So I decided to use a re-designed version of the 2 and 3 bit decoders to reduce their part count. I was quite happy with the 4 bit decoder design so I havent touched that.

The new k-maps I came up with are available in this spreadsheet, and at the end of the post you'll find a link to revised logicly files and images which I used to verify their operation. These are the final designs I used to build my decoders.

I could have likely made them even more compact if I made them more (what I call) "loose", i.e. some values would match, and would produce some strange looking output on the 7 segment display, but you're not likely to encounter those values due to the preceeding logic in the clock. This can help to simplify some of the minterms, which requires fewer components to implement. But I decided not to do that, opting to strictly decode only the values that I want, and out of range inputs will result in a blank display.

The result of the revision of these two decoders is a reduction in transistor/gate count per the following:

  • 2 bit decoder: originally 18 transistors and 14 gates, now 13 transistors and 10 gates
  • 3 bit decoder: originally 56 transistors and 26 gates, now 35 transistors and 22 gates

Quite a large saving on the 3 bit decoder.

The good stuff

So here are the design files for the time decoders. Usual formats include EAGLE schematic files and a PDF export, plus the logicly designs for the revised decoders.

11 comments:

  1. Thanks for the mention :)

    ReplyDelete
    Replies
    1. No worries. You did put a little fire under my butt to try a little harder. :-)

      Delete
  2. Hm, you should update the README in 7-seg-decoders/, it still says "3 bit decoder for displaying 0-7" rather than "3 bit decoder for displaying 0-5 (with blank display for values 6 and 7)".

    To be honest, I don't see your point in having unused values make the display all blank.
    Should those values ever appear on the inputs (due to some error in the logic feeding it) - then I'd prefer strange (and different) patterns over all blank. Simply because it might help to find the bug.

    This way you could go with just 23 transistors/14 gates for 0-5.
    If you want *easy* debugging then you'd just go for the whole 0-7 range, which is doable with 40 transistors/18 gates.

    Oh, and looking at your 3-bit logicly .png: you can easily omit antoher 3 NOTs there, thus 32 transistors and 19 gates (NOT-NOT at segment e and segments a=d can share the same NOT).

    ReplyDelete
    Replies
    1. I guess its just personal preference. Tom-ay-to tom-ah-to.

      You can, of course, build your own and make it work the way you want and optimise it all the way to the moon, but man its a BIG job ........ :-)

      Personally, I dont think I will build another project of this size using only discrete transistor logic. But it has been a fun exercise none the less!

      Delete
  3. Sure. It's just a very interesting optimization problem in itself, and I love thinking about it :)

    You see, there are different goals to optimize for (objective goals, not personal preference since that just cannot be discussed).

    1) low gate delay, ie. minimize nr of gates any input signal has to go through. This tends to increase the nr of gates, and even more so their fan-in, ie nr of transistors.

    2) low nr of transistors (cost, size). This tends to increase the nr of gates but even more so gate delay, ie adds more layers; thus also affects 4)

    3) low nr of gates. Connected to 2) but not the same. One can often trade this for more transistors. It is good for 4) however.

    4) sheer feasability. That is of course not entirely objective, but hey, looking at the backside of your boards...
    What I mean: fewer layers (of gates) are easier to understand and to synthesize, but tend to increase the nr of connections/transistors.
    On the other hand, one might prefer larger fan-in if that lowers the gate count, since one large gate with lots of inputs is easier - and less error-prone - to build than several gates with the same overall transistor count.

    A 5th might be reusability. Eg you'd decode all 3 bits to 0-7, even if right now you don't need 6 and 7.

    So... I would've appreciated if you'd address some or all of the above in a bit more detail.
    But hey, still an awesome project and blog!

    ReplyDelete
  4. Oh btw: I am actually building stuff. Right now I am working on multiplier circuits. I'm trying to find a sweet spot for a building block, eg. 2x2 bit -> 4 bit, several of which can then be combined to build eg an 8x8 bit -> 16 bit one.

    ReplyDelete
  5. I suppose if anything I have designed my circuits to use the fewest number of gates necessary to achieve the functionality that is required. Whether those gates use more or less transistors is dictated by the circuitry that is required.

    e.g. a D type flip flop which implements a single stage of a ripple counter needs 6 gates and a minimum of 14 transistors no matter what you do, while the decoders are probably the place to make the greatest potential savings.

    If I loosen up the k-maps to match on values that arent likely to ever be seen and if you spend enough time optimising you can lower the gate count quite reasonably.

    The month decoder that I have currently designed I spent quite a lot of time on, to the point that recently I tried re-designing it such that some of the minterms match values 12-15 (in an effort to potentially save some space on the calendar decoder board which is going to be jam packed). Those values are never likely to be seen at the input of the month decoder so I probably dont need to worry about ever seeing funny output on the display. But it seems that I did quite a lot of optimisation of the existing month decoder design that my re-designed decoder actually uses *more* transistors. And my original decoder blanks out values 12-15.

    So could I spend more time to try and optimise the other decoder design? Sure, always, but honestly Im not that worried about it. Im on the home stretch now and I'd just like to get it finished as it has balooned in to quite a massive project really. I want to get part of my life back. :-)

    Like a previous project I worked on last year, you can sit there and tweak and tweak for weeks or months to get things just right and perfect, but you'll never build anything that way. You get to a point where you feel youve done your best and are happy with what youve got, and you decide to commit to that.

    So Im not sure if that answers your questions, but I guess thats my mind set. Ive always said that I dont think my design is 100% optimal, although Ive done my personal best to try and optimise as much as possible, but it *works*, and at the end of the day that is what I am aiming for. :-)

    More thoughts ...

    Picking on #1 for a minute, my decision to use 100K resistors in my gates does have a material impact on switching times for the gates themselves. As I understand the datasheet of the 2N7000, it should be able to switch in as low as 10ns, but you need to supply the gate with 500mA to achieve that kind of speed. At 9 volts and 100K ohms, I give 9uA to the gates of my transistors. Taking measurements with my scope I see switching times from full low to full high of somewhere around 20uS in some cases. If I used lower value resistors I could get switching times much quicker, but then the clock would need a bigger power supply. And since the effective operating speed is 50-60Hz, I dont think making it much quicker would be worth the increased power requirement.

    So maybe that does kind of answer some questions. Just a bit of a brain dump of my thoughts on the subject. :-)

    ReplyDelete
  6. Hey, thanks for this pretty comprehensive answer!

    Of course I see your point of getting things done.
    It was just that I thought I had shown how to *systematically* improve things, at least for the 7-segs. Maybe I should give
    one of the 16-segs a try?

    What you said at the end about the gate delays is a bit of
    a shock for me. 20us is more than an order of magnitude longer than what I had hoped for (well below 1us). What's the trade-off
    like between power consumption and speed? What's it like at 5V?
    It'd be great if you could elaborate a bit more on that.


    Oh, and I got logicly now. It's not as bad as I had thought :)

    ReplyDelete
    Replies
    1. I'll play around with some different resistor values and see what kind of difference it makes in switching times. But as I understand the datasheet for the 2N7000, it can only achieve nanosecond switching times with hundreds of mA of current on the gate. I was also measuring from the earliest point where it looked like the waveform was starting to rise to the latest point where it looked like it had levelled off. Maybe thats not the correct way to measure, and might add significantly more time than reality.

      There are two issues that affect my ability to use higher currents for faster switching, namely to do with the size of the power supply components. The AC wall adapter is only rated to about 5 watts, and the linear regulator can only supply so much current before the heatsink requirements will start to increase too. Ive already had to increase the size of the heatsink a bit as you'll see in my most recent post (due to comparatively massive additional current draw caused by the LED displays), which I thought was a shame because the previous one was nice and compact, but wasnt able to dissipate heat quickly enough. As Im trying to make it as compact as possible with the constraints I already have, adding massive external power supplies or heatsinks wouldnt contribute towards that goal. I have some drop in replacement switchmode regulators that I could have used instead which can do many amps while generating essentially zero heat, but that goes against the ideal of doing everything as discrete as possible. :-)

      Logicly isnt too bad. It does still have some quirks and could be much better (for example, its very sluggish when you zoom out and try to pan around) but it has been a massive help to me in this project. The ability to test out a lot of the sometimes crazy looking logic I have really has helped the build to be as successful as it has been I think. Unfortunately it doesnt provide a faithful simulation, and as a result I have had to make some adjustments to my designs on the fly in the middle of building a board, and that resulted in a lot of head scratching and at times caused some worry about the viability of the design, but it had proved 90% of the logic without fault, and that was significant enough for me to be confident with actually moving forward with the build.

      I did take some of your suggestions on board to help with reducing component count in some of the decoders, e.g. the revised 3 bit decoder where I avoided using two inverters in series, and I also ganged up some outputs which would switch at the same time. I suppose some of my own personal goals, like blanking the display on out of range input, were at odds with your goal of achieving the absolute minimum number of gates even if it resulted in some funny output. Indeed that could have saved much more than I achieved, I suppose I had in my head how I wanted to do it and thats how I did it. :-)

      Delete
  7. Hey Tom :)
    Anything new on scope traces of the switching behaviour? I'd be really interested in such since I don't own a scope.

    You know, it's because I do not think your "D-type Flip-Flop"* is a minimal component for building counters.

    In fact, I managed to get a *synchronous* counter to work reliably using a combination of simple S-R Latches (2 gates, 4 transistors or 5 if you want an async CLEAR or PRESET) plus a combinational, truly edge-triggered input stage in front of that. The S and R signals are each produced by simple n-ary NOR gates. These take as inputs combinations of the various Q/Q' outputs from the S-R Latches plus - each of them - a pulsed ENABLE input (a short low-pulse actually, since we're using NOR logic).

    The key is to produce a suitable low-pulse (common to all n-ary NORs from the input stage). It must be just long enough to make the S-R Latches latch but short enough to not have the newly produced Q/Q' signals get through again.
    So we need to detect an edge (lo or hi or maybe both) in a CLK signal, then produce described low-pulse.

    And you know what - I did it with just NOR gates. Actually built, not just in logic.ly!

    Like so: not(nor(CLK, not(not(not(CLK)))))

    The interesting/strange bit is that the resistor for the binary nor in this must be considerably smaller than your "standard resistor" used in all the other gates (about half, less is better). Actually it seems to depend on the ratio of that resistor to that of the outermost not in the "delay line".
    I cannot really explain why that is, but I guess it's got to with the gate capacitance of the 2N7000. So that's where I'd need a scope...

    Why am I doing all this, where's the advantage?
    Well, in short it a) gives you synchronous rather than ripple counters and - more importantly - allows for an overall reduction of both, gate and transistor count *to about a third*!
    If you want me to I can elaborate on the How and Why of this reduction :)

    ___
    p.s.: * I've put "D-type Flip-Flop" in quotes because as far as I understand it, a Flip-Flop really is edge-triggered, whereas I'd describe your circuit rather as two-stage level-triggered. However, it's definitely an interesting one. In particular I think it's pretty robust. Btw: wouldn't it be nice to explain the rationale behind this circuit?

    ReplyDelete
    Replies
    1. Hey, sorry for the delay.

      Ive just been playing around with different value resistors to see how it affected the switching time and, well, I think this may be more to do with my scope than the transistors themselves but this is what I see:

      When ever I have a 100K resistor at the output, I see a rise time of about 6-7us through a buffer formed of 2 inverters chained together. Thats a 100K resistor at the output of both inverters...

      If I change the output resistor of the last inverter where I am measuring the rise time of the signal to a 1K resistor I can get the rise time down to about 80ns. This is while maintaining a 100K resistor at the output of the first inverter.

      Incidentally, with a 10K resistor at the output of the second inverter I see around 700ns, so that seems to correlate with the decade resistances I was testing with.

      Changing the output of the first inverter to use a 1K resistor as well doesnt seem to affect the result either.

      So, interesting results. I wasnt expecting to see this...

      Delete