Anda di halaman 1dari 55

library ieee ;

use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter is
port( clk: in std_logic;
reset: in std_logic;
enable: in std_logic;
count: out std_logic_vector(3 downto 0)
);
end counter;
architecture behav of counter is
signal pre_count: std_logic_vector(3 downto 0);
begin
process(clk, enable, reset)
begin
if reset = '1' then
pre_count <= "0000";
elsif (clk='1' and clk'event) then
if enable = '1' then
pre_count <= pre_count + "1";
end if;
end if;
end process;
count <= pre_count;
end behav;
------Test bench http://www.doulos.com/knowhow/vhdl_designers_guide/---library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_textio.all;
use std.textio.all;
entity counter_tb is
end;
architecture counter_tb of counter_tb is
COMPONENT counter
PORT ( count : OUT std_logic_vector(3 downto 0);
clk
: IN std_logic;
enable: IN std_logic;
reset : IN std_logic);
END COMPONENT ;
SIGNAL
SIGNAL
SIGNAL
SIGNAL

clk
reset
enable
count

:
:
:
:

std_logic := '0';
std_logic := '0';
std_logic := '0';
std_logic_vector(3 downto 0);

begin
dut : counter
PORT MAP (
count => count,
clk
=> clk,
enable=> enable,
reset => reset );

clock : PROCESS
begin
wait for 1 ns; clk
end PROCESS clock;

<= not clk;

stimulus : PROCESS
begin
wait for 5 ns; reset <= '1';
wait for 4 ns; reset <= '0';
wait for 4 ns; enable <= '1';
wait;
end PROCESS stimulus;
monitor : PROCESS (clk)
variable c_str : line;
begin
if (clk = '1' and clk'event) then
write(c_str,count);
assert false report time'image(now) &
": Current Count Value : " & c_str.all
severity note;
deallocate(c_str);
end if;
end PROCESS monitor;
end counter_tb;

Basic Logic Gates


---------------------------------------- driver (ESD book figure 2.3)
--- two descriptions provided
---------------------------------------library ieee;
use ieee.std_logic_1164.all;
---------------------------------------entity Driver is
port(
x: in std_logic;
F: out std_logic
);
end Driver;
---------------------------------------architecture behv1 of Driver is
begin
process(x)
begin
-- compare to truth table
if (x='1') then
F <= '1';
else
F <= '0';
end if;
end process;
end behv1;
architecture behv2 of Driver is
begin
F <= x;
end behv2;
-------------------------------------------------------------------------------- OR gate (ESD book figure 2.3)
--- two descriptions provided
-------------------------------------library ieee;
use ieee.std_logic_1164.all;
-------------------------------------entity OR_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);

end OR_ent;
--------------------------------------architecture OR_arch of OR_ent is
begin
process(x, y)
begin
-- compare to truth table
if ((x='0') and (y='0')) then
F <= '0';
else
F <= '1';
end if;
end process;
end OR_arch;
architecture OR_beh of OR_ent is
begin
F <= x or y;
end OR_beh;
----------------------------------------------------------------------------------------- AND gate (ESD book figure 2.3)
-- two descriptions provided
-------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
-------------------------------------------------entity AND_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);
end AND_ent;
-------------------------------------------------architecture behav1 of AND_ent is
begin
process(x, y)
begin
-- compare to truth table
if ((x='1') and (y='1')) then
F <= '1';
else
F <= '0';
end if;
end process;
end behav1;

architecture behav2 of AND_ent is


begin
F <= x and y;
end behav2;
---------------------------------------------------------------------------------------- XOR gate (ESD figure 2.3)
--- two descriptions provided
-------------------------------------library ieee;
use ieee.std_logic_1164.all;
-------------------------------------entity XOR_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);
end XOR_ent;
-------------------------------------architecture behv1 of XOR_ent is
begin
process(x, y)
begin
-- compare to truth table
if (x/=y) then
F <= '1';
else
F <= '0';
end if;
end process;
end behv1;
architecture behv2 of XOR_ent is
begin
F <= x xor y;
end behv2;
------------------------------------------ NOR gate (ESD figure 2.3)
--- two descriptions provided
----------------------------------------library ieee;
use ieee.std_logic_1164.all;

----------------------------------------entity NOR_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);
end NOR_ent;
-----------------------------------------architecture behv1 of NOR_ent is
begin
process(x, y)
begin
-- compare to truth table
if (x='0' and y='0') then
F <= '1';
else
F <= '0';
end if;
end process;
end behv1;
architecture behv2 of NOR_ent is
begin
F <= x nor y;
end behv2;
---------------------------------------------------------------------------------- NAND gate (ESD figure 2.3)
--- two descriptions provided
----------------------------------------library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------entity NAND_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);
end NAND_ent;
-----------------------------------------architecture behv1 of NAND_ent is
begin
process(x, y)
begin

-- compare to truth table


if (x='1' and y='1') then
F <= '0';
else
F <= '1';
end if;
end process;
end behv1;
----------------------------------------architecture behv2 of NAND_ent is
begin
F <= x nand y;
end behv2;
------------------------------------------------------------------------------- XOR gate (ESD figure 2.3)
--- two descriptions provided
-------------------------------------library ieee;
use ieee.std_logic_1164.all;
-------------------------------------entity XNOR_ent is
port(
x: in std_logic;
y: in std_logic;
F: out std_logic
);
end XNOR_ent;
--------------------------------------architecture behv1 of XNOR_ent is
begin
process(x, y)
begin
-- compare to truth table
if (x/=y) then
F <= '0';
else
F <= '1';
end if;
end process;
end behv1;
architecture behv2 of XNOR_ent is
begin
F <= x xnor y;

end behv2;
--------------------------------------------------------------------------------------------------- Combinational Logic Design
-- (ESD book figure 2.4)
-- by Weijun Zhang, 04/2001
--- A simple example of VHDL Structure Modeling
-- we might define two components in two separate files,
-- in main file, we use port map statement to instantiate
-- the mapping relationship between each components
-- and the entire circuit.
-----------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;

-- component #1

entity OR_GATE is
port(
X:
in std_logic;
Y:
in std_logic;
F2:
out std_logic
);
end OR_GATE;
architecture behv of OR_GATE is
begin
process(X,Y)
begin
F2 <= X or Y;
end process;
end behv;

-- behavior des.

------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;

-- component #2

entity AND_GATE is
port(
A:
in std_logic;
B:
in std_logic;
F1:
out std_logic
);
end AND_GATE;
architecture behv of AND_GATE is
begin
process(A,B)
begin
F1 <= A and B;
end process;
end behv;

-- behavior des.

-------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use work.all;
entity comb_ckt is

-- top level circuit

port(

input1:
input2:
input3:
output:

in std_logic;
in std_logic;
in std_logic;
out std_logic

);
end comb_ckt;
architecture struct of comb_ckt is
component AND_GATE is
port(
A: in std_logic;
B: in std_logic;
F1: out std_logic
);
end component;

-- as entity of AND_GATE

component OR_GATE is
port(
X: in std_logic;
Y: in std_logic;
F2: out std_logic
);
end component;

-- as entity of OR_GATE

signal wire: std_logic;

-- signal just like wire

begin
-- use sign "=>" to clarify the pin mapping
Gate1: AND_GATE port map (A=>input1, B=>input2, F1=>wire);
Gate2: OR_GATE port map (X=>wire, Y=>input3, F2=>output);
end struct;
---------------------------------------------------------------Testbench
--------------------------------------------------------------------- Test Bench for comb_ckt.vhd
-- (ESD figure 2.4)
-- by Weijun Zhang, 04/2001
--- Testbench is used to ensure the design is working properly
-- according to the specification.
-- assert statements are used to test the wrong value against
-- our desired one. we should test as many cases as possible,
-- particularly, we should include upper and lower limits
-- of the operations.
-------------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity CKT_TB is
end CKT_TB;

-- empty entity

------------------------------------------------------------------architecture TB of CKT_TB is

-- declare the whole circuit(entity of comb_ckt.vhd) as a component


component comb_ckt is
port(
input1: in std_logic;
input2: in std_logic;
input3: in std_logic;
output: out std_logic
);
end component;
-- declare all I/O ports from unit under test as signals.
-- signals are usually declared within architecture
signal T_input1, T_input2, T_input3, T_output: std_logic;
begin
U_UT: comb_ckt port map (T_input1,T_input2,T_input3,T_output);
process
variable err_cnt: integer := 0;
begin
-- Test case 1
T_input1 <= '0';
T_input2 <= '0';
T_input3 <= '0';
wait for 10 ns;
assert (T_output=((T_input1 or T_input2) and T_input3))
report "Failed Case1!" severity error;
if (T_output/=((T_input1 or T_input2) and T_input3)) then
err_cnt := err_cnt +1;
end if;
-- Test case 2
T_input1 <= '1';
T_input2 <= '1';
T_input3 <= '1';
wait for 10 ns;
assert (T_output=((T_input1 or T_input2) and T_input3))
report "Failed Case1!" severity error;
if (T_output/=((T_input1 or T_input2) and T_input3)) then
err_cnt := err_cnt +1;
end if;
-- Test case 3
T_input1 <= '1';
T_input2 <= '0';
T_input3 <= '1';
wait for 10 ns;
assert (T_output=((T_input1 or T_input2) and T_input3))
report "Failed Case1!" severity error;
if (T_output/=((T_input1 or T_input2) and T_input3)) then
err_cnt := err_cnt +1;
end if;
-- Test case 4
T_input1 <= '0';

T_input2 <= '1';


T_input3 <= '0';
wait for 10 ns;
assert (T_output=((T_input1 or T_input2) and T_input3))
report "Failed Case1!" severity error;
if (T_output/=((T_input1 or T_input2) and T_input3)) then
err_cnt := err_cnt +1;
end if;
-- summary of all the tests to see if any errors
if (err_cnt=0) then
assert false report "Testbench completed successfully!"
severity note;
else
assert true
report "Something wrong, try again pls!"
severity error;
end if;
wait;

-- stop running

end process;
end TB;
------------------------------------------------------------------configuration CFG_TB of CKT_TB is
for TB
end for;
end CFG_TB;
----------------------------------------------------------------------------------------------------------------------------- VHDL model for tri state driver
-- by Weijun Zhang, 05/2001
--- this friver often used to control system outputs
--------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity tristate_dr is
port(
d_in:
in std_logic_vector(7 downto 0);
en:
in std_logic;
d_out: out std_logic_vector(7 downto 0)
);
end tristate_dr;
architecture behavior of tristate_dr is
begin
process(d_in, en)
begin
if en='1' then
d_out <= d_in;
else
-- array can be created simply by using vector
d_out <= "ZZZZZZZZ";
end if;
end process;

end behavior;
testbench
----------------------------------------------------------------- Test Bench for Tri-state Driver
-- by Weijun Zhang, 05/2001
---------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity TB_tridr is
end TB_tridr;
architecture TB of TB_tridr is
component tristate_dr is
port(
d_in:
in std_logic_vector(7 downto 0);
en:
in std_logic;
d_out: out std_logic_vector(7 downto 0)
);
end component;
signal T_d_in, T_d_out: std_logic_vector(7 downto 0);
signal T_en: std_logic;
begin
U_UT: tristate_dr port map (T_d_in, T_en, T_d_out);
process
begin
T_d_in <= "11001100";
T_en <= '1';
wait for 20 ns;
assert(T_d_out = T_d_in) report "Error detected!"
severity warning;
T_en <= '0';
wait for 20 ns;
assert(T_d_out = "ZZZZZZZZ") report "Error detected!"
severity warning;
T_en <= '1';
wait for 10 ns;
wait;
end process;
end TB;
--------------------------------------------------------------configuration CFG_TB of TB_tridr is
for TB
end for;

end CFG_TB;
--------------------------------------------------------------Signal VS variables
--------------------------------------------------------- Signal vs. Variable (sig_var.vhd)
-- Look at the outputs in simulation waveform
-- for same computation, we get two different results
--- by Weijun Zhang, 05/2001
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity sig_var is
port(
d1, d2, d3:
res1, res2:
end sig_var;

in std_logic;
out std_logic);

architecture behv of sig_var is


signal sig_s1: std_logic;
begin
proc1: process(d1,d2,d3)
variable var_s1: std_logic;
begin
var_s1 := d1 and d2;
res1 <= var_s1 xor d3;
end process;
proc2: process(d1,d2,d3)
begin
sig_s1 <= d1 and d2;
res2 <= sig_s1 xor d3;
end process;
end behv;

Typical Combinational Components


-------------------------------------------------- VHDL code for 4:1 multiplexor
-- (ESD book figure 2.5)
-- by Weijun Zhang, 04/2001
--- Multiplexor is a device to select different
-- inputs to outputs. we use 3 bits vector to
-- describe its I/O ports
------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
-------------------------------------------------

entity Mux is
port(
I3:
I2:
I1:
I0:
S:
O:
);
end Mux;

in std_logic_vector(2 downto 0);


in std_logic_vector(2 downto 0);
in std_logic_vector(2 downto 0);
in std_logic_vector(2 downto 0);
in std_logic_vector(1 downto 0);
out std_logic_vector(2 downto 0)

------------------------------------------------architecture behv1 of Mux is


begin
process(I3,I2,I1,I0,S)
begin
-- use case statement
case S is
when "00" =>
when "01" =>
when "10" =>
when "11" =>
when others =>
end case;

O
O
O
O
O

<=
<=
<=
<=
<=

I0;
I1;
I2;
I3;
"ZZZ";

end process;
end behv1;
architecture behv2 of Mux is
begin
-- use when.. else
O <=
I0 when
I1 when
I2 when
I3 when
"ZZZ";

statement
S="00" else
S="01" else
S="10" else
S="11" else

end behv2;
---------------------------------------------------------------- Test Bench for Multiplexer (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- four operations are tested in this example.
--------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity Mux_TB is
end Mux_TB;

-- empty entity

--------------------------------------------------------------architecture TB of Mux_TB is
-- initialize the declared signals

signal
signal
signal
signal
signal
signal

T_I3: std_logic_vector(2 downto 0):="000";


T_I2: std_logic_vector(2 downto 0):="000";
T_I1: std_logic_vector(2 downto 0):="000";
T_I0: std_logic_vector(2 downto 0):="000";
T_O: std_logic_vector(2 downto 0);
T_S: std_logic_vector(1 downto 0);

component Mux
port(
I3:
I2:
I1:
I0:
S:
O:
);
end component;

in std_logic_vector(2 downto 0);


in std_logic_vector(2 downto 0);
in std_logic_vector(2 downto 0);
in std_logic_vector(2 downto 0);
in std_logic_vector(1 downto 0);
out std_logic_vector(2 downto 0)

begin
U_Mux: Mux port map (T_I3, T_I2, T_I1, T_I0, T_S, T_O);
process
variable err_cnt: integer :=0;
begin
T_I3
T_I2
T_I1
T_I0

<=
<=
<=
<=

"001";
"010";
"101";
"111";

-- I0-I3 are different signals

-- case select eqaul "00"


wait for 10 ns;
T_S <= "00";
wait for 1 ns;
assert (T_O="111") report "Error Case 0" severity error;
if (T_O/="111") then
err_cnt := err_cnt+1;
end if;
-- case select equal "01"
wait for 10 ns;
T_S <= "01";
wait for 1 ns;
assert (T_O="101") report "Error Case 1" severity error;
if (T_O/="101") then
err_cnt := err_cnt+1;
end if;
-- case select equal "10"
wait for 10 ns;
T_S <= "10";
wait for 1 ns;
assert (T_O="010") report "Error Case 2" severity error;
if (T_O/="010") then
err_cnt := err_cnt+1;
end if;
-- case select equal "11"

wait for 10 ns;


T_S <= "11";
wait for 1 ns;
assert (T_O="001") report "Error Case 3" severity error;
if (T_O/="001") then
err_cnt := err_cnt+1;
end if;
-- case equal "11"
wait for 10 ns;
T_S <= "UU";
-- summary of all the tests
if (err_cnt=0) then
assert (false)
report "Testbench of Mux completed sucessfully!"
severity note;
else
assert (true)
report "Something wrong, try again!"
severity error;
end if;
wait;
end process;
end TB;
---------------------------------------------------------------configuration CFG_TB of Mux_TB is
for TB
end for;
end CFG_TB;
------------------------------------------------------------------------------------------------------------------ 2:4 Decoder (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- decoder is a kind of inverse process
-- of multiplexor
------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
------------------------------------------------entity DECODER is
port(
I:
in std_logic_vector(1 downto 0);
O:
out std_logic_vector(3 downto 0)
);
end DECODER;
------------------------------------------------architecture behv of DECODER is
begin
-- process statement

process (I)
begin
-- use case statement
case I is
when "00" => O
when "01" => O
when "10" => O
when "11" => O
when others =>
end case;

<= "0001";
<= "0010";
<= "0100";
<= "1000";
O <= "XXXX";

end process;
end behv;
architecture when_else of DECODER is
begin
-- use when..else statement
O <=

"0001" when
"0010" when
"0100" when
"1000" when
"XXXX";

I
I
I
I

=
=
=
=

"00"
"01"
"10"
"11"

else
else
else
else

end when_else;
----------------------------------------------------------------------------------------------------------------- Test Bench for Decoder (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- four cases are tested here.
--------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity DECODER_TB is
end DECODER_TB;

-- entity declaration

architecture TB of DECODER_TB is
signal T_I: std_logic_vector(1 downto 0):="00";
signal T_O: std_logic_vector(3 downto 0);
-- declare the component
component DECODER
port(
I:
in std_logic_vector(1 downto 0);
O:
out std_logic_vector(3 downto 0)
);
end component;
begin

U_DECODER: DECODER port map (T_I, T_O);


process
-- variable should be declared within process
variable err_cnt : integer := 0;
begin
-- case "00"
wait for 10 ns;
T_I <= "00";
wait for 1 ns;
assert (T_O="0001") report "Error Case 0"
severity error;
if (T_O/="0001") then
err_cnt := err_cnt + 1;
end if;
-- case "01"
wait for 10 ns;
T_I <= "01";
wait for 1 ns;
assert (T_O="0010") report "Error Case 1"
severity error;
if (T_O/="0010") then
err_cnt := err_cnt + 1;
end if;
-- case "10"
wait for 10 ns;
T_I <= "10";
wait for 1 ns;
assert (T_O="0100") report "Error Case 2"
severity error;
if (T_O/="0100") then
err_cnt := err_cnt + 1;
end if;
-- case "11"
wait for 10 ns;
T_I <= "11";
wait for 1 ns;
assert (T_O="1000") report "Error Case 3"
severity error;
if (T_O/="1000") then
err_cnt := err_cnt + 1;
end if;
-- case "11"
wait for 10 ns;
T_I <= "UU";
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"

severity note;

else

assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
--------------------------------------------------------------configuration CFG_TB of DECODER_TB is
for TB
end for;
end CFG_TB;
------------------------------------------------------------------------------------------------------------------------ VHDL code for n-bit adder (ESD figure 2.5)
-- by Weujun Zhang, 04/2001
--- function of adder:
-- A plus B to get n-bit sum and 1 bit carry
-- we may use generic statement to set the parameter
-- n of the adder.
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-------------------------------------------------------entity ADDER is
generic(n: natural :=2);
port(
A:
in std_logic_vector(n-1 downto 0);
B:
in std_logic_vector(n-1 downto 0);
carry: out std_logic;
sum:
out std_logic_vector(n-1 downto 0)
);
end ADDER;
-------------------------------------------------------architecture behv of ADDER is
-- define a temparary signal to store the result
signal result: std_logic_vector(n downto 0);
begin
-- the 3rd bit should be carry
result <= ('0' & A)+('0' & B);

sum <= result(n-1 downto 0);


carry <= result(n);
end behv;
------------------------------------------------------------------------------------------------------------------------------ Test Bench for 2-bit Adder (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- five cases are tested in this example
---------------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ADDER_TB is
end ADDER_TB;

-- entity declaration

architecture TB of ADDER_TB is
component ADDER is
port(
A:
B:
carry:
sum:
);
end component;
signal A, B:
signal carry:
signal sum:

in std_logic_vector(1 downto 0);


in std_logic_vector(1 downto 0);
out std_logic;
out std_logic_vector(1 downto 0)

std_logic_vector(1 downto 0);


std_logic;
std_logic_vector(1 downto 0);

begin
U_ADDER: ADDER port map (A, B, carry, sum);
process
variable err_cnt: integer :=0;
begin
-- case 1
A <= "00";
B <= "00";
wait for 10 ns;
assert (sum="00") report "Sum Error!" severity error;
assert (carry='0') report "Carry Error!" severity error;
if (sum/="00" or carry/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 2
A <= "11";
B <= "11";

wait for 10 ns;


assert (sum="10") report "Sum Error!" severity error;
assert (carry='1') report "Carry Error!" severity error;
if (sum/="10" or carry/='1') then
err_cnt:=err_cnt+1;
end if;
-- case 3
A <= "01";
B <= "10";
wait for 10 ns;
assert (sum="11") report "Sum Error!" severity error;
assert (carry='0') report "Carry Error!" severity error;
if (sum/="11" or carry/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 4
A <= "10";
B <= "01";
wait for 10 ns;
assert (sum="11") report "Sum Error!" severity error;
assert (carry='0') report "Carry Error!" severity error;
if (sum/="11" or carry/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 5
A <= "01";
B <= "01";
wait for 10 ns;
assert (sum="10") report "Sum Error!" severity error;
assert (carry='0') report "Carry Error!" severity error;
if (sum/="10" or carry/='0') then
err_cnt:=err_cnt+1;
end if;
-- summary of testbench
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
-------------------------------------------------------------------configuration CFG_TB of ADDER_TB is
for TB
end for;

end CFG_TB;
----------------------------------------------------------------------------------------------------------------------- n-bit Comparator (ESD book figure 2.5)
-- by Weijun Zhang, 04/2001
--- this simple comparator has two n-bit inputs &
-- three 1-bit outputs
--------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
--------------------------------------------------entity Comparator is
generic(n: natural :=2);
port(
A:
in std_logic_vector(n-1 downto 0);
B:
in std_logic_vector(n-1 downto 0);
less:
out std_logic;
equal:
out std_logic;
greater:
out std_logic
);
end Comparator;
--------------------------------------------------architecture behv of Comparator is
begin
process(A,B)
begin
if (A<B) then
less <= '1';
equal <= '0';
greater <= '0';
elsif (A=B) then
less <= '0';
equal <= '1';
greater <= '0';
else
less <= '0';
equal <= '0';
greater <= '1';
end if;
end process;
end behv;
------------------------------------------------------------------------------------------------------------------------ Test Bench for 2-bit Comparator (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- nine cases are tested here
--------------------------------------------------------------------library ieee;

use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity Comparator_TB is
end Comparator_TB;

-- entity declaration

--------------------------------------------------------------------architecture TB of Comparator_TB is
component Comparator
port(
A:
B:
less:
equal:
greater:
);
end component;

in std_logic_vector(1 downto 0);


in std_logic_vector(1 downto 0);
out std_logic;
out std_logic;
out std_logic

signal A, B: std_logic_vector(1 downto 0):="00";


signal less, equal, greater: std_logic;
begin
Unit: Comparator port map (A, B, less, equal, greater);
process
variable err_cnt: integer :=0;
begin
-- Case 1 (using the loop statement)
A <= "11";
B <= "00";
for i in 0 to 2 loop
wait for 10 ns;
assert (greater='1') report "Comparison Error detected!"
severity error;
if (greater/='1') then
err_cnt:=err_cnt+1;
end if;
B <= B + '1';
end loop;
-- Case 2 (using the loop statement)
A <= "00";
B <= "01";
for i in 0 to 2 loop
wait for 10 ns;
assert (less='1') report "Comparison Error detected!"
severity error;
if (less/='1') then
err_cnt:=err_cnt+1;
end if;
B <= B + '1';
end loop;
-- Case 3

A <= "01";
B <= "01";
wait for 10 ns;
assert (equal='1') report "Comparison Error detected!"
severity error;
if (equal/='1') then
err_cnt:=err_cnt+1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
------------------------------------------------------------------configuration CFG_TB of Comparator_TB is
for TB
end for;
end CFG_TB;
----------------------------------------------------------------------------------------------------------------------- Simple ALU Module (ESD book Figure 2.5)
-- by Weijun Zhang, 04/2001
--- ALU stands for arithmatic logic unit.
-- It perform multiple operations according to
-- the control bits.
-- we use 2's complement subraction in this example
-- two 2-bit inputs & carry-bit ignored
--------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--------------------------------------------------entity ALU is
port(

A:
B:
Sel:
Res:

);
end ALU;

in std_logic_vector(1 downto 0);


in std_logic_vector(1 downto 0);
in std_logic_vector(1 downto 0);
out std_logic_vector(1 downto 0)

--------------------------------------------------architecture behv of ALU is


begin
process(A,B,Sel)
begin
-- use case statement to achieve
-- different operations of ALU
case Sel is
when "00" =>
Res <= A + B;
when "01" =>
Res <= A + (not B) + 1;
when "10" =>
Res <= A and B;
when "11" =>
Res <= A or B;
when others =>
Res <= "XX";
end case;
end process;
end behv;
---------------------------------------------------------------------------------------------------------------------------------- Test Bench for ALU design (ESD figure 2.5)
-- by Weijun Zhang, 04/2001
--- we illustrate how to use package and procedure in this example
-- it seems a kind of complex testbench for this simple module,
-- the method, however, makes huge circuit testing more complete,
-- covenient and managable
-----------------------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
-- define constant, signal and procedure within package for ALU
package ALU_package is
constant INTERVAL: TIME := 8 ns;
signal sig_A, sig_B: std_logic_vector(1 downto 0);
signal sig_Sel: std_logic_vector(1 downto 0);
signal sig_Res: std_logic_vector(1 downto 0);
procedure load_data(signal A, B: out std_logic_vector(1 downto 0);
signal Sel: out std_logic_vector(1 downto 0));
procedure check_data(signal Sel: out std_logic_vector( 1 downto 0));

end ALU_package;
-- put all the procedure descriptions within package body
package body ALU_package is
procedure load_data (signal A, B: out std_logic_vector(1 downto 0);
signal Sel: out std_logic_vector(1 downto 0) ) is
begin
A <= sig_A;
B <= sig_B;
Sel <= sig_Sel;
end load_data;
procedure check_data (signal Sel: out std_logic_vector( 1 downto 0)) is
begin
Sel <= sig_Sel;
if (sig_Sel="00") then
assert(sig_Res = (sig_A + sig_B))
report "Error detected in Addition!"
severity warning;
elsif (sig_Sel="01") then
assert(sig_Res = (sig_A - sig_B))
report "Error detected in Subtraction!"
severity warning;
elsif (sig_Sel="10") then
assert(sig_Res = (sig_A and sig_B))
report "AND Operation Error!"
severity warning;
elsif (sig_Sel="11") then
assert(sig_Res = (sig_A or sig_B))
report "OR operation Error!"
severity warning;
end if;
end check_data;
end ALU_package;
-- Test Bench code for ALU
-------------------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164. all;
use work.ALU_package.all;
entity ALU_TB is
end ALU_TB;

-- entity declaration

architecture TB of ALU_TB is
component ALU
port(
A:
B:
Sel:
Res:
);
end component;

in std_logic_vector(1 downto 0);


in std_logic_vector(1 downto 0);
in std_logic_vector(1 downto 0);
out std_logic_vector(1 downto 0)

signal A, B, Res: std_logic_vector(1 downto 0):="00";

signal Sel: std_logic_vector(1 downto 0);


begin
U_ALU: ALU port map (A, B, Sel, Res);
process
begin
sig_A <= "10";
sig_B <= "01";
sig_Sel <= "00";
wait for 1 ns;
load_data(A, B, Sel);
wait for 1 ns;
sig_Res <= Res;
wait for INTERVAL;
check_data(Sel);

-- case 1: Addition

sig_Sel <= "01";


wait for 1 ns;
load_data(A, B, Sel);
wait for 1 ns;
sig_Res <= Res;
wait for INTERVAL;
check_data(Sel);

-- case 2: subtraction

sig_Sel <= "10";


wait for 1 ns;
load_data(A, B, Sel);
wait for 1 ns;
sig_Res <= Res;
wait for INTERVAL;
check_data(Sel);

-- case 3: AND operation

sig_Sel <= "11";

-- case 4: OR operation

wait for 1 ns;


load_data(A, B, Sel);
wait for 1 ns;
sig_Res <= Res;
wait for INTERVAL;
check_data(Sel);
wait;
end process;
end TB;
------------------------------------------------------------------------configuration CFG_TB of ALU_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------------------------------------------------------------- Example of doing multiplication showing
-- (1) how to use variable with in process
-- (2) how to use for loop statement

-- (3) algorithm of multiplication


--- by Weijun Zhang, 05/2001
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-- two 4-bit inputs and one 8-bit outputs
entity multiplier is
port(
num1, num2:
in std_logic_vector(1 downto 0);
product:
out std_logic_vector(3 downto 0)
);
end multiplier;
architecture behv of multiplier is
begin
process(num1, num2)
variable num1_reg: std_logic_vector(2 downto 0);
variable product_reg: std_logic_vector(5 downto 0);
begin
num1_reg := '0' & num1;
product_reg := "0000" & num2;
-- use variables doing computation
-- algorithm is to repeat shifting/adding
for i in 1 to 3 loop
if product_reg(0)='1' then
product_reg(5 downto 3) := product_reg(5 downto 3)
+ num1_reg(2 downto 0);
end if;
product_reg(5 downto 0) := '0' & product_reg(5 downto 1);
end loop;
-- assign the result of computation back to output signal
product <= product_reg(3 downto 0);
end process;
end behv;
--------------------------------------------------------- Test Bench for Mutiplier
-- by Weijun Zhang, 05/2001
-------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity TB_multiplier is
end TB_multiplier;

architecture TB of TB_multiplier is
component multiplier is
port(
num1, num2: in std_logic_vector(1 downto 0);
product:
out std_logic_vector(3 downto 0)
);
end component;
signal T_num1, T_num2: std_logic_vector(1 downto 0);
signal T_product: std_logic_vector(3 downto 0);
begin
U_UT: multiplier port map (T_num1, T_num2, T_product);
process
begin
T_num1 <= "11";
T_num2 <= "11";
wait for 20 ns;
assert(T_product="1001") report "Error detected!"
severity warning;
T_num1 <= "01";
T_num2 <= "00";
wait for 20 ns;
assert(T_product="0000") report "Error detected!"
severity warning;
T_num1 <= "10";
T_num2 <= "10";
wait for 20 ns;
assert(T_product="0100") report "Error detected!"
severity warning;
T_num1 <= "11";
T_num2 <= "10";
wait for 20 ns;
assert(T_product="0110") report "Error detected!"
severity warning;
wait;
end process;
end TB;
----------------------------------------------------------configuration CFG_TB of TB_multiplier is
for TB
end for;
end CFG_TB;
-----------------------------------------------------------

Latch & Flip-Flops

--------------------------------------------- Simple D Latch (ESD book Chapter 2.3.1)


-- by Weijun Zhang, 04/2001
--

-- latch is simply controlled by enable bit


-- but has nothing to do with clock sigal
-- notice this difference from flip-flops
-------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
-------------------------------------------entity D_latch is
port(
data_in:
enable:
data_out:
);
end D_latch;

in std_logic;
in std_logic;
out std_logic

-------------------------------------------architecture behv of D_latch is


begin
-- compare this to D flipflop
process(data_in, enable)
begin
if (enable='1') then
-- no clock signal here
data_out <= data_in;
end if;
end process;
end behv;
--------------------------------------------------------------------------------------------------------------- Test Bench for simple latch(ESD 2.3.1)
-- by Weijun Zhang, 04/2001
------------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity latch_TB is
end latch_TB;

-- entity declaration

------------------------------------------------------------------architecture TB of latch_TB is
signal T_data_in: std_logic;
signal T_enable:
std_logic;
signal T_data_out: std_logic;
component D_latch
port(
data_in:
enable:
data_out:
);
end component;

in std_logic;
in std_logic;
out std_logic

begin
U_latch: D_latch port map (T_data_in, T_enable, T_data_out);
process
variable err_cnt: integer := 0;
begin
T_data_in <= '1';
T_enable <= '0';
wait for 20 ns;
-- case 1
T_enable <= '1';
wait for 5 ns;
assert(T_data_out='1') report "Error1!" severity error;
if (T_data_out/='1') then
err_cnt := err_cnt + 1;
end if;
-- case 2
T_data_in <= '0';
wait for 20 ns;
assert(T_data_out='0') report "Error2!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;
-- case 3
T_data_in <= '1';
wait for 20 ns;
assert(T_data_out='1') report "Error3!" severity error;
if (T_data_out/='1') then
err_cnt := err_cnt + 1;
end if;
-- case 4
T_enable <= '0';
T_data_in <= '0';
wait for 20 ns;
assert(T_data_out='1') report "Error4!" severity error;
if (T_data_out/='1') then
err_cnt := err_cnt + 1;
end if;
-- case 5
T_enable <= '1';
wait for 5 ns;
assert(T_data_out='0') report "Error5!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"

severity note;

else

assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
-------------------------------------------------------------------configuration CFG_TB of latch_TB is
for TB
end for;
end CFG_TB;
------------------------------------------------------------------------------------------------------------------ D Flip-Flop (ESD book Chapter 2.3.1)
-- by Weijun Zhang, 04/2001
--- Flip-flop is the basic component in
-- sequential logic design
-- we assign input signal to the output
-- at the clock rising edge
--------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
use work.all;
--------------------------------------------entity dff is
port(
data_in:
clock:
data_out:
);
end dff;

in std_logic;
in std_logic;
out std_logic

---------------------------------------------architecture behv of dff is


begin
process(data_in, clock)
begin
-- clock rising edge
if (clock='1' and clock'event) then
data_out <= data_in;
end if;
end process;
end behv;

-------------------------------------------------------------------------------------------------------------- Test Bench for D flip-flop


---------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
entity dff_TB is
end dff_TB;

-- entity declaration

---------------------------------------------------------------architecture TB of dff_TB is
signal T_data_in: std_logic;
signal T_clock:
std_logic;
signal T_data_out: std_logic;
component dff
port(
data_in:
clock:
data_out:
);
end component;

in std_logic;
in std_logic;
out std_logic

begin
U_DFF: dff port map (T_data_in, T_clock, T_data_out);
-- concurrent process to offer clock signal
process
begin
T_clock <= '0';
wait for 5 ns;
T_clock <= '1';
wait for 5 ns;
end process;
process
variable err_cnt: integer := 0;
begin
-- case 1
T_data_in <= '1';
wait for 12 ns;
assert (T_data_out='1') report "Error1!" severity error;
if (T_data_out/='1') then
err_cnt := err_cnt + 1;
end if;
-- case 2
T_data_in <= '0';
wait for 28 ns;
assert (T_data_out='0') report "Error2!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;

-- case 3
T_data_in <= '1';
wait for 2 ns;
assert (T_data_out='0') report "Error3!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;
-- case 4
T_data_in <= '0';
wait for 10 ns;
assert (T_data_out='0') report "Error4!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;
-- case 5
T_data_in <= '1';
wait for 20 ns;
assert (T_data_out='1') report "Error5!" severity error;
if (T_data_out/='0') then
err_cnt := err_cnt + 1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
----------------------------------------------------------------configuration CFG_TB of dff_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------------------------------------------- JK Flip-Flop with reset
-- (ESD book Chapter 2.3.1)
-- by Weijun Zhang, 04/2001
--- the description of JK Flip-Flop is based
-- on functional truth table
-- concurrent statement and signal assignment
-- are using in this example
---------------------------------------------library ieee;

use ieee.std_logic_1164.all;
---------------------------------------------entity JK_FF is
port ( clock:
J, K:
reset:
Q, Qbar:
);
end JK_FF;

in std_logic;
in std_logic;
in std_logic;
out std_logic

----------------------------------------------architecture behv of JK_FF is


-- define the useful signals here
signal state: std_logic;
signal input: std_logic_vector(1 downto 0);
begin
-- combine inputs into vector
input <= J & K;
p: process(clock, reset) is
begin
if (reset='1') then
state <= '0';
elsif (rising_edge(clock)) then
-- compare to the truth table
case (input) is
when "11" =>
state <= not state;
when "10" =>
state <= '1';
when "01" =>
state <= '0';
when others =>
null;
end case;
end if;
end process;
-- concurrent statements
Q <= state;
Qbar <= not state;
end behv;
---------------------------------------------------------------------------------------------------------------------- Test Bench for JK flip-flop (ESD 2.3.1)
--- we use another process to offer the concurrent clock signal
---------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
entity jkff_TB is
end jkff_TB;

-- entity declaration

--------------------------------------------------------------------architecture TB of jkff_TB is
signal
signal
signal
signal

T_J, T_K:
std_logic;
T_clock:
std_logic;
T_reset:
std_logic;
T_Q, T_Qbar:
std_logic;

component JK_FF is
port (
clock:
J, K:
reset:
Q, Qbar:
);
end component;

in std_logic;
in std_logic;
in std_logic;
out std_logic

begin
U_JKFF: JK_FF port map (T_clock, T_J, T_K, T_reset, T_Q, T_Qbar);
-- concurrent process to offer clock signal
process
begin
T_clock <= '0';
wait for 5 ns;
T_clock <= '1';
wait for 5 ns;
end process;
process
variable err_cnt: integer := 0;
begin
T_reset <= '1';
wait for 25 ns;
T_reset <= '0';
wait for 10 ns;
-- case 1
T_J <= '0';
T_K <= '1';
wait for 15 ns;
assert (T_Q='0') report "Error1!" severity error;
if (T_Q/='0') then
err_cnt := err_cnt + 1;
end if;
-- case 2
wait for 5 ns;

T_J <= '1';


T_K <= '0';
wait for 15 ns;
assert (T_Q='1') report "Error2!" severity error;
if (T_Q/='0') then
err_cnt := err_cnt + 1;
end if;
-- case 3
wait for 5 ns;
T_J <= '1';
T_K <= '1';
wait for 15 ns;
assert (T_Q='0') report "Error3!" severity error;
if (T_Q/='0') then
err_cnt := err_cnt + 1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
-------------------------------------------------------------------configuration CFG_TB of jkff_TB is
for TB
end for;
end CFG_TB;
---------------------------------------------------------------------

Typical Sequential Components

---------------------------------------------------- n-bit Register (ESD book figure 2.6)


-- by Weijun Zhang, 04/2001
--- KEY WORD: concurrent, generic and range
--------------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--------------------------------------------------entity reg is
generic(n: natural :=2);
port(
I:
in std_logic_vector(n-1 downto 0);

clock:
load:
clear:
Q:

in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(n-1 downto 0)

);
end reg;
---------------------------------------------------architecture behv of reg is
signal Q_tmp: std_logic_vector(n-1 downto 0);
begin
process(I, clock, load, clear)
begin
if clear = '0' then
-- use 'range in signal assigment
Q_tmp <= (Q_tmp'range => '0');
elsif (clock='1' and clock'event) then
if load = '1' then
Q_tmp <= I;
end if;
end if;
end process;
-- concurrent statement
Q <= Q_tmp;
end behv;
--------------------------------------------------------------------------------------------------------------------- Test Bench for 2-bit register (ESD figure 2.6)
-- by Weijun Zhang, 04/2001
--- several ways you may use to specify the concurrent clock signal
-----------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity reg_TB is
end reg_TB;

-- entity declaration

-----------------------------------------------------------------architecture TB of reg_TB is
component reg
port(
I:
clock:
load:
clear:
Q:

in std_logic_vector(1 downto 0);


in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0)

);
end component;
signal
signal
signal
signal
signal

T_I:
T_clock:
T_load:
T_clear:
T_Q:

std_logic_vector(1 downto 0);


std_logic;
std_logic;
std_logic;
std_logic_vector(1 downto 0);

begin
U_reg: reg port map (T_I, T_clock, T_load, T_clear, T_Q);
-- concurrent process to offer the clock signal
process
begin
T_clock <= '0';
wait for 5 ns;
T_clock <= '1';
wait for 5 ns;
end process;
process
variable err_cnt: integer :=0;
begin
T_I <= "10";
T_load <= '0';
T_clear <= '1';
-- case 1
wait for 20 ns;
T_load <= '1';
wait for 10 ns;
assert (T_Q="10") report "Test1 Failed!" severity error;
if (T_Q/=T_I) then
err_cnt := err_cnt+1;
end if;
-- case 2
wait for 10 ns;
T_load <= '0';
wait for 10 ns;
assert (T_Q="10") report "Test2 Failed!" severity error;
if (T_Q/=T_I) then
err_cnt := err_cnt+1;
end if;
-- case 3
wait for 10 ns;
T_clear <= '0';
wait for 10 ns;
assert (T_Q="00") report "Test3 Failed!" severity error;
if (T_Q/=T_I) then
err_cnt := err_cnt+1;
end if;

-- case 4
wait for 10 ns;
T_clear <= '1';
wait for 10 ns;
assert (T_Q="00") report "Test4 Failed!" severity error;
if (T_Q/=T_I) then
err_cnt := err_cnt+1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of register completely successfully!"
severity note;
else
assert true
report "Something wrong, check again pls!"
severity error;
end if;
wait;
end process;
end TB;
-----------------------------------------------------------------configuration CFG_TB of reg_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------------------------------------------------- 3-bit Shift-Register/Shifter
-- (ESD book figure 2.6)
-- by Weijun Zhang, 04/2001
--- reset is ignored according to the figure
--------------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
--------------------------------------------------entity shift_reg is
port(
I:
clock:
shift:
Q:
);
end shift_reg;

in std_logic;
in std_logic;
in std_logic;
out std_logic

--------------------------------------------------architecture behv of shift_reg is


-- initialize the declared signal
signal S: std_logic_vector(2 downto 0):="111";

begin
process(I, clock, shift, S)
begin
-- everything happens upon the clock changing
if clock'event and clock='1' then
if shift = '1' then
S <= I & S(2 downto 1);
end if;
end if;
end process;
-- concurrent assignment
Q <= S(0);
end behv;
------------------------------------------------------------------------------------------------------------------ Test Bench for 3-bit shift register (ESD figure 2.6)
-- by Weijun Zhang, 04/2001
--- please note usually the processes within testbench do
-- not have sesitive list.
-------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity shifter_TB is
end shifter_TB;

-- entity declaration

architecture TB of shifter_TB is
component shift_reg
port(
I: in std_logic;
clock:
in std_logic;
shift:
in std_logic;
Q: out std_logic
);
end component;
signal
signal
signal
signal

T_I:
T_clock:
T_shift:
T_Q:

std_logic;
std_logic;
std_logic;
std_logic;

begin
U_shifter: shift_reg port map (T_I, T_clock, T_shift, T_Q);
-- concurrent process of clock
process
begin
T_clock <= '0';
wait for 5 ns;

T_clock <= '1';


wait for 5 ns;
end process;
-- concurrent process of test
process
variable err_cnt: integer := 0;
begin
T_shift <= '1';
T_I <= '0';
wait for 20 ns;
T_I <= '1';
wait for 20 ns;
T_I <= '0';
wait for 10 ns;
T_I <= '1';
wait;
end process;

-- start shifting
-- 1st/2nd bit input
-- 3rd bit input
-- 4th bit input

process
variable err_cnt: integer :=0;
begin
-- case 1
wait for 30 ns;
assert(T_Q='0') report "Test1 Failed !"
severity error;
if (T_Q/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 2
wait for 10 ns;
assert(T_Q='0') report "Test2 Failed !"
severity error;
if (T_Q/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 3
wait for 10 ns;
assert(T_Q='1') report "Test3 Failed !"
severity error;
if (T_Q/='1') then
err_cnt:=err_cnt+1;
end if;
-- case 4
wait for 10 ns;
assert(T_Q='1') report "Test4 Failed !"
severity error;
if (T_Q/='1') then
err_cnt:=err_cnt+1;
end if;
-- summary of all the tests

if (err_cnt=0) then
assert (false)
report "Testbench of Shifter completed successfully!"
severity note;
else
assert (true)
report "Something wrong, try again!"
severity error;
end if;
wait;
end process;
end TB;
---------------------------------------------------------------configuration CFG_TB of shifter_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------------------------------------------------- VHDL code for n-bit counter (ESD figure 2.6)
-- by Weijun Zhang, 04/2001
--- this is the behavior description of n-bit counter
-- another way can be used is FSM model.
---------------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
---------------------------------------------------entity counter is
generic(n: natural :=2);
port(
clock: in std_logic;
clear: in std_logic;
count: in std_logic;
Q:
out std_logic_vector(n-1 downto 0)
);
end counter;
---------------------------------------------------architecture behv of counter is
signal Pre_Q: std_logic_vector(n-1 downto 0);
begin
-- behavior describe the counter
process(clock, count, clear)
begin
if clear = '1' then
Pre_Q <= Pre_Q - Pre_Q;

elsif (clock='1' and clock'event) then


if count = '1' then
Pre_Q <= Pre_Q + 1;
end if;
end if;
end process;
-- concurrent assignment statement
Q <= Pre_Q;
end behv;
---------------------------------------------------------------------------------------------------------------------------- Test Bench for counter (ESD figure 2.6)
-- by Weijun Zhang, 04/2001
----------------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity counter_TB is
end counter_TB;

-- entity declaration

----------------------------------------------------------------------architecture TB of counter_TB is
component counter
port(
clock:
clear:
count:
Q:
);
end component;
signal
signal
signal
signal

T_clock:
T_clear:
T_count:
T_Q:

in std_logic;
in std_logic;
in std_logic;
out std_logic_vector(1 downto 0)

std_logic;
std_logic;
std_logic;
std_logic_vector(1 downto 0);

begin
U_counter: counter port map (T_clock, T_clear, T_count, T_Q);
process
begin
T_clock <=
wait for 5
T_clock <=
wait for 5
end process;

'0';
ns;
'1';
ns;

process
variable err_cnt: integer :=0;
begin

-- clock cycle is 10 ns

T_clear <= '1';


T_count <= '1';
wait for 20 ns;

-- start counting

T_clear <= '0';

-- clear output

-- test case 1
wait for 10 ns;
assert (T_Q=1) report "Failed case 1" severity error;
if (T_Q/=1) then
err_cnt := err_cnt+1;
end if;
-- test case 2
wait for 10 ns;
assert (T_Q=2) report "Failed case 2" severity error;
if (T_Q/=2) then
err_cnt := err_cnt+1;
end if;
-- test case 3
wait for 10 ns;
assert (T_Q=3) report "Failed case 3" severity error;
if (T_Q/=3) then
err_cnt := err_cnt+1;
end if;
-- test case 4
wait for 10 ns;
assert (T_Q=0) report "Failed case 4" severity error;
if (T_Q/=0) then
err_cnt := err_cnt+1;
end if;
-- test case 5
wait for 20 ns;
T_clear <= '1';
wait for 10 ns;
assert (T_Q=0) report "Failed case 5" severity error;
if (T_Q/=0) then
err_cnt := err_cnt+1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of Adder completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;

---------------------------------------------------------------configuration CFG_TB of counter_TB is


for TB
end for;
end CFG_TB;
----------------------------------------------------------------

Sequential Logic Design

------------------------------------------------------ VHDL FSM (Finite State Machine) modeling


-- (ESD book Figure 2.7)
-- by Weijun Zhang, 04/2001
--- FSM model consists of two concurrent processes
-- state_reg and comb_logic
-- we use case statement to describe the state
-- transistion. All the inputs and signals are
-- put into the process sensitive list.
----------------------------------------------------library ieee ;
use ieee.std_logic_1164.all;
----------------------------------------------------entity seq_design is
port(
a:
clock:
reset:
x:
);
end seq_design;

in std_logic;
in std_logic;
in std_logic;
out std_logic

----------------------------------------------------architecture FSM of seq_design is


-- define the states of FSM model
type state_type is (S0, S1, S2, S3);
signal next_state, current_state: state_type;
begin
-- cocurrent process#1: state registers
state_reg: process(clock, reset)
begin
if (reset='1') then
current_state <= S0;
elsif (clock'event and clock='1') then
current_state <= next_state;
end if;
end process;
-- cocurrent process#2: combinational logic
comb_logic: process(current_state, a)
begin

-- use case statement to show the


-- state transistion
case current_state is
when S0 => x <= '0';
if a='0' then
next_state <= S0;
elsif a ='1' then
next_state <= S1;
end if;
when S1 => x <= '0';
if a='0' then
next_state <= S1;
elsif a='1' then
next_state <= S2;
end if;
when S2 => x <= '0';
if a='0' then
next_state <= S2;
elsif a='1' then
next_state <= S3;
end if;
when S3 => x <= '1';
if a='0' then
next_state <= S3;
elsif a='1' then
next_state <= S0;
end if;
when others =>
x <= '0';
next_state <= S0;
end case;
end process;
end FSM;
---------------------------------------------------------------------------------------------------------------------- test bench for FSM (ESD book figure 2.7)
-- by Weijun Zhang, 04/2001
----------------------------------------------------------------library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity fsm_tb is
end fsm_tb;

-- entity declaration

-----------------------------------------------------------------

architecture TB of fsm_tb is
signal
signal
signal
signal

T_a: std_logic;
T_clock: std_logic;
T_reset: std_logic;
T_x: std_logic;

component seq_design
port(
a:
clock:
reset:
x:
);
end component;

in std_logic;
in std_logic;
in std_logic;
out std_logic

begin
U_fsm: seq_design port map(T_a, T_clock, T_reset, T_x);
process
begin
T_clock <=
wait for 5
T_clock <=
wait for 5
end process;

'1';
ns;
'0';
ns;

-- clock cycle 10 ns

process
variable err_cnt: integer :=0;
begin
-- case 1
T_reset <= '1';
wait for 20 ns;
assert (T_x='0') report "Failed Case 1" severity error;
if (T_x/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 2
T_reset <= '0';
T_a <= '0';
wait for 20 ns;
assert (T_x='0') report "Failed Case 2" severity error;
if (T_x/='0') then
err_cnt:=err_cnt+1;
end if;
-- case 3
wait for 30 ns;
T_a <= '1';
wait for 35 ns;
assert (T_x='1') report "Failed Case 3" severity error;
if (T_x/='1') then
err_cnt:=err_cnt+1;
end if;

-- case 4
wait for 70 ns;
T_reset <= '1';
wait for 10 ns;
assert (T_x='0') report "Failed Case 4" severity error;
if (T_x/='0') then
err_cnt:=err_cnt+1;
end if;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of FSM completely successfully!"
severity note;
else
assert true
report "Something wrong, Check again pls!"
severity error;
end if;
wait;
end process;
end TB;
---------------------------------------------------------------------configuration CFG_TB of fsm_TB is
for TB
end for;
end CFG_TB;
------------------------------------------------------------------------------------------------------------------------------------- a simple 4*4 RAM module (ESD book Chapter 5)
-- by Weijun Zhang
--- KEYWORD: array, concurrent processes, generic, conv_integer
-------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-------------------------------------------------------------entity SRAM is
generic(
width:
depth:
addr:
port(
Clock:
Enable:
Read:
Write:
Read_Addr:
Write_Addr:
Data_in:
Data_out:
);

integer:=4;
integer:=4;
integer:=2);
in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic_vector(addr-1 downto 0);
in std_logic_vector(addr-1 downto 0);
in std_logic_vector(width-1 downto 0);
out std_logic_vector(width-1 downto 0)

end SRAM;
-------------------------------------------------------------architecture behav of SRAM is
-- use array to define the bunch of internal temparary signals
type ram_type is array (0 to depth-1) of
std_logic_vector(width-1 downto 0);
signal tmp_ram: ram_type;
begin
-- Read Functional Section
process(Clock, Read)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Read='1' then
-- buildin function conv_integer change the type
-- from std_logic_vector to integer
Data_out <= tmp_ram(conv_integer(Read_Addr));
else
Data_out <= (Data_out'range => 'Z');
end if;
end if;
end if;
end process;
-- Write Functional Section
process(Clock, Write)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Write='1' then
tmp_ram(conv_integer(Write_Addr)) <= Data_in;
end if;
end if;
end if;
end process;
end behav;
------------------------------------------------------------------------------------------------------------------------------------ Test Bench for memory module (ESD book Chapter 5)
-- by Weijun Zhang, 04/2001
--- use loop statement to test module completely
-------------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity MEM_TB is
end MEM_TB;

-- entity declaration

--------------------------------------------------------------------

architecture TB of MEM_TB is
component SRAM is
port(
Clock:
Enable:
Read:
Write:
Read_Addr:
Write_Addr:
Data_in:
Data_out:
);
end component;
signal
signal
signal
signal

in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic_vector(1 downto 0);
in std_logic_vector(1 downto 0);
in std_logic_vector(3 downto 0);
out std_logic_vector(3 downto 0)

T_Clock, T_Enable, T_Read, T_Write: std_logic;


T_Data_in, T_Data_out: std_logic_vector(3 downto 0);
T_Read_Addr: std_logic_vector(1 downto 0);
T_Write_Addr: std_logic_vector(1 downto 0);

begin
U_CKT: SRAM port map (T_Clock, T_Enable, T_Read, T_Write,
T_Read_Addr, T_Write_Addr, T_Data_in, T_Data_out);
Clk_sig: process
begin
T_Clock<='1';
wait for 5 ns;
T_Clock<='0';
wait for 5 ns;
end process;

-- clock cycle 10 ns

process
variable err_cnt: integer := 0;
begin
T_Enable <= '1';
T_Read <= '0';
T_Write <= '0';
T_Write_Addr <= (T_Write_Addr'range => '0');
T_Read_Addr <= (T_Read_Addr'range => '0');
T_Data_in <= (T_Data_in'range => '0');
wait for 20 ns;
-- test write
for i in 0 to 3 loop
T_Write_Addr <= T_Write_Addr + '1';
T_Data_in <= T_Data_in + "10";
T_Write <= '1';
wait for 10 ns;
assert (T_Data_out="ZZZZ")
report "Something wrong!" severity Error;
if (T_Data_out /= "ZZZZ") then
err_cnt := err_cnt + 1;
end if;
end loop;
-- test read
for i in 0 to 2 loop

T_Read_Addr <= T_Read_Addr + '1';


T_Read <= '1';
wait for 10 ns;
assert (conv_integer(T_Data_out)=2*conv_integer(T_Read_Addr))
report "Something wrong!" severity Error;
if (conv_integer(T_Data_out)/=2*conv_integer(T_Read_Addr)) then
err_cnt := err_cnt + 1;
end if;
end loop;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of ROM completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
-------------------------------------------------------------------------configuration CFG_TB of MEM_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------------------

--------------------------------------------------------------- 32*8 ROM module (ESD Book Chapter 5)


-- by Weijun Zhang, 04/2001
--- ROM model has predefined content for read only purpose
-------------------------------------------------------------library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ROM is
port(
Clock
:
Reset
:
Enable :
Read
:
Address :
Data_out:
);
end ROM;

in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic_vector(4 downto 0);
out std_logic_vector(7 downto 0)

--------------------------------------------------------------

architecture Behav of ROM is


type ROM_Array is array (0 to 31)
of std_logic_vector(7 downto 0);
constant Content: ROM_Array := (
0 => "00000001",
1 => "00000010",
2 => "00000011",
3 => "00000100",
4 => "00000101",
5 => "00000110",
6 => "00000111",
7 => "00001000",
8 => "00001001",
9 => "00001010",
10 => "00001011",
11 => "00001100",
12 => "00001101",
13 => "00001110",
14 => "00001111",
OTHERS => "11111111"
);

-- Suppose ROM has


-- prestored value
-- like this table
--------------

begin
process(Clock, Reset, Read, Address)
begin
if( Reset = '1' ) then
Data_out <= "ZZZZZZZZ";
elsif( Clock'event and Clock = '1' ) then
if Enable = '1' then
if( Read = '1' ) then
Data_out <= Content(conv_integer(Address));
else
Data_out <= "ZZZZZZZZ";
end if;
end if;
end if;
end process;
end Behav;
--------------------------------------------------------------------------------------------------------------------------- Test Bench for 32*8 ROM module
-- (ESD book Chapter 5 Example)
-- by Weijun Zhang, 04/2001
------------------------------------------------------------library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ROM_TB is
end ROM_TB;

-- entity declaration

------------------------------------------------------------architecture TB of ROM_TB is

component ROM is
port(
Clock
:
Reset
:
Enable :
Read
:
Address :
Data_out:
);
end component;

in std_logic;
in std_logic;
in std_logic;
in std_logic;
in std_logic_vector(4 downto 0);
out std_logic_vector(7 downto 0)

signal T_Clock, T_Reset, T_Read, T_Enable: std_logic;


signal T_Address: std_logic_vector(4 downto 0);
signal T_Data_out: std_logic_vector(7 downto 0);
begin
U_ROM: ROM port map (T_Clock, T_Reset, T_Enable,
T_Read, T_Address, T_Data_out);
Clk_sig: process
begin
T_Clock<='1';
wait for 5 ns;
T_Clock<='0';
wait for 5 ns;
end process;

-- clock cycle 10 ns

process
variable err_cnt: integer := 0;
begin
T_Enable <= '1';
T_Read <= '0';
T_Reset <= '1';
T_Address <= (T_Address'range => '0');
wait for 20 ns;
assert(T_Data_out = "ZZZZZZZZ")
report "Something wrong!" severity Error;
if (T_Data_out /= "ZZZZZZZZ") then
err_cnt := err_cnt + 1;
end if;
T_Reset <= '0';
T_Read <= '1';
for i in 0 to 31 loop
wait for 20 ns;
if T_Address < 15 then
assert (T_Data_out = i + 1)
report "Something wrong!" severity Error;
if (T_Data_out /= i + 1) then
err_cnt := err_cnt + 1;
end if;
else
assert (T_Data_out = "11111111")
report "Something wrong!" severity Error;
if (T_Data_out /= "11111111") then

err_cnt := err_cnt + 1;
end if;
end if;
T_Address <= T_Address + '1';
end loop;
-- summary of all the tests
if (err_cnt=0) then
assert false
report "Testbench of ROM completed successfully!"
severity note;
else
assert true
report "Something wrong, try again"
severity error;
end if;
wait;
end process;
end TB;
-------------------------------------------------------------configuration CFG_TB of ROM_TB is
for TB
end for;
end CFG_TB;
--------------------------------------------------------------

Anda mungkin juga menyukai