It is assumed that you have already completed the first lab where you implemented a full adder and its test bench. In this lab there are three activities.
- Implement the full adder using Verilog’s clunky state machine table specification.
- Implement the full adder in VHDL.
- Test out a SystemVerilog implementation of a sequential circuit from the textbook.
You can find a pretty good overview of Verilog in the Verilog overview & references page at Texas A&M.
Using a state machine specification in Verilog
Getting ready
Start up ModelSim by typing vsim & at the command line prompt.
Open you project from the last lab. It should contain fulladder.v, a rather succinct implementation of a full adder, testbench.v, a testbench for your full adder.
Use the testbench to exercise the full adder to refresh your memory and to get ready for the next part.
A state machine in Verilog
In Verilog, a finite state machine specification is given as a user defined primitive (UDP). The UDP looks like a module with a truth table inside. The truth table is inconveniently confined to have only one output column. Also, in the header for the UDP, the single output must be the first parameter; and, in the table of the UDP, the single output must be the last column.
Open up fulladder.v and add, via cut-and-paste, a
UDP called sumbit
for computing the
sum bit of the full adder.
// Compute the sum bit primitive sumbit ( output Sn, input An, input Bn, input Cn ) ; table // An Bn Cn --> Sn 0 0 0 : 0 ; 0 0 1 : 1 ; 0 1 0 : 1 ; 0 1 1 : 0 ; 1 0 0 : 1 ; 1 0 1 : 0 ; 1 1 0 : 0 ; 1 1 1 : 1 ; endtable endprimitive
Now it’s your turn.
Within this same file,
create a second UDP called carrybit
for computing the carry bit of the
full adder. It will look a lot like sumbit
, so start with
a copy.
Using your UDP’s
Now you must modify your fulladder
module to use sumbit
and carrybit
.
We do this by using a structural implementation, similar
to our first implementation,
the structural implementation with logic gates,
of the full adder in
last week’s lab.
The entire body of your fulladder
consists of
only two lines, one a “call” to carrybit
and
the other a “call” to sumbit
.
You don’t even need to introduce any new variables.
Try to complete this one on your own, but ask for help if you are stuck.
Running the testbench
You don’t need to change the testbench. Just use it.
Show the instructor a run of your testbench with the UDP implementation.
A very quick look at VHDL
VHDL and Verilog have shared the circuit specification market for years, although Verilog; with the help of SystemVerilog, may now be pulling ahead. The design philosophies of VHDL come from ADA, which is a bit like Pascal and C++. You may find them to be a little odd.
We won’t use VHDL in any significant way in this class, but you should see at least one VHDL program.
Creating the project
Close your Verilog full adder project and
create a new project called
lab2vhdl
inside your
csci/320/lab2 directory.
Adding an interface
Start by adding a single VHDL file called fulladder.vhd containing the following.
library IEEE ; use IEEE.STD_LOGIC_1164.all ; -- specification for the fulladder interface -- PS: Think Java abstract method entity fulladder is port( An: in STD_LOGIC ; Bn: in STD_LOGIC ; Cn: in STD_LOGIC ; Cnp1: out STD_LOGIC ; Sn: out STD_LOGIC) ; end fulladder ;
Study this for a little while.
There is no real code.
This file is a bit like the a Java interface
or a C++ .h file.
It does not implement the full adder, it just specifies the types
of the ports.
Go ahead and compile this file, just like you might
compile a Java interface.
Also, notice the library
and use
statements.
They should remind you of the import
of Java.
It should already be clear that VHDL is a wordy programming language.
Adding an implementation
Next add another VHDL program, this time stored in fulladderdf.vhd, to your project. (Right-click in the Project tab to add a file to the project.)
This program will be a dataflow implementation of the full adder. Start with the following almost-complete definition and then add the one missing line.
library IEEE ; use IEEE.STD_LOGIC_1164.all ; -- dataflow implementation of fulladder interface architecture fulladderdataflow of fulladder is begin Sn <= An xor Bn xor Cn ; end ;
You really do have to spell out the logical operators
as and
and or
.
I told you VHDL was wordy.
Isn’t it odd you don’t even give the parameter names
in the architecture
.
That’s one difference with the Java interface
.
Simulating your VHDL full adder
You can simulate your VHDL full adder without a test bench, just like
your simulated your Verilog full adder at the beginning of
the first Verilog lab
So start up the simulator,
add input and output ports to
the wave, and type commands like the following at
the vsim prompt.
Be sure to select fulladderdataflow
,
and not fulladder
,
for the simulation.
You need to select the Architecture,
not the Entity.
This means expanding down two levels.
> force An 0 > force Bn 0 > force Cn 0 > run 100
Show off your simulation.
A VHDL test bench
Let’s include a VHDL test bench to the mix.
Call it testbench.vdh and just cut-and-paste this entire program. It would be too much to expect you to write it.
library IEEE ; use IEEE.STD_LOGIC_1164.all ; use IEEE.STD_LOGIC_UNSIGNED.all; -- Neither input or output entity testfulladder is end testfulladder ; -- actual test bench architecture fulladdertester of testfulladder is component fulladder port( An: in STD_LOGIC ; Bn: in STD_LOGIC ; Cn: in STD_LOGIC ; Cnp1: out STD_LOGIC ; Sn: out STD_LOGIC) ; end component ; signal vin : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000" ; signal vout : STD_LOGIC_VECTOR(1 DOWNTO 0) ; begin dut: fulladder port map( An => Vin(2), Bn => Vin(1), Cn => Vin(0), Cnp1 => Vout(1), Sn => Vout(0)) ; process begin wait for 100 ps ; vin <= vin + "1" ; end process ; end ;
Notice that this program has both the entity
specification and
the architecture
implementation.
Also, note how the fulladder
component
is
connected to the testbench program.
We will talk a bit more about this program in class. For now, just simulate it.
Run the VHDL testbench and display its inputs and outputs within the wave simulator.
By the way, in the old days, the testing engineers ran the simulations as a ”batch“ job and looked at the wave forms later using programs. GTKWave, Some still do this. There are even YouTube tutorials to guide you through the experience.
Today large simulations may run for weeks. In this case, extensive testbench programs are created that thoroughly test the design and produce a report for the testers.
ModelSim on your own
It’s time for the first near-solo flight. Here are links to a couple of files from the textbook.
These files are neither Verilog or VHDL. They are in SystemVerilog, your third HDL dialect of the lab.
Create a new project with one of these programs. Be sure to add the file as a SystemVerilog.
Start up the simulator, but do not expect reasonable output until
you have clock the circuit at least once.
You may be a little problem using the force
on vector values. Just type the bits.
Do a simulation that would illustrate if you are using the latch or the flip flop.