Lab #5 Slides - the GMU ECE Department

advertisement
ECE 332
Digital Electronics and Logic Design
Lab
Lab 5
VHDL Design Styles
Testbenches
Concurrent Statements &
Adders
VHDL Design Styles
VHDL Design
Styles
BEHAVIORAL
DATAFLOW
“concurrent”
statements
STRUCTURAL
components and
interconnects
SYTHESIZABLE
NONSYNTHESIZABLE
“sequential” statements
• State machines
• Registers
• Test Benches
• Modeling IP
VHDL subset most suitable for synthesis
ECE 332
George Mason University
XOR3 Example
ECE 332
George Mason University
Entity XOR3 (same for all
architectures)
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY xor3 IS
PORT(
A : IN
B : IN
C : IN
Result
);
END xor3;
ECE 332
STD_LOGIC;
STD_LOGIC;
STD_LOGIC;
: OUT STD_LOGIC
George Mason University
Dataflow Architecture
ARCHITECTURE dataflow OF xor3 IS
SIGNAL U1_out: STD_LOGIC;
BEGIN
U1_out <= A XOR B;
Result <= U1_out XOR C;
END dataflow;
U1_out
ECE 332
George Mason University
Dataflow Description
• Describes how data moves through the system and the various
processing steps.
– Dataflow uses series of concurrent statements to realize logic.
– Dataflow is most useful style when series of Boolean equations can
represent a logic  used to implement simple combinational logic
• Concurrent statements are evaluated at the same time; thus,
the order of these statements doesn’t matter
– This is not true for sequential/behavioral statements
This order…
U1_out <= A XOR B;
Result <= U1_out XOR C;
Is the same as this order…
Result <= U1_out XOR C;
U1_out <= A XOR B;
ECE 332
George Mason University
Structural Architecture
(XOR3 gate)
ARCHITECTURE structural OF xor3 IS
SIGNAL U1_OUT: STD_LOGIC;
COMPONENT xor2 IS
PORT(
I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
Y : OUT STD_LOGIC
);
END COMPONENT;
BEGIN
U1: xor2 PORT MAP ( I1
I2
Y
U2: xor2 PORT MAP ( I1
I2
Y
END structural;
ECE 332
=> A,
=> B,
=> U1_OUT);
=> U1_OUT,
=> C,
=> Result);
A
B
XOR3
Result
C
I1
I2
Y
XOR2
U1_OUT
A
B
C
RESULT
George Mason University
Component and Instantiation
• Named association connectivity
(recommended)
COMPONENT xor2 IS
PORT(
I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
Y : OUT STD_LOGIC
);
END COMPONENT;
BEGIN
U1: xor2 PORT MAP (
I1 => A,
I2 => B,
Y => U1_OUT);
...
COMPONENT PORT NAME
ECE 332
LOCAL WIRE
George Mason University
Component and Instantiation
• Positional association connectivity
(not recommended)
COMPONENT xor2 IS
PORT(
I1 : IN STD_LOGIC;
I2 : IN STD_LOGIC;
Y : OUT STD_LOGIC
);
END COMPONENT;
BEGIN
U1: xor2 PORT MAP (A, B, U1_OUT);
...
ECE 332
George Mason University
Structural Description
• Structural design is the simplest to understand. This style is
the closest to schematic capture and utilizes simple building
blocks to compose logic functions.
• Components are interconnected in a hierarchical manner.
• Structural descriptions may connect simple gates or complex,
abstract components.
• Structural style is useful when expressing a design that is
naturally composed of sub-blocks.
ECE 332
George Mason University
Behavioral Architecture (XOR3 gate)
ARCHITECTURE behavioral OF xor3 IS
BEGIN
PROCESS (A,B,C)
BEGIN
IF ((A XOR B XOR C) = '1') THEN
Result <= '1';
ELSE
Result <= '0';
END IF;
END PROCESS;
END behavioral;
ECE 332
George Mason University
Behavioral Description
• It accurately models what happens on the inputs and
outputs of the black box (no matter what is inside
and how it works).
• This style uses PROCESS statements in VHDL.
• Statements are executed in sequence in a process
statement  order of code matters!
ECE 332
George Mason University
Single Wire Versus Bus
SIGNAL a : STD_LOGIC;
a
1
wire
SIGNAL b : STD_LOGIC_VECTOR(7 downto 0);
b
8
ECE 332
bus
George Mason University
Standard Logic Vectors
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
a:
b:
c:
d:
e:
f:
STD_LOGIC;
STD_LOGIC_VECTOR(3 DOWNTO 0);
STD_LOGIC_VECTOR(3 DOWNTO 0);
STD_LOGIC_VECTOR(7 DOWNTO 0);
STD_LOGIC_VECTOR(15 DOWNTO 0);
STD_LOGIC_VECTOR(8 DOWNTO 0);
……….
a
b
c
d
e
f
<=
<=
<=
<=
<=
<=
ECE 332
'1';
"0000";
B"0000";
"0110_0111";
X"AF67";
O"723";
------
Binary base
Binary base
You can use
Hexadecimal
Octal base
assumed by default
explicitly specified
'_' to increase readability
base
George Mason University
Single versus Double Quote
• Use single quote to hold a single bit signal
– a <= '0', a <='Z'
• Use double quote to hold a multi-bit signal
– b <= "00", b <= "11"
ECE 332
George Mason University
Testbenches
ECE 332
George Mason University
Testbench Block Diagram
Testbench
Processes
Generating
Stimuli
Design Under
Test (DUT)
Observed Outputs
ECE 332
George Mason University
Testbench Defined
• A testbench applies stimuli (drives the inputs) to
the Design Under Test (DUT) and (optionally)
verifies expected outputs.
• The results can be viewed in a waveform window
or written to a file.
• Since a testbench is written in VHDL, it is not
restricted to a single simulation tool (portability).
• The same testbench can be easily adapted to test
different implementations (i.e. different
architectures) of the same design.
ECE 332
George Mason University
Testbench Anatomy
ENTITY tb IS
--TB entity has no ports
END tb;
ARCHITECTURE arch_tb OF tb IS
--Local signals and constants
COMPONENT TestComp -- All Design Under Test component declarations
PORT ( );
END COMPONENT;
----------------------------------------------------BEGIN
DUT:TestComp PORT MAP(
-- Instantiations of DUTs
);
testSequence: PROCESS
-- Input stimuli
END PROCESS;
END arch_tb;
ECE 332
George Mason University
Testbench for XOR3
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY xor3_tb IS
END xor3_tb;
ARCHITECTURE xor3_tb_architecture OF xor3_tb IS
-- Component declaration of the tested unit
COMPONENT xor3
PORT(
A : IN STD_LOGIC;
B : IN STD_LOGIC;
C : IN STD_LOGIC;
Result : OUT STD_LOGIC );
END COMPONENT;
-- Stimulus signals - signals mapped to the ports of tested entity
SIGNAL A, B, C : STD_LOGIC;
SIGNAL test_result : STD_LOGIC;
BEGIN
DUT : xor3
PORT MAP (
A => A,
B => B,
C => C,
Result => test_result);
ECE 332
George Mason University
Testbench for XOR3 (2)
PROCESS
BEGIN
A <= ‘0’; B <= ‘0’;
WAIT FOR 10 ns;
A <= ‘0’; B <= ‘0’;
WAIT FOR 10 ns;
A <= ‘0’; B <= ‘1’;
WAIT FOR 10 ns;
A <= ‘0’; B <= ‘1’;
WAIT FOR 10 ns;
A <= ‘1’; B <= ‘0’;
WAIT FOR 10 ns;
A <= ‘1’; B <= ‘0’;
WAIT FOR 10 ns;
A <= ‘1’; B <= ‘1’;
WAIT FOR 10 ns;
A <= ‘1’; B <= ‘1’;
WAIT;
END PROCESS;
END xor3_tb_architecture;
ECE 332
C <= ‘0’;
C <= ‘1’;
C <= ‘0’;
C <= ‘1’;
C <= ‘0’;
C <= ‘1’;
C <= ‘0’;
C <= ‘1’;
George Mason University
Testbench waveform
ECE 332
George Mason University
Dataflow VHDL
Major instructions
Concurrent statements
•
•
•
•
concurrent signal assignment ()
conditional concurrent signal assignment
(when-else)
selected concurrent signal assignment
(with-select-when)
generate scheme for equations
(for-generate)
Conditional concurrent signal
assignment
When - Else
target_signal <= value1 when condition1 else
value2 when condition2 else
. . .
valueN-1 when conditionN-1 else
valueN;
Value N
Value N-1
0
1
.…
…
0
1
0
1
Value 2
Value 1
Condition N-1
Condition 2
Condition 1
Target Signal
Operators
• Relational operators
=
/=
<
<=
>
>=
• Logic and relational operators precedence
Highest
Lowest
=
and
/=
or
not
<
<=
nand
nor
>
xor
>=
xnor
Priority of Logic and Relational
Operators
compare a = bc
Incorrect
… when a = b and c else …
equivalent to
… when (a = b) and c else …
Correct
… when a = (b and c) else …
Tri-state Buffer – example
ena
LIBRARY ieee;
USE ieee.std_logic_1164.all;
input
output
ENTITY tri_state IS
PORT ( ena:
IN STD_LOGIC;
input: IN STD_LOGIC_VECTOR(7 downto 0);
output: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END tri_state;
ARCHITECTURE tri_state_dataflow OF tri_state IS
BEGIN
output <= input WHEN (ena = '0') ELSE
(OTHERS => 'Z');
END tri_state_dataflow;
OTHERS means all bits not directly specified,
in this case all the bits.
Dataflow VHDL
Major instructions
Concurrent statements
•
•
•
•
concurrent signal assignment ()
conditional concurrent signal assignment
(when-else)
selected concurrent signal assignment
(with-select-when)
generate scheme for equations
(for-generate)
Selected concurrent signal assignment
With –Select-When
with choice_expression select
target_signal <= expression1 when choices_1,
expression2 when choices_2,
. . .
expressionN when choices_N;
expression1
choices_1
expression2
choices_2
target_signal
expressionN
choices_N
choice expression
Allowed formats of choices_k
WHEN value
WHEN value_1 to value_2
WHEN value_1 | value_2 | .... | value N
this means boolean “or”
Allowed formats of choice_k - example
WITH sel SELECT
y <= a WHEN "000",
b WHEN "011" to "110",
c WHEN "001" | "111",
d WHEN OTHERS;
MLU: Block Diagram
MUX_0
A1
A
IN 0
NEG_A
MUX_1
IN 1
MUX_2
Y1
IN 2
IN 3
Y
O U T PU T
S E L1
S E L0
B
B1
MUX_4_1
MUX_3
NEG_B
L1 L0
NEG_Y
MLU: Entity Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY mlu IS
PORT(
NEG_A : IN STD_LOGIC;
NEG_B : IN STD_LOGIC;
NEG_Y : IN STD_LOGIC;
A :
IN STD_LOGIC;
B :
IN STD_LOGIC;
L1 :
IN STD_LOGIC;
L0 :
IN STD_LOGIC;
Y :
OUT STD_LOGIC
);
END mlu;
MLU: Architecture Declarative Section
ARCHITECTURE mlu_dataflow OF mlu IS
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
SIGNAL
A1 : STD_LOGIC;
B1 : STD_LOGIC;
Y1 : STD_LOGIC;
MUX_0 : STD_LOGIC;
MUX_1 : STD_LOGIC;
MUX_2 : STD_LOGIC;
MUX_3 : STD_LOGIC;
L: STD_LOGIC_VECTOR(1 DOWNTO 0);
MLU - Architecture Body
BEGIN
A1<= NOT A WHEN (NEG_A='1') ELSE
A;
B1<= NOT B WHEN (NEG_B='1') ELSE
B;
Y <= NOT Y1 WHEN (NEG_Y='1') ELSE
Y1;
MUX_0
MUX_1
MUX_2
MUX_3
<=
<=
<=
<=
A1
A1
A1
A1
AND B1;
OR
B1;
XOR B1;
XNOR B1;
L <= L1 & L0;
with (L) select
Y1 <= MUX_0 WHEN "00",
MUX_1 WHEN "01",
MUX_2 WHEN "10",
MUX_3 WHEN OTHERS;
END mlu_dataflow;
Data-flow VHDL
Major instructions
Concurrent statements
•
•
•
•
concurrent signal assignment ()
conditional concurrent signal assignment
(when-else)
selected concurrent signal assignment
(with-select-when)
generate scheme for equations
(for-generate)
For Generate Statement
For - Generate
label: FOR identifier IN range GENERATE
BEGIN
{Concurrent Statements}
END GENERATE [label];
PARITY Example
PARITY: Block Diagram
PARITY: Entity Declaration
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY parity IS
PORT(
parity_in
parity_out
);
END parity;
: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
: OUT STD_LOGIC
PARITY: Block Diagram
xor_out(1)
xor_out(2)
xor_out(3)
xor_out(4)
xor_out(5) xor_out(6)
PARITY: Architecture
ARCHITECTURE parity_dataflow OF parity IS
SIGNAL xor_out: std_logic_vector (6 downto 1);
BEGIN
xor_out(1)
xor_out(2)
xor_out(3)
xor_out(4)
xor_out(5)
xor_out(6)
parity_out
<=
<=
<=
<=
<=
<=
<=
parity_in(0) XOR parity_in(1);
xor_out(1) XOR parity_in(2);
xor_out(2) XOR parity_in(3);
xor_out(3) XOR parity_in(4);
xor_out(4) XOR parity_in(5);
xor_out(5) XOR parity_in(6);
xor_out(6) XOR parity_in(7);
END parity_dataflow;
PARITY: Block Diagram (2)
xor_out(0)
xor_out(1)
xor_out(2)
xor_out(3)
xor_out(4)
xor_out(5) xor_out(6)
xor_out(7)
PARITY: Architecture
ARCHITECTURE parity_dataflow OF parity IS
SIGNAL xor_out: STD_LOGIC_VECTOR (7 downto 0);
BEGIN
xor_out(0)
xor_out(1)
xor_out(2)
xor_out(3)
xor_out(4)
xor_out(5)
xor_out(6)
xor_out(7)
parity_out
<=
<=
<=
<=
<=
<=
<=
<=
<=
parity_in(0);
xor_out(0) XOR
xor_out(1) XOR
xor_out(2) XOR
xor_out(3) XOR
xor_out(4) XOR
xor_out(5) XOR
xor_out(6) XOR
xor_out(7);
END parity_dataflow;
parity_in(1);
parity_in(2);
parity_in(3);
parity_in(4);
parity_in(5);
parity_in(6);
parity_in(7);
PARITY: Architecture (2)
ARCHITECTURE parity_dataflow OF parity IS
SIGNAL xor_out: STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
xor_out(0) <= parity_in(0);
G2: FOR i IN 1 TO 7 GENERATE
xor_out(i) <= xor_out(i-1) XOR parity_in(i);
END GENERATE;
parity_out <= xor_out(7);
END parity_dataflow;
Combinational Logic Synthesis
for
Beginners
Simple Rules
For combinational logic,
use only concurrent statements
•
•
•
•
concurrent signal assignment
()
conditional concurrent signal assignment
(when-else)
selected concurrent signal assignment
(with-select-when)
generate scheme for equations
(for-generate)
Simple Rules
• For circuits composed of:
– simple logic operations (logic gates)
– simple arithmetic operations (addition,
subtraction, multiplication)
– shifts/rotations by a constant
• Use
– concurrent signal assignment
()
Simple Rules
• For circuits composed of
– multiplexers
– decoders, encoders
– tri-state buffers
• Use:
– conditional concurrent signal assignment (when-else
)
– selected concurrent signal assignment (with-selectwhen)
Left versus Right Side
Left side
<=
Right side
<= when-else
with-select <=
• Internal signals (defined
in a given architecture)
• Ports of the mode
- out
- inout
- buffer (don’t recommend
using buffer in this class)
Expressions including:
• Internal signals (defined
in a given architecture)
• Ports of the mode
- in
- inout
- buffer
Explicit Component Declaration Tips
• For simple projects put entity .vhd files all
in same directory
• Declare components in main code
• Xilinx will figure out hierarchy
automatically
METHOD #2: Package component
declaration
• Components declared in package
• Actual instantiations and port maps always in
main code
Packages
• Instead of declaring all components can declare
all components in a PACKAGE, and INCLUDE the
package once
– This makes the top-level entity code cleaner
– It also allows that complete package to be used by
another designer
• A package can contain
– Components
– Functions, Procedures
– Types, Constants
Package – example (1)
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
PACKAGE GatesPkg IS
COMPONENT mux2to1
PORT (w0, w1, s
f
END COMPONENT ;
COMPONENT priority
PORT (w
: IN
y
: OUT
z
: OUT
END COMPONENT ;
: IN
STD_LOGIC ;
: OUT
STD_LOGIC ) ;
STD_LOGIC_VECTOR(3 DOWNTO 0) ;
STD_LOGIC_VECTOR(1 DOWNTO 0) ;
STD_LOGIC ) ;
Package – example (2)
COMPONENT dec2to4
PORT (w
: IN
En
: IN
y
: OUT
END COMPONENT ;
STD_LOGIC_VECTOR(1 DOWNTO 0) ;
STD_LOGIC ;
STD_LOGIC_VECTOR(0 TO 3) ) ;
COMPONENT regn
GENERIC ( N : INTEGER := 8 ) ;
PORT (
D
: IN
STD_LOGIC_VECTOR(N-1 DOWNTO 0) ;
Enable, Clock
: IN
STD_LOGIC ;
Q
: OUT
STD_LOGIC_VECTOR(N-1 DOWNTO 0) ) ;
END COMPONENT ;
Package – example (3)
constant
constant
constant
constant
constant
constant
constant
constant
END GatesPkg;
ADDAB : std_logic_vector(3 downto 0) := "0000";
ADDAM : std_logic_vector(3 downto 0) := "0001";
SUBAB : std_logic_vector(3 downto 0) := "0010";
SUBAM : std_logic_vector(3 downto 0) := "0011";
NOTA : std_logic_vector(3 downto 0) := "0100";
NOTB : std_logic_vector(3 downto 0) := "0101";
NOTM : std_logic_vector(3 downto 0) := "0110";
ANDAB : std_logic_vector(3 downto 0) := "0111";
Package usage (1)
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
USE work.GatesPkg.all;
ENTITY priority_resolver1 IS
PORT (r
: IN
STD_LOGIC_VECTOR(5 DOWNTO 0) ;
s
: IN
STD_LOGIC_VECTOR(1 DOWNTO 0) ;
clk
: IN
STD_LOGIC;
en
: IN
STD_LOGIC;
t
: OUT
STD_LOGIC_VECTOR(3 DOWNTO 0) ) ;
END priority_resolver1;
ARCHITECTURE structural OF priority_resolver1 IS
SIGNAL
SIGNAL
SIGNAL
SIGNAL
p :
q :
z :
ena
STD_LOGIC_VECTOR (3 DOWNTO 0) ;
STD_LOGIC_VECTOR (1 DOWNTO 0) ;
STD_LOGIC_VECTOR (3 DOWNTO 0) ;
: STD_LOGIC ;
Package usage (2)
BEGIN
u1: mux2to1 PORT MAP (
w0 => r(0) ,
w1 => r(1),
s => s(0),
f => p(0));
p(1) <= r(2);
p(2) <= r(3);
u2: mux2to1 PORT MAP (
w0 => r(4) ,
w1 => r(5),
s => s(1),
f => p(3));
u3: priority PORT MAP (
w => p,
y => q,
z => ena);
u4: dec2to4 PORT MAP (
w => q,
En => ena,
y => z);
u5: regn GENERIC MAP (
N => 4)
PORT MAP (
D => z ,
Enable => En ,
Clock => Clk,
Q => t );
END structural;
Explicit Component Declaration versus Package
• Explicit component declaration is when you
declare components in main code
– When have only a few component declarations, this is
fine
– When have many component declarations, use
packages for readability
• Packages also help with portability and sharing of
libraries among many users in a company
• Remember, the actual instantiations always take
place in main code
– Only the declarations can be in main code or package
How to add binary numbers
• Consider adding two 1-bit binary numbers x and y
– 0+0 = 0
– 0+1 = 1
x
y
Carry
– 1+0 = 1
0
0
0
– 1+1 = 10
0
0
1
0
1
1
0
0
1
1
0
1
1
• Carry is x AND y
• Sum is x XOR y
• The circuit to compute this is called a half-adder
60
Sum
= s (sum)
c (carry)
x y s c
1 1 0 1
1 0 1 0
0 1 1 0
0 0 0 0
61
A full adder is a circuit that accepts as input thee bits x, y, and c, and produces
as output the binary sum cs of a, b, and c.
c
HA
X
Y
x
y
x
y
c
s (sum)
c (carry)
X
HA
Y
s
S
S
C
C
S
c
C
1
1
1
1
1
0
1
0
0
1
0
1
0
0
0
0
1
1
1
0
0
1
1
0
1
0
1
0
1
0
1
0
1
0
1
1
0
0
0
0
62
The full adder
• The full circuitry of the full adder
c
s
x
y
c
63
Adding bigger binary numbers
• We can use a half-adder and full adders to
compute the sum of two Boolean numbers
1 0
1 1
+1 1
? 0
64
0
0 0
1 0
1 0
Adding bigger binary numbers
• Just chain one half adder and full adders together,
e.g., to add x=x3x2x1x0 and y=y3y2y1y0 we need:
x0
y0
x1
y1
x2
y2
x3
y3
X
Y
HA
s0
S
C
C
FA
s1
S
X
Y
C
C
FA
s2
S
X
Y
C
C
FA
S
X
Y
C
s3
c
65
Download