Showing posts with label logicly. Show all posts
Showing posts with label logicly. Show all posts

Sunday, 29 October 2017

Clock project debrief

And this is really it, after a bit of a break!

I hope this has been an interesting journey to follow along, and with this post I want to give a "debrief" on the project - what worked and went well, what didn't work or didn't go so well, things like that.

Concept

The concept was certainly interesting - build a clock (not too interesting in and of itself), but build it out of a single type of logic, and build it using discrete components. It seemed like a big task when I initially set out to do it, and I guess my hunch was right. I just didn't realise how big it would end up being.

The goal was first and foremost a working clock. A secondary goal was to create something of interest, or certainly something attention grabbing. I think it will be - in the right company anyway. Some people will probably think I was just crazy. So far, those who have seen it in person are suitably impressed.

Functionality wise it has everything that I need and want. I guess thats the advantage of designing and building something yourself. But there were also technical constraints to consider, like the number of transistors I could fit per board which would also limit the amount of functionality I could have. In the end I'm quite pleased that I managed to fit everything I wanted in, and managed to keep each functional block contained on a single board.

Design

It might just be a case of Stockholm syndrome, but I've quite enjoyed the simplicity of building everything using NOR logic. In a way it is kind of strange to imagine building anything any other way now. Being a universal gate, you can form any kind of logic you need with the right combination of NOR gates. But certainly, for a large scale project, utilising all of the available types of logic would probably result in a more compact design. For example, a two input AND gate implemented with NOR requires 3 gates - 2 to invert the inputs, and 1 for the output - at a minimum that is 2 transistors per input to the "AND" gate. An AND gate implemented directly only requires 1 transistor per input. But the goal of this project was to only use NOR, so that is beside the point.

In the very early stages of the project I had some ideas about how I would make this all fit together, and I think some of those ideas very rightly were replaced with others. One such iteration involved running a lot of wires between the boards as I hadn't yet figured out how I would use headers and sockets to link all of the boards together. Luckily I would find the right parts to allow me to avoid having to use that "wired" method, and I feel better off for it - taking it apart is certainly MUCH easier, and the clock is nice and tidy and well contained as a result.

CAD tools

Logicly, as I discovered early on in the process, did prove to be a very valuable tool. It helped me to prototype logic very quickly to develop and debunk ideas, and to hone in specific design details. It wasn't free in the end as I ran out of the free trial period, but it was worth it. It does have a few performance issues when you scroll out far enough, but if you want to play around with logic for learning purposes it't certainly a good tool to have. If you just need an ability to test something and don't need to keep it afterwards, the trial web interface certainly does a good job. I'll continue to use it to test out ideas in the future.

EAGLE is a PCB CAD tool that I have been using for some years now. It can be had for free with some limitations around useable board area, but schematics can still hold a significant amount of circuitry (limited to two sheets in the free version). For my needs, EAGLE worked just fine, although if I weren't stuck with the free version right now I might have been able to release a single schematic file instead of one per board. I'm in two minds about how to handle the new subscription model now that Autodesk has taken it over. On one hand it looks nice and flexible - pay for what you need for as long as you need it - on the other hand I kind of feel I would just prefer to pay once and get it over and done with...

Physical tools

The tools you have to work with make an untold contribution to your productivity and ability to actually do what it is you are trying to do. I am certainly over the "buy cheap tools just to get the job done" phase of my life, and I am starting to "invest" in better quality tools, and more specialised tools for particular jobs. One tool I want to call out specifically which helped to no end was a wire stripping tool:


Now, this wasnt an expensive tool at all (counter to the theme), but along side a two pairs of Knipex side cutters (one with the lead catcher and one without) and a soldering iron, this tool completed the essential trio. It is adjustable, and once dialled in just right, stripping the Kynar insulation of the wire I used was so much easier. Without this tool I'd have been doomed to using something like a knife, or my side cutters to try and strip the insulation, and I don't want to think how much extra effort this would have created. Perhaps rather ironically, this particular tool worked a lot better than the original wire stripping tool I used which was almost 3 times the price...

Acquiring an oscilloscope is also worthy of a mention. Without it, I would have had a very hard time seeing just what was going on with some signals, and and even harder time figuring out how to go about correcting some things. In the tradition of buying quality tools, I ended up buying a Keysight MSOX2024A. It was plenty more expensive than a Rigol for example, especially for a first-time scope owner, but I am loving every minute working with this thing. I bought it from Keysight's "premium used" store via ebay, and that ended up costing me about 50% retail of a new unit. In fact, it was even cheaper than a brand new 70MHz unit that I was originally looking at. It even came with 5 years of Keysight warranty, so I think in-all thats a big win.

During the project my original soldering iron died - to quote Photonicinduction: it popped (quite literally). To replace that I, once again, "splashed out" and bought a Hakko FX-888D. The difference using this iron over my previous one is incredible. The iron itself is so light that you barely even notice that you're using it, and came with a really nice holder that has a wet sponge and a brass sponge, although these days I tend to only use a brass sponge which does a much better job I think. Also much more conveniently, the transformer unit can sit closer to the iron itself, so I gained some freedom of movement with the iron through a bit of additional cable length. As a bonus, it is also an ESD safe iron, as were a lot of the tools that I ended up acquiring over the course of this project. Probably not a bad thing given I was working with MOSFETs.

And if I can make one more recommendation without sounding like an advert: MG Chemicals Desoldering Braid. Don't think about it, just buy it! (have some IPA wipes ready to clean up afterwards)

Construction

I don't believe that I will undertake another project in this way again - that's not to say I won't do another project, but I won't build it quite this discrete - next time I will likely use pre-packaged logic, and/or a microcontroller.

Using discrete componentry in this way is a huge task, especially when all of the wiring between logic elements is taken in to account. There's a lot of it, and its VERY fiddly, and although I did find a method to help make this part of the process a little easier (I would strip a length of insulation off the end of my jumper wire, solder it to the first pin in the circuit, and then strip subsequent appropriate lengths of insulation towards the previous solder joint before making the next solder joint and so on - I hope that makes sense...), and over time I got better and better at doing it, it was still a very tedious piece of work and I did make mistakes along the way.

I suppose a project like this might be easier and perhaps achieveable by more people if you could purchase circuit boards with all of the circuitry taken care of, and just needing you to solder everything in to place. You still get a clock made entirely of transistors, but you could probably manage to keep a couple of months of your life for something else.

The physical construction of the NOR gates worked extremely well. Little did I know when I started that it would be so perfectly suited. Certainly, building other types of gates would be much more difficult if not impossible due to the way they need to be wired together. The NOR gate layout was very well suited to this as the source pin of the transistors could be connected to a common ground rail, and the drain pin commoned via a resistor to the positive voltage rail allowing them to all maintain the same orientation on the board, and avoiding any complicated or tricky wiring.

If I do decide to build some discrete logic in this way again, I do think that NOR would probably be my go-to logic gate for such a task - it's really easy and convenient to build!

Conclusion

I'm glad its over, and now I can move on to something else. Maybe a break doing nothing will actually be a good thing.

There is still one board to build to dim the display, but I'll work on that some other time and post here when it's done.

Other than this, a Bill of Materials and a run down of costs might also be worth while, so here goes: https://docs.google.com/spreadsheets/d/1-uWIQYHm8d-aZ7Yp9LqevuUCRR0vtjQFpsaY1evqYjc/edit#gid=0

Quick facts:
  • ~2450 components in total
  • ~£272 worth of components, excluding parts sourced from ebay which were primarily headers/sockets, nuts/screws/spacers, and prototype boards, and which will probably total somewhere around £50
Theres a good chance the total cost of components is higher than it needs to be. If I bought more stuff off ebay it would likely be a lot cheaper, but RS is my favorite supplier, and they offer free, next day delivery on almost everything. You do tend to have to buy in bulk, which means you end up with surplus components, but they can go towards future projects so its not all bad.

And finally, some photos of the fully assembled unit (the empty board will eventually become the display dimmer).




Thursday, 30 March 2017

Clock design notes #4 - ripple counters

Ripple counters are used extensively in my clock. I use them as a prescaler for the mains frequency, and also for the various counters in the time and calendar "modules".

A ripple counter is an asynchronous counter. An external clock signal is applied only to the input of the first stage. The output of the first stage feeds in to the clock input of the second stage, and the output of the second stage feeds the next stage, and so on and so forth for as many stages as required. So as the name suggests, any changes that happen to the output state of each stage within the counter are going to ripple from one stage to the next - something like a line of dominos falling over.

This is basically the opposite of a synchronous counter, whose outputs all change at the same time based on a clock signal which is applied to all stages simultaneously. This results in an instantaneous change to all outputs at the same time in line with the clock signal.

I chose to use ripple counters instead of some other kind of synchronous counter (like one built from master-slave JK flip flops) because they are easier to implement with fewer transistors, and my clock doesn't have such an operating frequency where a synchronous counter might actually be necessary. For example, a modern CPU in a computer has an operating frequency somewhere in the multiple gigahertz (GHz) range (1GHz is 1 billion hertz... or 1 billion cycles per second), whereas my clock is timed from the AC mains frequency, which will be 50 or 60 hertz (hz) depending on where it is operated. So a little bit of delay here and there is not really detrimental to its operation - theres a relative eternity for things to settle down and work itself out (20ms per cycle at 50hz vs 1ns at 1GHz, several orders of magnitude).

So what is a ripple counter? It can be (as in my case) a series of D type flip flops cascaded together, and a D type flip flop is basically a series of SR latches.

So .. what is an SR latch? It's a very simple latch with two inputs, S (set) and R (reset), and two outputs, Q and the complement of Q (often referred to as "not Q"). The two inputs can be used to switch between two states: Q high and not Q low, or Q low and not Q high. In order to bring Q high, you must place a high signal on the set input. To bring Q low, you place a high signal on the reset input (not Q is always the opposite). Importantly, and as a latch, it holds the last state you applied even after you remove your input signal. Setting both the set and reset inputs high at the same time is an invalid input state, and at that point both Q and not Q will be low. As you'll see below, the topology of the SR latch circuit is symmetrical, so you can arbitrarily assign set and reset to either of the two inputs, the only rule is that Q will be the diagonally opposite output to the set input, and not Q will be diagonally opposite to the reset input.

You'll see them represented like this in my schematics, made easily out of two 2-input NOR gates:


You wont always see the inputs and outputs labelled in my schematics, and you might not always see the two outputs of the latch being used, but you will see this kind of circuit topology very frequently. I use a forward slash to indicate an inverted signal (i.e. the complement).

The explanation above is a bit brief, so I present to you a video by Ben Eater who explains this in more detail, and provides some practical examples to show its behaviour. It's a good video, and he has plenty more covering a project to build a small computer of sorts on a series of breadboards. Well worth watching his videos if you are interested in digital electronics, I highly recommend you check his channel out - you will learn a lot.

Moving on, three SR latches make a D type flip flop. In my clock I use D type flip flops with up to three inputs: clock (always), reset (always), and preset. Flip flops tend to be "edge triggered", that is, they will change state on either the rising or falling edge of the input clock pulse - which one depends on its construction. You may also be able to configure a flip flop to invert its state each time the clock input is pulsed, but this is not always the default behaviour. In my case, since I am using NOR logic, my flip flops will trigger and invert on the falling edge (high to low) of the input clock signal.

Setting the reset pin high will cause it to reset to a default state, in my case, Q being low. It's worth noting that while the clock input triggers on the falling edge, the reset input triggers on the rising edge.

In between resetting a D type flip flop and the next clock pulse, you can also feed in a preset signal. If the preset signal is high, the flip flop will start with Q being high, and the next clock pulse will transition Q to low. If the preset is left low, or no preset input is provided, the flip flop starts with Q low and the next clock pulse will transition it to high. A "full featured" D type flip flop will look like this in my schematics:


But once again, the inputs and outputs wont always be labelled, I've included them here to show you where those inputs are located. And as you can see, it's nothing more than three SR latches crossconnected in a specific way.

I don't have a particularly good video in mind to provide a link to to give a better explanation of the D type flip flop other than Ben Eaters video above, but I do have a link to a web page with a simulator that you can play with. It's not an exact representation of what I have here, but its pretty darn close and the operation is exactly the same. The only thing you need to do is set the D input to what ever the "not Q" output is before clicking the clock button, and you will see that you get the required behaviour which is to invert state on every clock pulse (you can see in my schematic above, not Q is tied to one of the inputs of GATE4, and that in the web based simulator, the same input to GATE4 is just a toggle).

There's also a mountain of additional reading on flip flops on this Wikipedia page.

Getting to the point where this all relates to a ripple counter... With the above theory in mind, recall that I have configured my D type flip flops to invert state on each clock pulse, and that they do this on the falling edge of the clock pulse.

If we start with all ripple counters in a reset state, such that Q is low for all outputs, and then feed a clock pulse in to the first stage (referred to as the "least significant bit") of the ripple counter, its Q output inverts to high on the falling edge of the clock pulse. On the next clock pulse, Q inverts back to low at the falling edge of the clock pulse. That output is also connected to the clock input of the second stage, so on the first stage output transitioning from high to low, Q of the second stage then inverts from low to high. We have just counted from 0 to 1 to 2. Now, the next clock pulse to the first stage inverts its Q output to high, and with high Q outputs on our first two ripple counter stages we are at binary value of 3. A further clock pulse to the first stage inverts its output to low, and that high to low transition causes the second stage to invert its Q output to low, and with the second stage output tied to the third stage clock input, that high to low transition causes the third stage to invert from low to high. We've now counted  0, 1, 2, 3, 4 (in binary, with the least significant bit on the right: 000, 001, 010, 011, 100).

But words aren't always interesting, so here's what is known as a timing diagram to visualise all of what I wrote above, plus a few extra clock pulses so you can see how it continues on:


As you can see, after the 8th clock pulse transitions high to low, all 3 stages return to low Q output state. It's no coincidence, a 3 bit counter can count from 0-7 which is 8 different values.

Bear in mind that this is just for demonstration purposes. Recall that a ripple counter is an asynchronous counter, so the outputs do not all transition instantly at the falling edge of the clock, rather, the falling edge of the clock is only when the "chain reaction" will begin, starting with the first stage and "rippling" through the counter as each stages output transitions from high to low, but only as far as the first stage that transitions low to high (because further stages will only be clocked when the preceeding stage transitions from high to low). The above diagram would indeed be accurate for a synchronous counter. Just a limitation of trying to draw it up in a spreadsheet I guess. But we are talking on the order of nanoseconds here, so it might be reasonably fair to say they do change "pretty much all at the same time".

If that still isn't enough to satisfy your understanding, I also provide a logicly file where you can see it in action for yourself. Heres a screenshot if you want to reconstruct it in the online demo:


If you look through logicly's options and ensure that the "Limit Propagation to Frame Rate" option is checked, then you may actually be able to see the ripple effect in action.

As I mentioned at the start of the post, I'm using ripple counters throughout my clock. In fact there will be 7 in total. I also use a lone D type flip flop as a toggle for leap year handling.

The day of month counter is the only counter in the clock which accepts a pre-set value. This is so that each time it is reset it can be set to start counting from 1 instead of 0 like all of the other counters.

And finally, if you were wondering about transistor counts as per my recent posts, a D type flip flop with no preset input takes 14 transistors to implement or 15 with a preset input, but there is also some additional reset logic to go along with these counters, so more detailed counts will be provided in future posts when I discuss their specific design and construction.

Sunday, 19 March 2017

Clock design notes #3 - 16 segment decoders

In the last post I covered how I came up with the logic for some 7 segment decoders. In this post I will brush over the process to make 16 segment decoders to display month and day of week names. I say brush over because it's very much the same process, and I'd just end up repeating myself otherwise, but there are a couple of specifics for the 16 segment decoders so they deserve their own post.

It starts once again by working out a truth table to determine which segments need to be on for any given input value. To help make this process easier, I whipped up a little "character builder" in a spreadsheet, and by setting different cells to 0 or 1 I could turn different segments on or off, and the resulting string of 0's and 1's would go in to the truth table, e.g.:


Unlike 7 segment displays, the segment names you see here may not be standard, they are based on my chosen display from Kingbright, so adjust accordingly if you use different displays.

By fiddling with the character builder I assembled all of the characters necessary for month and day names and planted them in to their respective truth tables, then converted it all in to k-maps with minterms figured out to suit.

The truth tables and k-maps are a bit bigger and more numerous this time around, so instead of posting images here I'll link you to another spreadsheet that contains all of the workings. I've been "strict" again with the month and day of week names in that values beyond those which are required will result in a blank display. e.g. the month counter will be 4 bits, but for values 12-15 my decoders do not produce any output (December is month 11 with January being month 0 - everything in my clock is indexed to 0).

You'll notice in the truth tables that typically segments a and b are the same, as well as e and f, and occasionally some others. So when I did my k-maps, I combined some segments in to the same k-map as they share exactly the same logic to turn them on and off.

To help minimise transistor count I loosened up some of the minterms to overlap with others where possible (the more cells you match the fewer inputs you need to AND and thus the fewer transistors needed), and fed the output of some NOR gates via an inverter in to other NOR gates to minimise some duplication. Perhaps there is room for more optimisation, but I think things are pretty slick as they are and I'm happy with the results.

And like with the 7 segment decoders, the final step was to translate this to logic and simulate it in logicly, and as before I've shared the logicly files for my decoders: day of week decoder, month decoder

Here's a sneak peak at the month decoder, it's by far the biggest of them all, but it does what it says on the tin:


You might need to use a little imagination to see the output on the right, or reference the light bulbs against the segments in the datasheet linked above. But with all zeroes on the input it is displaying "JAN".

And here's a count of transistors and gates that each decoder uses:

  • Day of week decoder: 91 transistors, 54 gates
  • Month decoder: 201 transistors, 101 gates

I don't think theres much else to say, so this is a nice short post. If you want some additional detail and background on how this all came together, check out my post about the 7 segment decoders.

Wednesday, 15 March 2017

Clock design notes #2 - 7 segment decoders

This time I promise to talk about something more technical, so I'll cover how I designed, from scratch, the BCD (Binary Coded Decimal) to 7 segment decoders that will drive the clock display, and also the day of the month display as part of the calendar.

I had originally intended to have an n-bit ripple counter feeding a decoder that could translate that n bit value in to outputs for two 7 segment displays. It seemed like the nicest and most "pure" solution, and I had begun designing things this way, but it started to get very complex vey quickly - a lot of gates using a lot of transistors, and I started to worry that I wouldn't be able to fit all of the decoders for the clock and calendar on to a single board each, and this is something I am trying very hard to achieve (i.e. one block of functionality per board).

I'll cover ripple counters in another post, but I've opted for a solution that involves one counter per display with varying numbers of bits depending on the maximum value a display needs to show. For example, the seconds "unit" counter will be 4 bits able to count 0-15 but resetting at 10 (so, 0-9), while the "tens" counter will be 3 bits able to count 0-7 but resetting at 6 (so, 0-5). The "tens" counter for hours would be 3 bits as it only needs to show up to the 20's. As a result I had to come up with three 7 segment decoders, one to handle each of 2, 3 and 4 bit BCD values, but I'll cover the process for the 4 bit decoder in this post (it's pretty much the same for the others).

The first step was to nut out a truth table that would determine which segments will be on for each given input value, and this is what I came up with:


It also helps to have a diagram of the display next to your truth table as a reference. 7 segment displays have an industry standard layout with each segment labelled a-g, and laid out in the arrangement you see above. Also, I've opted to only decode values 0-9, ignoring values 10-15 which would otherwise (perhaps) decode to letters A-F for hexadecimal readout - in my decoder they will result in a blank display.

Through this truth table you can also "stylise" your digits. For example, some decoders may leave segment a off for the digit 6, or segment d off for digit 9, others might turn them on. It's really up to you at this point (I chose to have segment a on for 6 and d on for 9 as I like that style).

The next step is where you start to work out the logic that will drive the segments. The method I used involves k-maps. You can find more detail on these at this Wikipedia page, but I'll give a brief run through of how I worked with them here.

The best way I can think of to explain a k-map is a table with a number of cells equal to and representing the number of different values in a given sized binary number. A 4 bit binary number would have a k-map of 16 cells because 4 bits of binary can represent 16 different values (0-15). And we need one k-map per segment of a display so that each input value can be mapped against a segment to determine whether it should be on or off for that value. This gives 7 k-maps for a 7 segment display. So this is what I started with:


AB and CD represent each half of the input value, and the arrangement is done according to Gray code, which might look a little confusing at first, but actually starts to make sense after working with k-maps for a little while. Pay attention to the ordering of the input bits A-D. In the truth table they are ordered most to least significant bit, but in the k-map I've done them least to most significant bit. The ordering doesnt matter, but in the truth table I opted to represent it how you'd typically see binary, whereas in the k-map I did it for ease of recognition with the bits reading left to right.

The next step is to place a 1 in each cell of the k-map where, in this case, the a segment of the display should be turned on, and 0 where it should be off. To do this, take each value from the a column of the truth table and place it in the appropriate cells of the k-map to come up with something like this:


With the above k-map you then need to define what are called "minterms" (or "maxterms" if you're working complementary wise), and they are essentially formulas that match cells of the k-map. I'm not sure if that made much sense, but heres a couple of examples that might help make this easier to understand:


And lets see if I can try to explain how this works...

Taking the yellow example, we can see that two cells are highlighted, and the formula to match those two cells is A'B'C'. The apostrophe indicates the complement, so A' ("not A") matches on 0, whereas A would match on 1. Beginning with A', match any rows where A is 0, which is the top two rows. Next is B', so this would narrow the match to only rows where B is also 0, so this would match the top row only as in the bottom row, A is 1. And finally with C' we further narrow the match to only columns where C is 0. So in that case, we end up with the two left hand cells of the top row.

Moving to the red example, we see that we need to start by matching only rows where the value of B is a 1. Next we need to narrow the match to only columns where C is 0, and finally columns where D is 0. This results in the middle two cells of the left hand column.

I'll leave the green example for you to run over and see if you can figure out how it works (answer at the bottom of the post).

The final step in this part of the process is to work out all of the minterms for the given k-map, and this is what I came up with for the a segment:


The same process is repeated until you have mapped out all of the segments against their respective input values. I've shared a spreadsheet which contains all of the k-maps for the 2, 3 and 4 bit decoders with the minterms that I worked out that you can look over, copy, play with, and maybe you might even find some efficiencies that I could have made. I tried hard and went over them for several days to try and minimise them as much as I could, but everyone reaches a point where you think "good enough".

Some logic can also be simplified, for example, A'BD' actually matches two cells, one on either side of the map. It doesn't matter that it overlaps with BC'D', but it does save a transistor because to match a single cell you need to AND against 4 inputs. 😏

I haven't been able to properly represent instances where minterms overlap each other, for example A'B'C' and B'C'D both match the cell corresponding to value ABCD = 0001. A limitation of using a spreadsheet I suppose. But it should all be there and all be correct. Certainly I think so because ...

The final step was to translate this to logic itself, taking inputs and producing output according to the k-map. A piece of software I have been using to simulate a lot of the logic for my clock is logic.ly. It's a neat piece of software that you can also try on-line for free or download a 30 day trial for various OSes. It has so far proven to be rather valuable in testing out whether something I have come up with will actually work or not - before committing it to a mess of wires.

The minterms defined above can now be translated in to logical AND operations. For example, to match A'B'C', we simply need a 3-input NOR gate (remember, a NOR gate can be used to perform AND operations). In the case of A'B'C', if you connect non-inverted A, B and C input signals to the NOR gate, if all of those inputs are low the NOR gate output will be high. That high signal can be fed in to an OR gate (NOR followed by a NOT) to turn on the a segment when the A, B and C inputs are all low, including any other situations where it should be on.

After a little bit of analysis you might also happen to notice that some gate combinations are used several times over. In my case, CD' is used 4 times in the decoder, so I was able to build that as its own little block of logic which could be fed in to other gates. This actually saves me a further single solitary transistor. BD' is used 3 times, but with 3 transistors to implement a similar little block of logic as CD', and then 3 transistors used to accept its input in to the 3 gates that use it versus using 2 transistors in the 3 gates that use that combination, you only break even. The real savings are at 4 uses and above, but unfortunately we don't get that many opportunities in this decoder.

Anyhow, this is what I came up with for my 4 bit BCD to 7 segment decoder and, of course, using nothing but NOR and NOT gates:


As you can see, with a value of 0110 (6) being input in to the decoder, I am getting a 6 on the display.

Don't worry about trying to re-create this yourself (unless you want to try out my circuit above in the online logicly demo, which I don't believe can load files), I have also shared the logicly files for all three of the decoders: 2 bit decoder, 3 bit decoder, 4 bit decoder

The end result, including any optimisation that I could find myself, is that each decoder uses the following number of transistors and gates (inverters/NOT gates included):

  • 2 bit decoder: 18 transistors, 14 gates
  • 3 bit decoder: 58 transistors, 26 gates
  • 4 bit decoder: 72 transistors, 30 gates

I think I'll leave it there for now. A similar process was followed to determine the logic for the 16 segment displays to display 3 letter month names (JAN, FEB, MAR etc) and 2 letter day of week names (MO, TU, WE etc). I'll cover this in another post.

Answer: ACD'