ECE 742 - Digital System-on-Chip Design: Lab Report
ECE 742 - Digital System-on-Chip Design: Lab Report
Lab Report
Introduction:
In this lab, we designed and built two different code converter circuits
using the Nexys 4 DDR Development board, which is designed
around the Xilinx Artix-7. We also gained experience using the Xilinx
Vivado digital circuit development tools.
Codeconverter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity simpleCodeConv is
Port ( A : in STD_LOGIC_VECTOR(3 downto 0);
Y : out STD_LOGIC_VECTOR(3 downto 0));
end simpleCodeConv;
begin
-- inverted inputs
A2_N <= NOT A(2);
A1_N <= NOT A(1);
A0_N <= NOT A(0);
-- output functions
Y(3) <= A(3) OR (A(2) AND A(0)) OR (A(2) AND A(1));
Y(2) <= (A2_N AND A(0)) OR (A2_N AND A(1)) OR (A(2) AND A1_N AND A0_N);
Y(1) <= (A1_N AND A0_N) OR (A(1) AND A(0));
Y(0) <= A0_N;
end Behavioral;
CodeConverter_tb.vhd
library
IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
component simpleCodeConv2
port ( A : in std_logic_vector(3 downto 0);
Y : out std_logic_vector(3 downto 0));
end component;
begin
Universal_codec
uut : simpleCodeConv2
port map ( A => a,
onv.vhd
Y => y);
librar
clock : process is
y ieee;
begin
use ieee.std_logic_1164.all;
clk <= '0'; wait for 5ns;
use ieee.numeric_std.all;
clk <= '1'; wait for 5ns;
-- clock period is 10ns
end process clock;
entity uniCodeConv is
Port ( Aprocess(clk)
: in STD_LOGIC_VECTOR(3 downto 0);
Y :variable
out STD_LOGIC_VECTOR(3
count : integer := 0; downto 0);
selbegin
: in STD_LOGIC);
end uniCodeConv;
if clk = '1' and clk'event then
architecture Behavioral of uniCodeConv
count := count + 1; is
a <= std_logic_vector(to_unsigned(count,4));
end if;
end process;
end sim;
begin
process(sel)
begin
case sel is
when '0' => Y <= std_logic_vector(to_unsigned(to_integer(unsigned( A )) + 3, 4));
when '1' => Y <= std_logic_vector(to_unsigned(to_integer(unsigned( A )) - 3, 4));
when others => Y <= "0000";
end case;
end process;
end Behavioral;
Universal_codeconv_tb.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity unicode_conv_TB is
-- Port ( );
end unicode_conv_TB;
component uniCodeConv
port ( A : in std_logic_vector(3 downto 0);
Y : out std_logic_vector(3 downto 0);
SEL : in STD_LOGIC:='1' );
end component;
begin
uut : uniCodeConv
port map ( A => a,
Y => y,
SEL => sel);
clock : process is
begin
clk <= '0'; wait for 5ns;
clk <= '1'; wait for 5ns;
-- clock period is 10ns
end process clock;
process is
begin
sel <= '0'; wait for 100ns;
sel <= '1'; wait for 100ns;
end process;
process(clk, sel)
variable count : integer := 0;
begin
if clk = '1' and sel = '1' and clk'event then
count := count + 1;
a <= std_logic_vector(to_unsigned(count,4));
end if;
end process;
end Behavioral;
Nexys4 Board: When input = 1000 and SEL = 1 the output = 0101 as
per the code conversion from Excess-3 code to Natural BCD
Conclusion:
In this lab, we designed and built a four-bit ripple carry adder and
subtractor circuit using modular design techniques using the Nexys 4
DDR Development board, which is designed around the Xilinx Artix-
7. The necessary coding concepts and procedures were introduced.
Procedure:
1. In this lab, we will first design a one-bit adder and use this as
sub-component for constructing four-bit ripple carry adder.
2. Create a file for one-bit adder and enter the VHDL code.
Simulate the code for its functionality and verify the results.
3. After verifying the results, create a new VHDL file to develop
four-bit adder. In the architecture, we import the entity of full
adder as a component and match the in and out bits as the
original code.
4. Then we apply logic for the four-bit ripple carry adder using the
one-bit adders in array on inputs a and b and store the result in S
and cout as sum and carry from the logic we used.
5. Assign pin numbers to the input and output ports in the design
using Nexys4DDRMaster.xdc file.
6. Synthesize the design and check for syntax errors. Run
implementation and generate bitstream to program Nexys4DDR
board.
7. Ensure that the board functions as expected in both adder and
subtractor mode. The output is verified through manually giving
inputs through the board.
A. Full Adder
Fulladder.vhd
library
ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity full_adder is
port (
a : in std_logic;
b : in std_logic;
c_in : in std_logic;
s : out std_logic;
c_out : out std_logic);
end full_adder;
-- EndofSignalSpecification
begin
-- put your own code here ..
-- EndofCode
end behav;
Fulladder-tb.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity full_addertb is
end full_addertb;
COMPONENT full_adder
port (
A : in std_logic;
B : in std_logic;
C_IN : in std_logic;
S : out std_logic;
C_OUT : out std_logic);
end COMPONENT;
signal s : std_logic;
signal c_out : std_logic;
-- EndofSignalSpecification
BEGIN
-- put your own code here ..
uut: full_adder PORT MAP(
A => a,
B => b,
C_IN => c_in,
S => s,
C_OUT => c_out);
stim_proc : process
begin
wait for 10ns;
A <= '0';
B <= '0';
C_IN <= '0';
wait for 10ns;
A <= '0';
B <= '0';
C_IN <= '1';
wait for 10ns;
A <= '0';
B <= '1';
C_IN <= '0';
wait for 10ns;
A <= '0';
B <= '1';
C_IN <= '1';
wait for 10ns;
A <= '1';
B <= '0';
C_IN <= '0';
wait for 10ns;
A <= '1';
B <= '0';
C_IN <= '1';
wait for 10ns;
A <= '1';
B <= '1';
C_IN <= '0';
wait for 10ns;
end process;
-- EndofCode
end behav;
Ripple_carry_adder.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Ripple_Adder is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
Cin : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0);
Cout : out STD_LOGIC);
end Ripple_Adder;
architecture Behavioral of Ripple_Adder is
-- Full Adder VHDL Code Component Decalaration
component full_adder_vhdl_code
Port ( A : in STD_LOGIC;
B : in STD_LOGIC;
Cin : in STD_LOGIC;
S : out STD_LOGIC;
Cout : out STD_LOGIC);
end component;
-- Intermediate Carry declaration
signal c1,c2,c3: STD_LOGIC;
begin
-- Port Mapping Full Adder 4 times
FA1: full_adder_vhdl_code port map( A(0), B(0), Cin, S(0), c1);
FA2: full_adder_vhdl_code port map( A(1), B(1), c1, S(1), c2);
FA3: full_adder_vhdl_code port map( A(2), B(2), c2, S(2), c3);
FA4: full_adder_vhdl_code port map( A(3), B(3), c3, S(3), Cout);
end Behavioral;
Ripple_carry_adder_tb.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY Tb_Ripple_Adder IS
END Tb_Ripple_Adder;
ARCHITECTURE behavior OF Tb_Ripple_Adder IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT Ripple_Adder
PORT(
A : IN std_logic_vector(3 downto 0);
B : IN std_logic_vector(3 downto 0);
Cin : IN std_logic;
S : OUT std_logic_vector(3 downto 0);
Cout : OUT std_logic
);
END COMPONENT;
--Inputs
signal A : std_logic_vector(3 downto 0) := (others => '0');
signal B : std_logic_vector(3 downto 0) := (others => '0');
signal Cin : std_logic := '0';
--Outputs
signal S : std_logic_vector(3 downto 0);
signal Cout : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Ripple_Adder PORT MAP (
A => A,
B => B,
Cin => Cin,
S => S,
Cout => Cout
);
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
A <= "0110";
B <= "1100";
wait for 100 ns;
A <= "1111";
B <= "1100";
wait for 100 ns;
A <= "0110";
B <= "0111";
wait for 100 ns;
A <= "0110";
B <= "1110";
wait for 100 ns;
A <= "1111";
B <= "1111";
wait;
end process;
END;
The Full Adder and four-bit ripple carry adder were implemented
successuflly. The ripple carry adder was constructed using full adder
as the sub-component. The results were verified both from the Vivado
software as well as the Nexys4 device.