TITLE: Project #3: HEX Decoder/Display Driver
AUTHOR: Chuck McManis
LAST UPDATE: 8-Mar-2001

Show a hexadecimal digit on a 7 segment LED display, allow the display to be blanked (all segments off) and tested (all segments on) at any time. This project is a purely combinatorial project. Easy right? BZZZT! Actually the project is quite easy but the way it turned out took me on an interesting side trip.

If you’re using the XESS board you can use the display on that board, but if you’re using the BED-SPARTAN2+ you will need to add a plug-on board with a display. You will also need some way to enter a 4 bit value.

Now go do the project and come back here. :-)

The interesting bit started when I looked at the synthesis report from the WebPACK ISE software. When synthesizing the first version it came back with this:

HDL Synthesis Report

Found no macro

Starting low level synthesis… Optimizing unit <hex_display> …

Building and optimizing final netlist …

========================================================================= Final Results Top Level Output File Name : hex_display.edn Output Format : EDIF crit : Speed Users Target Library File Name : Virtex Keep Hierarchy : NO Macro Generator : Macro+

Design Statistics

IOs : 13

Cell Usage :

BELS : 26

LUT2 : 5

LUT3 : 2

LUT4 : 14

MUXF5 : 5

IO Buffers : 13

IBUF : 6

# OBUF : 7

Now look at those numbers carefully, 26 logic elements to synthesize a stupid display decoder? Are they nuts? So I figured, “Ah… its optimizing for speed so it is spending gates to shorten propagation paths.” Thus I changed the preference for Area in the Synthesis->Properties menu. Ran it again and guess what, same result. Only now it says ‘crit AREA’ rather than speed.

Now I knew that this could be done in fewer gates because I could do it with logic similar to the Xilinx CLBs with fewer gates. Remember Karnaugh or K-maps ? The Xilinx base architecture has something that they call a Complex Logic Blocks (CLB). This CLB is really a 16 bit RAM that, because it is RAM, can “pretend” that it is any combinational logic that can be expressed as 4 inputs and one output. It does this by filling the RAM bits with the truth table of desired function. Complexity isn’t an issue as any 4 input truth table should take one CLB.

Looking at the hex decoder spec yet again you notice that you could express it as 7 independent logic functions, each taking six inputs (TEST, BLANK, and DATA[3..0]). And the output being a segment.

Now the interesting thing is that you can think of each segment independently as a function of four input bits (the display value) and if you label the display value bits ABCD, then you can write the K-map for the “A” segment as follows:

Table 1: Karnaugh Map for the A Segment
AB \ CD 00 01 11 10
00 on off on on
01 off on on on
11 on off on on
10 on on on off

You could no doubt minimize it but you can see that these four inputs produce one output (segment A). Now, let’s call that output DATA and notice that the truth table for the LED attached to the segment driver function is:

Table 2: Resolving the Outputs to Logic
BLANK TEST DATA OUTPUT
“on” don’t care don’t care off
“off” “on” don’t care on
“off” “off” output of segment function data

This second function is another function of three input variables and one output variable.

What that implies is that unless you were not trying, you could get the circuit to fit into 7 CLBs to hold the segment functions and 7 CLBs to hold the selection function. That is 14 CLBs or one half what the WebPACK ISE tool was getting.

If you instantiate a lot of displays you will waste a lot of your FPGA.

So I wrote it the second way, and while the synthesizer liked this one better, it wasn’t that much better. In fact the result is shown here:

HDL Synthesis Report

Found no macro

Starting low level synthesis… Optimizing unit <hex1_display> …

Building and optimizing final netlist …

========================================================================= Final Results Top Level Output File Name : hex1_display.edn Output Format : EDIF crit : Area Users Target Library File Name : Virtex Keep Hierarchy : NO Macro Generator : Macro+

Design Statistics

IOs : 13

Cell Usage :

BELS : 26

LUT2 : 5

LUT3 : 2

LUT4 : 14

MUXF5 : 5

IO Buffers : 13

IBUF : 6

# OBUF : 7

What I really wanted was an EDIF viewer to tell just what the heck this thing was synthesizing for my simple circuit. I tried reading through it but it was too opaque for me. I then tried writing the same circuit several different ways. Until finally I wrote it using the brute force method, of defining a bunch of little circuits, and then wiring them up together. That got me down to 14 logic units. Which was certainly better than the XST compiler was doing on its own.

So my local expert says, “But how do the non-free tools work on it?” and so I tried it on a Foundation 3.1i system, the answer, “7 SLICEs.” Yes, the Synopsys FPGA compiler synthesized the circuit into seven of the Spartan2 “SLICE” blocks (think of them as super CLBs).

The bottom line was, you get what you pay for. Sigh. No one seems to have figured out that you would get a lot more for less if normal people could get access to the specs for less than $250 each. Welcome to the “standards” world. Reminds me of the Lily Tomlin sketch about the phone company, “We don’t care, we don’t have to, we’re the IEEE.”

The Project

Design a 4-to–7 decoder circuit that converts a 4 bit value into hexadecimal digits on a 7 segment LED display. You should do two designs, in the first design use a process block and a case statement. In the second design use a concurrent assignment statement.

Table 3: Signal Specifications for the Project
Pin Direction Description
DATA[3..0] IN These four input pins determine the value shown on the display. Use the BED-DIPSWITCH board connected to J9 and assign these to locations P102, P101, P100, and P99. (labeled 3 through 0 on the switch board)
SEGS[6..0] OUT Connect these pins to the outer segments (labeled a-g) of a seven segment LED display. For a BED-7SEGMENT-DISPLAYS board, connect it to J4 and use locations P179, P180, P175, P174, P173, P178, and P176.
TEST IN This pin is used to "test" the display, when asserted true, all segments on the display should light up. Use the BED-DIPSWITCH board connected to J9 and assign this to location P29 (labeled 15 on the switch board)
BLANK IN This pin is used to "blank" the display, when asserted true all segments on the display should extinguish. It should have priority over TEST above. Use the BED-DIPSWITCH board connected to J9 and assign this to location P30 (labeled 14 on the switch board.)

This project uses two ways to synthesize a 7-segment display driver out of purely combinatorial logic. While both designs work in exactly the same way, they may not be equivalent in terms to the number of gates they consume.

This is perhaps the most frustrating aspect of VHDL, trying to out guess the logic inference engine.

Purpose

This project’s primary goal is to use two different VHDL constructs, the case statement and the concurrent signal assignment statement, to generate a decoder. You should also examine the synthesis report and determine which one (if either) uses fewer gates. Try setting the optimization for area rather than speed and see what effect, if any, that has on the output.

Discussion

The HEX Decoder/Driver circuit has three primary inputs, a TEST pin, a BLANK pin, and the DATA[3..0] pins. The output is 7 lines labeled SEGS[6..0] that are connected to the ‘a-g’ pins on a seven segment display.

Display drivers are a really useful circuit since one really great use of an FPGA or CPLD is to replace a bunch of logic that is driving a display panel with a single chip, further the panel can be “reconfigured” without re-wiring. This latter benefit, a natural consequence of using programmable logic, is great when prototyping. The advantages of the TEST and BLANK pins also becomes more obvious when you build these panels.

The TEST pin allows you to see if all the lights on the display panel are working, this can eliminate two questions when debugging a faulty display “Is there power?” and “Are the displays connected?” Once you know that both of these answers are YES then you can work back from the display into the circuit.

The BLANK pin is great for shutting off the display, and if you pulse it you can actually “dim” the display. See the going further section below for ways to explore this usage.

Going Further

This project will be re-used as a component in later projects, thus it is good to know how it works and how big it is. Try different ways of coding it (I’ve done at least 6) and compare their various trade-offs. Other things to explore: