Adder Implementation Using VHDL

 

In this lab, we will learn how to describe a simple combinatorial circuit using VHDL, we will explore the use of components, and signals.

 

What we want to accomplish is to make a 4 bit adder.This adder will add a 4-bit number A to a 4-bit number B, producing a 4-bit Sum and a carry bit out.We want to make this design out of two modular pieces, a 1 bit half-adder, and a 1 bit full-adder.

 

First, get the reference design from here.Create a folder in your home directory called AdderVHDL, and unzip it.Open it with the ispDesignEXPERT tool.Again, ignore the box that asks you if you want to use a different device.You will want to double-click on the top folder in the sources window that says RefDesginA, and re-name the project to AdderVHDL.Now you are ready to go.You should be looking at this:

 

 

Now, lets create a VHDL source file.To do this, select the Source menu item from the menu bar, select New, and choose VHDL module:

 

This will produce a text editor window where you will choose a name for the file, the entity name, and the architecture name, choose HalfAdder for all of these. This will create the following template in the text editor for you to work with:

 

 

Now, letís fill things in.You recall from our lecture discussions the concepts of the Entity and the Architecture.The Entity is the abstraction of the circuit.We can relate this to a function prototype in C.The Architecture is the implementation of the circuit, we can relate this to the function body in C.If you are not clear on these concepts, please review the material I handed out in lecture, or go here and look at the page for First Look: Entities and Architectures.

 

First, observe that the template by default includes the ieee std_logic_1164 library.Recall from lecture that this lets us use the std_logic data type.Remember that this gives us something a little more powerful than the simple native VHDLďbitĒ type.The ďbitĒ type can assume the values 0 or 1, the std_logic type is also a one-bit-wide data type, but it can assume a number of values.These values are primarily intended for simulation purposes, the values our std_logic type can assume are:

 

'U',  -- Uninitialized

 'X',  -- Forcing  Unknown

 '0',  -- Forcing  0

 '1',  -- Forcing  1

  'Z',  -- High Impedance  

  ĎW',  -- Weak Unknown

  'L',  -- Weak     0      

  'H',  -- Weak     1      

   '-'   -- Don't care

   

Most of the time, we will be dealing with the Ď0í and Ď1í values of std_logic, but donít ignore the fact that any std_logic data type can assume any of the above values. Read more about this topic in the web site I referenced above.Itís very good.

 

Ok, letís make our half-adder.Letís go from the top-down by first filling out the entity declaration.The top-down approach is a very powerful engineering tool.If you were working on a large project, you would first examine the requirements, and then start the design by making a very simple division of the system into several large blocks.You would then define the interface of these blocks, and make some statement of the operation performed by each block.Can you see how the Entity-Architecture paradigm might support this?To continue, lets think, our half adder will take two inputs and produce a sum and a carry output.Letís declare the Entity:

 

 

So, what we have described so far is a ďblack boxĒ that we promise will be a half adder.We will see later of what value this ďblack boxĒ declaration is.

 

We shouldnít have to do a whole lot of head-scratching to come up with the implementation of this. For something more complicated, you may want to use your usual combinatorial design methodology of making a truth table, and writing the Boolean equations.I would encourage you NOT to try to simplify logic equations you obtain in this way.If they are simple enough for you to reduce with a K-map, they can be written just as easily as a sum of products expression, and the compiler will simplify them for you.

 

So, letís fill in the implementation:

 

Lets do the same thing again for a full adder, repeat the process, make another VHDL module. You should have a file that looks like this:

 

 

Ok, letís review what our mission is here.We wanted to construct a 4 bit adder out of these two components.Letís look at a block diagram to help us understand:

 


†††††††††††††††† A0††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† Half Adder†††††††††††††††††††††††††††††††††††††††††† Sum0††

Half Adder

 

 
†††††††††††††††††††††††††††††††††††††††††††††††

††††††††††††††††††††††††††† B0

 


u††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† Ca††††††††††††††††††† Sum1†††††††††††††† †††††††††††††††††††††††††††††††††††

Full Adder

 

Full Adder

 

Full Adder

 
††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A1†††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††† B1††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† Sum2†††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A2†††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† B2††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† Sum3†††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††† A3†††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† B3††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† Carry Out

 

 

 

 

 

 

 

So, what we have made is the two ďblack boxesĒ that make up the interior of this thing, the Half Adder and the Full Adder.What we need to accomplish yet is to make the ďblack boxĒ, or entity, for the whole thing, figure out some way to make three full adders and one half adder inside of it, and figure out some way to hook them all up.Lucky for us, VHDL makes this relatively easy.Letís get started.

 

Make another VHDL module, call it FourBitAdder.From our diagram above, itís pretty easy to see what the entity declaration should look like.8 inputs, 4 outputs.Letís learn something new.Instead of declaring a bunch of different bit signals, lets use the std_logic_vector type.This lets us declare and use a group of bits as a bus, or vector.It is similar to the concept of an array in C.Most of you have done some coding in C.If I make a variable declaration like :

 

int ††my_array[4];

 

This give me 4 ints that I can access like my_array[0], my_array[1] and so on.Also, if I looked at the array in memory, I would see 4 contiguous memory locations occupied by my array 0-1-2-3.

 

VHDL gives us a similar capability with a little extra.If I make the VHDL declaration:

 

A:in std_logic_vector( 0 to 3 ) this gives me a 4-bit ďarrayĒ of std_logic type.Since we are designing hardware, itís best to think of it as a bus, a group of 4 wire if you will.Now, what I just wrote gives us something like this:

A††††††††††††††††††††

††††††††††††††††††††††††††††††††††† =†† †††††††††††††††††††††††††††††† A(0)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(1)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(2)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(3)

 

Now, about the extra.VHDL gives us the ability to have additional data types besides our bit things.Later on we will explore how to use things like are more like numbers than bits.We will be able to assign multi-bit numbers to busses like we have just declared.In those cases, it makes a difference which wire on our bus lines up with which bit in the number.VHDL gives us the ability to control the order of indexing of the bus.If I were to write the declarationA :in std_logic_vector(3 downto 0), it still gives me a 4 bit bus, but conceptually it would look like this:

 

A††††††††††††††††††††

††††††††††††††††††††††††††††††††††† =†† †††††††††††††††††††††††††††††† A(3)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(2)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(1)

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† A(0)

 

More on this later.For now, lets get started on our 4 bit adder entity declaration:

 

 

This looks like a good start.Compare the entity declaration to our block diagram, we have three 4-bit busses, two are inputs, one is output, and a single bit out.

 

Now, how do we use our half adder and full adder in this design?The answer is to use the concept of components.Observe what I add to the architecture below:

 

The component keyword is telling the logic compiler that I am using an entity-architecture defined elsewhere in this architecture.Observe that I am using the name of the entity I want to employ, and repeating the port declaration associated with that entity.This is similar to C, where I must include the function prototype before I use that function.

 

I need one more thing before I can complete this block, and that is something to use internal to this architecture to hook up the carryís between the blocks.We saw in a previous exercise the concepts of Signals.These are ďwiresĒ that we can use inside an architecture.In this example we need three wires.Letís get those like this:

 

Iíve made a signal called InternalCarry that is a bus with 3 wires in it.

 

Now, our only remaining problem is to actually make the adders, and connect them together.We do this with component instantiations and port mapping.Observe:

 

 

See whatís going on here?The line

 

Half:HalfAdder port map ( Ain(0),Bin(0),Sum(0), InternalCarry(0) );

 

Gives us an instance of our HalfAdder called Half.We are explicitly hooking up elements of our input busses A(0), B(0), to the spots in the port occupied by Ain and Bin, as indicated in the port map in the component declaration of HalfAdder.Likewise we are hooking up an element of our output vector Sum(0) to the spot in the port occupied by Sum, and an element of our internal signal InternalCarry(0) to the spot in the port occupied by Cout.Draw a picture of this to make sure you understand.

 

Letís look at the next line:

 

Full1: FullAdder port map ( Ain(1),Bin(1),InternalCarry(0), Sum(1), InternalCarry(1) );

 

This gives us an instance of FullAdder named Full1.The port mapping is similar to the line above.Note how we use InternalCarry(0) for the spot in the port occupied by Cin for the full adder.Recall that InternalCarry(0) was also what we put in the port map for the carry out of the half adder.What we have done is ďdraw the wireĒ from the Cout of the half adder to the Cin of the first full adder.Get the idea?

 

Now, save the file and look at the project manager.

 

 

Note how the files for the FullAdder and HalfAdder are indented from the file for the FourBitAdder.This indicates our design hierarchy. It shows that the file FourBitAdder uses the two components below it.Now compile the file FourBitAdder by double-clicking on the Synplify Synthesize VHDL File process.You should get a green check by the process, if not, find your typo!Double click on the Generate Schematic Symbol process.This will make a Part that will represent the 4 bit adder, it will appear in your [Local] library in the schematic editor.

 

Letís do something fun with this.Open the schematic editor, and click on the place part button of the drawing toolbar. Place an instance of the fourbitadder part on the schematic, like this:

 

 

Letís look at the part close-up:

 

 

Isnít that nice?See how the part has busses for the inputs and outputs?See how those lines are heavy compared to the Cout line, and how they have the notation [3:0]?I think itís cool.

 

Iíve got in mind a way to hook this up so we can watch it work on the Lattice Demo Board.What Iím going to do is plunk down a couple of 4 bit counters to drive the inputs.We have 4 7-segment displays, so we should be able to watch the two 4-bit inputs and the 4 bit plus carry output.We can use the push buttons to control the counters.Letís do it:

 

First, letís delete the wires we wonít be using from the reference design.Use the delete button on the drawing toolbar, itís the one that looks like an erasure. Your schematic should look like this:

 

 

Plunk down a couple of 74162 decade counters from the VANTTTL library, your schematic should look like this:

 

 

Letís hook them up.To do this, you will have to learn how to handle busses on the schematic.Recall that the inputs and outputs of our counters are busses.Letís zoom in on the connections between the counter outputs and the adder. The way we add busses is to first draw a wire, just like we were making a single connection, and then use the NET NAME drawing tool to name it as a bus.So, use the drawing toolbar to draw a wire from the Ain[3:0] input of the counter as shown below.Then click on the drawing toolbar button that says ABC on it.At the bottom of the screen type Ain[3:0], note that we donít have to give it the same name as the adder input, but we do have to make the bus size and ordering [3:0] the same.Place the net name on the wire.Observe that it will change to a thick line, indicating a bus.

 

Now we need to add taps- individual wires- off of the bus to hook up to the output pins of the counters. To do this, use the bus tap button from the drawing toolbar, itís the one in the upper right corner that looks like a ĎTí on itís side.Draw the tap from the bus to the pin on the counter.Draw one for each Q pin.Now we need to specify which wire on the bus each tap is hooked up to.Use the Net Name ( ABC ) button for this.Specify which wire by using the vector subscript notation, Ain[0] is the LSB wire on the bus,Ain[3] is the msb wire on the bus.Name each tap, your schematic should look like this:

 

 

Do the same for the other counter. Then finish things up on the input side of the counters.Tie the parallel load inputs low, remember the pull-up and pull-down symbols are in the parts library under GATES, at the very bottom of the list.Hook up the counter clock inputs to the IO driver hooked to CLK0.Hook up the enables to separate push buttons.Remember that these inputs are normally high, pushing the button on the demo board brings them low.Hook up the button thatís left to load both counters. Draw a neater schematic than I did.

 

 

Now, it would be kind of nifty if we could use our 7 segment displays to watch the Ain, the Bin, the Sum and the Carry, no?SO, lets hook up the Ain bus to U24, the bin to U23, the carry out to U26 and the Sum to U22.Use busses. Observe below:

 

 

Observe what I did with bus Bin[3:0], the act of naming two nets with the same name means that they are electrically connected.Much like the GLOBAL part in Pspsice.

 

 

Your completed output side should look like this:

 

 

Go back to the project manager and double click on compile schematic ( save it first ), you should get a green check, that or a cryptic error message. Check your connections.Observe the hierarchy indicated by the indentation of the sources:

 

 

There is one last thing I want you to do to the schematic.Later on in the simulation, we will want to look at some of the signals that exist inside the schematic, but do not actually connect to pins on the device, I am talking specifically about the bus signals Ain[3:0], Bin[3:0], and Sum[3:0].We need to tell the tool to keep these signals available for us.If we donít, the logic compiler may simplify things in a way that makes these signals hard to get at.I know this is a little complicated,trust me for now, Iíll explain more later. Look at the following example, from the drawing toolbarselect the Net Attribute Editor button, .This should bring up the dialog box below.Select the Sum[3:0] bus, it should turn green as shown below. Select the Keep = line in the dialog and type TRUE in the edit box, hit enter.This will tell the tool to preserve this bus for us.Repeat this action for the Ain[3:0] and Bin[3:0] busses. Donít forget to save the schematic.

 

 

 

Now we need to simulate, open the test vector file, refdesign.abv ( double-click on it in the Sources window ). We can, and will, make some sophisticated test vectors, letís start out like Tina Turner, slow and easy.Observe the following, Iím just editing in the Test_Vectors section ( remember that test vectors are written in ABLE, if you have questions about syntax, open up the ABLE language guide in HELP, or call me ):

 

"This is the actual section for the vectors that will do our simulation.

"It starts with the keyword Test_vectors.Following this is a line that tells

" us what signals in the design we are simulating -- ([clk,SW3,SW2,SW1] -> [U22,U23,U24,U26])

" What we do is specify the conditions we want for the input signals by filling in the left

" hand side of the equation, the right hand side can be filled in with the expected outputs.

" Note that one of our input signals is a clock - clk.We can simulate a clock pulse by the special

" keyword .C..The other input signals can be assigned 0 or 1 .

" We can specify values for the outputs, or use the keyword .X. for don't care.This will allow us

" to view the output waveforms, then it is up to us to determine if they are correct.If we put in

" specific values for the outputs, the functional simulator will give us warnings if the circuit

" does not give those outputs.

 

TRACE ([clk,SW3,SW2,SW1] -> [U22,U23,U24,U26]);

Test_vectors

([clk,SW3,SW2,SW1] -> [U22,U23,U24,U26])

[.C.,0,0,0] -> [.x.,.x.,.x.,.x.];††††††† "initially all zeros

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];††††† " the .C. gives us one clock pulse

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];††††† " remember that our pushbuttons are normally high, hence the '1' s

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];††††† " this should represent steady-state operation with no buttons pushed,

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];††††† " and the clock running/

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

[.C.,1,1,1] ->†† [.x.,.x.,.x.,.x.];

 

 

 

Now, compile the vectors and double-click on Functional Simulation:

 

 

This brings up the simulator window, click the red ! button to run it, this brings up the waveform window:

 

 

This is a bit unwieldy, too many waveforms,delete all but CLK, SW1, SW2, and SW3 by selecting the U22A and dragging to select the rest.Click the button that looks like a blank screen to delete them from the simulation. Now letís look at some of our internal signals.Click on the button that looks like a screen with waveforms on it.This should open the following dialog:

 

 

In the right scroll box, you can see all of the signals that are actually inputs or outputs to the outside world.In the left side there is the instance D.Select D and hit the PUSH button.This will make the signals inside the schematic appear in the right box, like this:

 

 

Now letís display the Ain[3:0], Bin[3:0], and Sum[3:0] signals.One way to do this is to add each signal individually, letís do that with Ain. Click on AIN[0] on the right box and then click Show.The waveform should now be added to the viewer.Repeat for AIN[1] Ė AIN[3].Recall that the 74162 is a decade counter, it is counting from 0 to 9 and repeating.Recall that we defined the bus as Ain[3:0], and hooked it up so that Ain[3] was the msb.Does the waveform make sense to you?Good.

 

 

Now letís add Bin[3:0], but letís add as a bus.Hit the Bus>> button, you should see the following:

 

Select BIN[0] Ė BIN[3] and click the AddNet(s) button. Click Save Bus, then Show, you should see the bus displayed as follows:

 

 

Awesome, huh? Do the same for Sum[3:0].

 

 

Well, looks like it works for even numbers, anyhow.Our simple set of test vectors doesnít really test this very well.Observe the glitches on the sum output, the bane of combinatorial logic. It would appear that we glitch on every transition of AIN[1], or is it BIN[1], or both???