Вы находитесь на странице: 1из 15

Combinational Logic

(Homework #4)

11-Sep-2018
For ECE-501, Dr. Kessler

Submitted By
Rachel Rajan
M.S in Computer Engineering
Student ID: 101624260
ECE 501, HW4 Rachel Rajan, 09/11/2018

Introduction
The main objective of this assignment is to implement two VHDL design of a combinational logic
circuit using a combination of ModelSim and Quartus based on the given truth table of a particular
logic circuit. The first technique is a dataflow method, which uses concurrent signal assignment
statements. It utilizes Boolean algebra to relate the inputs and outputs of the logic circuit. The
second technique is a behavioral method, which uses only process statements. It describes a
systems behavior or function in an algorithmic fashion. Each design is verified with the help of a
testbench, it is a program that applies a predetermined stimulus to a design entity during a
simulation to simulate the environment in which the design entity will operate. Here, ModelSim
is used for simulation to verify if the compiled VHDL represents the truth table of circuit. Then,
Quartus is utilized to compile each design and is fitted to a particular FPGA. This final step is done
to determine to find any differences between the final compiled and the optimized design generated
by the heuristics of the fitting algorithms and VHDL compiler

Design
The dataflow implementation directly implies a corresponding gate-level implementation. It uses
Boolean equations to perform logical operations on a given input, and then a respective output is
generated based on the truth table of the particular circuit. The Boolean equations are deduced
from the truth table with the help of a Karnaugh map (also called as K-map). Then, the resulting
Boolean equations are translated to the equivalent VHDL syntax. The VHDL code for the dataflow
design is given in Appendix A1.1 of this report.
The behavioral implementation of the circuit utilizes logical case statements to map each input to
its respective output which effectively represent the truth table for the particular circuit. These case
statements are conditional, where based on the value of the input the corresponding output is
selected. And these processes happen concurrently rather than sequentially. The VHDL code for
the behavioral design is given in Appendix A 1.2 of this report.
Finally, a testbench program was created and ModelSim was used to simulate each of the designs.
The same testbench was utilized for both simulations since the same external port interface was
used for each design. Additional changes were in the names used to instantiate the specific module.
The test bench program consists of four sections, which are a component declaration section, Input
signal declarations and initializations, Output declarations and the test component instantiation.
The output of the design is then compared with the obtained result and expected output from the
truth table, and if the output does not match the expected output it is considered as an error. If there
are no errors, then the design is declared to pass the test. The VHDL code for the testbench program
is given in Appendix A 1.1 a, and A 1.2 a of this report.

2 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

Results
The simulated output of the dataflow design is shown below in Figure 1.

Figure 1. ModelSim simulation of dataflow design


Additionally, the ModelSim transcript is present above showing that the dataflow design passed
the testbench program. Once the design was verified in ModelSim, it was then used to create a
Quartus project so that it could be compiled and fitted/routed for the DE2 115 FPGA board. The
results of the Quartus compilation for the dataflow design are shown below in Figure 2.

Figure 2. Quartus compilation results of dataflow design

3 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

From Figure 2, Quartus compilation results of the dataflow design, it can be seen that only four
logic elements on the FPGA were used by the compiled VHDL code.
To gain more insight regarding the interpretation of Quartus compiler and dataflow design
representation using the Boolean algebra expressions, the RTL viewer was used to see the
schematic circuit generated by the compiler. For the dataflow design, this is shown below in Figure
3.

Figure 3. Quartus RTL viewer of dataflow design

4 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

The simulated output of the behavioral design is shown below in Figure 4. Additionally, the
ModelSim transcript is present below showing that the behavioral design passed the testbench
program. Once the design was verified in ModelSim, it was then used to create a Quartus project
so that it could be compiled and fitted/routed for the DE2 115 FPGA board. The results of the
Quartus compilation for the dataflow design are shown below in Figure 4.

Figure 4. ModelSim simulation of Behavioral design


.

5 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

Figure 5. Quartus compilation results of behavioral design

From Figure 5, Quartus compilation results of the behavioral design, it can be seen that only four
logic elements on the FPGA were used by the compiled VHDL code.
To gain more insight regarding the interpretation of Quartus compiler and behavioral design
implementation using case statement representation of the truth table for the logic circuit, the RTL
viewer was used to see the schematic circuit generated by the compiler. For the behavioral design,
this is shown below in Figure 6.

6 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

Figure 6. Quartus RTL viewer of behavioral design

Conclusion
From the results section of this report, it can be inferred that both the dataflow and behavioral designs
performed functionally in a similar way and in the final VHDL code generated by the Quartus compiler
fitter. Here, both designs use the same total number of logic elements (i.e., 4) on the FPGA board and
produced identical outputs upon simulation. Also, if the differences between the dataflow designs and
behavioral designs are barely small, then behavioral design can be preferred over dataflow for
understandability, clarity, and time saving approaches. Apart from use in academic environments, the
behavioral design is likely to be preferred in terms of easy to understand, and able to modify compared to
the dataflow design.

7 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

APPENDIX
Appendix A 1.1 – VHDL Code (Dataflow implementation)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity CL_dataflow is port ( F : out std_logic_vector(3 downto 0);


A : in std_logic; B : in std_logic; C : in std_logic; D : in std_logic );
end CL_dataflow;

architecture dataflow of CL_dataflow is


begin
F(0) <= (not A and not B) or (not A and not C and D) or (not B and not C and D) or (not B and C and not
D) or (A and B and C);
F(1) <= (not A and D) or (not C and D) or (not A and not B and not C) or (A and not B and C and not D);
F(2) <= (not A and not B and D) or (not A and not C and D) or (not B and not C and D) or (B and C and
not D) or (A and not C and not D) or (A and B and C);
F(3) <= (not B and C) or (not A and not B and not D) or (not A and C and D) or (B and not C and D) or
(A and C and not D);
end dataflow;

Appendix 1.1 a VHDL Testbench (dataflow implemenatation)


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity test_CL_dataflow is end;

8 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

architecture test of test_CL_dataflow is


component CL_dataflow
port ( F : out std_logic_vector(3 downto 0);
A : in std_logic;
B : in std_logic;
C : in std_logic;
D : in std_logic);
end component;

signal F : unsigned(3 downto 0);


signal A_in : std_logic := '0';
signal B_in : std_logic := '0';
signal C_in : std_logic := '0';
signal D_in : std_logic := '0';
signal F_expected : unsigned(3 downto 0) := to_unsigned(0,4);
signal inputs : unsigned(3 downto 0) := to_unsigned(0,4);
signal outputs : unsigned(3 downto 0) := to_unsigned(0,4);

begin dev_to_test: CL_dataflow


port map ( unsigned(F) => F,
A => A_in,
B => B_in,
C => C_in,
D => D_in );

-- create the test outputs


inputs <= A_in & B_in & C_in & D_in;
F_expected <= outputs;

9 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

expected_proc : process(inputs)
begin
case inputs is
when "0000" => outputs <= "1011";
when "0001" => outputs <= "0111";
when "0010" => outputs <= "1001";
when "0011" => outputs <= "1111";
when "0100" => outputs <= "0000";
when "0101" => outputs <= "1111";
when "0110" => outputs <= "0100";
when "0111" => outputs <= "1010";
when "1000" => outputs <= "0100";
when "1001" => outputs <= "0111";
when "1010" => outputs <= "1011";
when "1011" => outputs <= "1000";
when "1100" => outputs <= "0100";
when "1101" => outputs <= "1010";
when "1110" => outputs <= "1101";
when "1111" => outputs <= "0101";
when others => outputs <= (others => 'X');
end case;
end process expected_proc;

stimulus : process
-- Variables for testbench
variable ErrCnt : integer := 0 ;
variable WriteBuf : line ;
begin for i in std_logic range '0' to '1' loop A_in <= i;
for j in std_logic range '0' to '1' loop B_in <= j;
for k in std_logic range '0' to '1' loop C_in <= k;

10 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

for m in std_logic range '0' to '1' loop D_in <= m;


wait for 10 ns;
if(F_expected /= F) then write(WriteBuf, string'("ERROR CL_dataflow test failed at F: A = "));
write(WriteBuf, A_in);
write(WriteBuf, string'(", B = "));
write(WriteBuf, B_in);
write(WriteBuf, string'(", C = "));
write(WriteBuf, C_in);
write(WriteBuf, string'(", D = ")); write(WriteBuf, D_in);
writeline(Output, WriteBuf);
ErrCnt := ErrCnt+1;
end if;
end loop; -- m
end loop; -- k
end loop; -- j
end loop; -- i
if (ErrCnt = 0) then report "SUCCESS!!! CL_behavioral Test Completed";
else report "CL_behavioral is broken" severity warning;
end if;
end process stimulus;
end test;

Appendix A 1.2 – VHDL Code (Behavioral implementation)


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CL_behavioral is
port ( F : out std_logic_vector(3 downto 0);
A : in std_logic;
B : in std_logic;
C : in std_logic;

11 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

D : in std_logic );
end CL_behavioral;

architecture behavior of CL_behavioral is


signal inputs : std_logic_vector(3 downto 0);
begin -- wiring up I/O to signals
inputs <= A & B & C & D;
CL_behavioral_proc: process(inputs)
begin
case inputs is
when "0000" => F <= "1011";
when "0001" => F <= "0111";
when "0010" => F <= "1001";
when "0011" => F <= "1111";
when "0100" => F <= "0000";
when "0101" => F <= "1111";
when "0110" => F <= "0100";
when "0111" => F <= "1010";
when "1000" => F <= "0100";
when "1001" => F <= "0111";
when "1010" => F <= "1011";
when "1011" => F <= "1000";
when "1100" => F <= "0100";
when "1101" => F <= "1010";
when "1110" => F <= "1101";
when "1111" => F <= "0101";
when others => F <= (others => 'X');
end case;
end process CL_behavioral_proc;

12 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

end behavior;

Appendix 1.2 a VHDL Testbench (Behavioral implementation)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity test_CL_behavioral is end;

architecture test of test_CL_behavioral is


component CL_behavioral port ( F : out std_logic_vector(3 downto 0);
A : in std_logic;
B : in std_logic;
C : in std_logic;
D : in std_logic );
end component;
signal F : unsigned(3 downto 0);
signal A_in : std_logic := '0';
signal B_in : std_logic := '0';
signal C_in : std_logic := '0';
signal D_in : std_logic := '0';
signal F_expected : unsigned(3 downto 0) := to_unsigned(0,4);
signal inputs : unsigned(3 downto 0) := to_unsigned(0,4);
signal outputs : unsigned(3 downto 0) := to_unsigned(0,4);

begin
dev_to_test: CL_behavioral port map ( unsigned(F) => F, A => A_in, B => B_in, C => C_in, D => D_in
);

13 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

-- create the test outputs


inputs <= A_in & B_in & C_in & D_in;
F_expected <= outputs;
expected_proc : process(inputs)
begin
case inputs is
when "0000" => outputs <= "1011";
when "0001" => outputs <= "0111";
when "0010" => outputs <= "1001";
when "0011" => outputs <= "1111";
when "0100" => outputs <= "0000";
when "0101" => outputs <= "1111";
when "0110" => outputs <= "0100";
when "0111" => outputs <= "1010";
when "1000" => outputs <= "0100";
when "1001" => outputs <= "0111";
when "1010" => outputs <= "1011";
when "1011" => outputs <= "1000";
when "1100" => outputs <= "0100";
when "1101" => outputs <= "1010";
when "1110" => outputs <= "1101";
when "1111" => outputs <= "0101";
when others => outputs <= (others => 'X');
end case;
end process expected_proc;
stimulus : process -- Variables for testbench
variable ErrCnt : integer := 0 ;
variable WriteBuf : line ;
begin
for i in std_logic range '0' to '1' loop A_in <= i;

14 of 15
ECE 501, HW4 Rachel Rajan, 09/11/2018

for j in std_logic range '0' to '1' loop B_in <= j;


for k in std_logic range '0' to '1' loop C_in <= k;
for m in std_logic range '0' to '1' loop D_in <= m;
wait for 10 ns;
if(F_expected /= F) then write(WriteBuf, string'("ERROR CL_behavioral test failed at F: A = "));
write(WriteBuf, A_in);
write(WriteBuf, string'(", B = "));
write(WriteBuf, B_in);
write(WriteBuf, string'(", C = "));
write(WriteBuf, C_in);
write(WriteBuf, string'(", D = "));
write(WriteBuf, D_in);
writeline(Output, WriteBuf); ErrCnt := ErrCnt+1;
end if;
end loop; -- m
end loop; -- k
end loop; -- j
end loop; -- i
if (ErrCnt = 0) then report "SUCCESS!!! CL_behavioral Test Completed";
else report "CL_behavioral is broken" severity warning;
end if;
end process stimulus;
end test;

15 of 15

Вам также может понравиться