Overview
- A Hardware Description Language (HDL)
- Specifies logic functions only
- Computer-aided tools (CAD) to synthesize optimized gates
- Describe structure & behavior of digital designs for simulation
- Easy to develop, debug, & maintain
- Independent of manufacturers
- Systems thought of as:
- Combinational logic
- Registers
- Finite state machine
Fundamentals
Syntax
- Naming
- Only with characters, digits, underscore
- Case-insensitive
- White-space insensitive
Modules
Entity
- External view of the module
- Input, output, etc.
ENTITY entity_name IS
PORT(
port_name1: port_mode data_type;
port_name2: port_mode data_type;
...
);
END entity_name;
port_mode
in
: signals come into this port; only read within entity
out
: values only updated within the entity; cannot be readinout
: bi-directional, can be read & updated within the entity; can be updated by multiple drivers outside the entitybuffer
: values at output can only be read within the entity; only one driver
data_type
std_logic
std_logic vector
Architecture
- Internal operations of the module
- Function, time, etc.
- Composed of interconnected processes and components, operating concurrently
ARCHITECTURE architecture_name OF entity_name IS
[ signal/variable declarations ] -- optional
BEGIN
[ code ]
END architecture_name;
Library (not core)
- Contains pre-defined data types & conversion functions for the module to use
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
Data Types & Data Objects
Data Types
- Types
- Standard package
bit
bit vector
integer
- ...
ieee.std_logic_1164
std_logic
U Uninitialized W Weak Unknown Z High Impedance - Don’t Care L Weak 0 1 Forcing 1 X Forcing Unknown H Weak 1 0 Forcing 0
std_logic vector
- Standard package
- Tips
- Use of
std_logic
& its vector is recommended for all entities - Operations between different data types are not allowed
- Use of
Data Objects
Has a type & value.
Signal: wires in schematic; concurrent
SIGNAL list_of_names: type [:= initial value];
signal_name <= <expression>;
Variable: does not exist physically
VARIABLE list_of_names: type [:= initial value];
Constant: similar to variable but with fixed value
CONSTANT list_of_names: type [:= initial value];
Assignments & Operations
Assignment Statements
SIGNAL a: STD_LOGIC;
SIGNAL b:
STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL c: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL d:
STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL e: STD_LOGIC_VECTOR(3 DOWNTO 0);
a <= '1'; -- Single-quote '
b <= "1010"; -- Double-quote "
c <= B"0001"; -- Binary base assumed by default (= "0001")
d <= X"AF67"; -- Hexadecimal base
e <= O"723"; -- Octal base
SIGNAL x, y, z : STD_LOGIC;
SIGNAL a, b, c : STD_LOGIC_VECTOR(0 TO 7);
x <= y AND z;
a <= b OR c;
Precedence of Operators
Design Styles
Structural Modeling | Dataflow Modeling | Behavioral Modeling | |
---|---|---|---|
Level of abstraction | low | intermediate | |
Description | Components & their interconnections | Function & flow of data | Overall behavior |
Suitable for | Design naturally composed of sub-blocks | Logic presented by a sequence of boolean equations; gate networks, combinational logic | Complex system; both combinational & sequential logic blocks |
Structural Modeling
- Component declaration
- Declare interface of components (sub-modules)
COMPONENT
- Component instantiation
- Specify interconnection between sub-modules
PORT MAT
- Signal declaration
ARCHITECTURE structural OF xor3_gate IS
COMPONENT xor2
PORT(
I1: IN STD_LOGIC;
I2: IN STD_LOGIC;
Y : OUT STD_LOGIC);
END COMPONENT;
SIGNAL U1_OUT: STD_LOGIC;
BEGIN
U1: xor2 PORT MAP (I1 => A, I2 => B, Y => U1_OUT);
U2: xor2 PORT MAP (I1 => U1_OUT, I2 => C, Y => Result);
END structural;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY xor2 IS
PORT(
I1: IN STD_LOGIC;
I2: IN STD_LOGIC;
Y : OUT STD_LOGIC);
END xor2;
ARCHITECTURE dataflow OF xor2 IS
BEGIN
Y <= I1 xor I2;
END dataflow;
Dataflow Modeling
- Concurrent signal assignments
- Event-triggered
- Conditional signal assignments
WHEN-ELSE
ARCHITECTURE dataflow OF xor3_gate IS
SIGNAL U1_OUT: STD_LOGIC;
BEGIN
U1_OUT <= A XOR B;
Result <= U1_OUT XOR C;
END dataflow;
Behavioral Modeling
- Basic block for sequential modeling:
PROCESS
- Used to describe sequential circuits with memory
- Sensitivity list: cause execution if value of the signals change
[process_name:] PROCESS [(a sensitivity list)] [WAIT statement]
-- ONE AND ONLY ONE OF ABOVE TWO IS ALLOWED
BEGIN
[ code ]
END PROCESS process_name;
ARCHITECTURE behavioral OF xor3_gate IS
BEGIN
xor3_behave: PROCESS (A, B, C)
BEGIN
IF ((A XOR B XOR C) = '1') THEN
Result <= '1';
ELSE
Result <= '0';
END IF;
END PROCESS xor3_behave;
END behavioral;
IF-THEN
IF <condition1> THEN
{sequence of statements}
ELSIF <condition2> THEN
{sequence of statements}
.
.
ELSE
{sequence of statements}
END IF;
CASE
CASE {expression} IS
WHEN <condition1> =>
{sequence of statements}
WHEN <condition2> =>
{sequence of statements}
.
.
WHEN OTHERS => -- (optional)
{sequence of statements}
END CASE;
Blocking & Non-Blocking Assignments
- Blocking
- Assignments:
:=
- To variables
- Only exists within a process
- Less direct relationship to the synthesized hardware
- Evaluate sequentially; assigned immediately
- Assignments:
- Non-blocking
- Assignments:
<=
- To signals and I/O ports
- Declared outside a process
- In a clocked process, signal assignments treated as flip-flops (
output <= input
)
- Evaluate sequentially; assigned concurrently
- Only the last assignment matters
- Assignments:
Guidelines
- Synchronous sequential logic
Process (clk)
- Non-blocking assignments
- Simple combinational logic
- Concurrent assignments outside process statements
- Complex combinational logic
Process (all inputs)
- Blocking assignments
Testbench
An entity without ports that has structural architecture.
- Instance of Entity Under Test (EUT)
- Test Pattern Generator
- Response Evaluator
...
BEGIN -- instantiate device under test
dut: sillyfunction PORT MAP (a, b, c, y); -- apply inputs one at a time
PROCESS BEGIN
a <= '0'; b <= '0'; c <= '0'; WAIT FOR 10 ns;
ASSERT y
= '1' REPORT "000 failed";
...
END PROCESS;
END;
Finite State Machine (FSM)
- State:
CASE-WHEN
- Transitions:
IF-THEN
Enumerated Data Types
States must be of enumerated data types. Object storing current state must be signals of enumerated data types.
TYPE type_name IS (identifier list separated by commas);
SIGNAL my_state: state_type;
Feedback for Signals or Variables
- Object types of output used in feedback must be
INOUT
orBUFFER
- Using signals or variables
- Assignments may be made from one to another, provided the types match
- Use variables when passing data within a process
- Use signals to pass data outside a process
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY state_machine IS
PORT(
PB, RESET, Clock: IN STD_LOGIC;
Y: OUT STD_LOGIC);
END state_machine;
ARCHITECTURE behav OF state_machine IS
TYPE STATE_TYPE IS (State0, State1);
SIGNAL State, NextState: STATE_TYPE;
BEGIN
[process]
END ARCHITECTURE behav;
Process (Approach 1)
-- state register
PROCESS (RESET, Clock) BEGIN
IF (RESET = '1') THEN State <= State0;
ELSIF rising_edge(Clock) THEN State <= NextState;
END IF;
END PROCESS;
-- next state logic
PROCESS (all) BEGIN
CASE State IS
WHEN State0 =>
IF (PB = '0') THEN NextState <= State1;
ELSE NextState <= State0;
END IF;
WHEN State1 =>
IF (PB = '0') THEN NextState <= State0;
ELSE NextState <= State1;
END IF;
WHEN others =>
NextState <= State0;
END CASE;
END PROCESS;
-- output logic
Y <= '1' WHEN State = State1 ELSE '0';
Process (Approach 2)
PROCESS (PB, RESET, Clock, State) BEGIN
IF (rising_edge(Clock)) THEN
IF (RESET = '1') THEN -- Reset and initialization
State <= State0;
Y <= '0';
ELSE
-- Define State Transitions in CASE-WHEN Statement
CASE State IS
WHEN State0 =>
IF (PB = '0') THEN
State <= State1;
Y <= '1';
ELSE
State <= State0;
Y <= '0';
END IF;
WHEN State1 =>
IF (PB = '0') THEN
State <= State0;
Y <= '0';
ELSE
State <= State1;
Y <= '1';
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
Counter
Synchronous Counter
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Counter IS
PORT(
Clock, Reset
: IN STD_LOGIC;
Max_count
: IN STD_LOGIC_VECTOR( 7 DOWNTO 0 );
Count: OUT STD_LOGIC_VECTOR( 7 DOWNTO 0 ) );
END Counter;
ARCHITECTURE behav OF Counter IS
SIGNAL internal_count: STD_LOGIC_VECTOR( 7 DOWNTO 0 );
BEGIN
count <= internal_count;
PROCESS ( Reset, Clock ) BEGIN
IF reset = '1' THEN
internal_count <= "00000000";
ELSIF ( clock 'EVENT AND clock = '1' ) THEN
IF UNSIGNED(internal_count) < UNSIGNED(Max_count) THEN
internal_count <= STD_LOGIC_VECTOR(UNSIGNED(internal_count) + 1);
ELSE
internal_count <= "00000000";
END IF;
END IF;
END PROCESS;
END behav;
Type Casting & Conversion
Asynchronous Counter
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY asyn_counter IS
PORT(
clk, reset: IN STD_LOGIC;
count0, count1, count2, count3: INOUT STD_LOGIC);
END asyn_counter;
ARCHITECTURE behav OF asyn_counter IS
BEGIN
PROCESS (reset, clk, count0, count1, count2)
BEGIN
IF reset = '1' THEN
count0 <= '0';
count1 <= '0';
count2 <= '0';
count3 <= '0';
ELSE
IF (rising_edge(clk)) THEN
count0 <= NOT count0;
END IF;
IF (rising_edge(count0)) THEN
count1 <= NOT count1;
END IF;
IF (rising_edge(count1)) THEN
count2 <= NOT count2;
END IF;
IF (rising_edge(count2)) THEN
count3 <= NOT count3;
END IF;
END IF;
END PROCESS;
END behav;
Timing Analysis
Measures the delay of every design path to ensure that the circuit meets all timing constraints (clock frequency, setup and hold times of flip-flops, etc.).
Flip-Flops
TSU
: setup timeTHD
: hold timeTCQ
: clock-to-q propagation delay
FSM
TNS
: propagation time for next-state logicTCLK
: clock periodSetup time constraint:
state_nxt
must be stabilizedTSU
before the next triggering edgeTCLK >= TSU + TCQ + TNS
Control
- Delay signal assignment
output <= input after 10 ns;
- Use
WAIT
statementsWAIT ON x
WAIT UNTIL x = '1'
WAIT FOR 20 ns
WAIT ON x UNTIL x = '1' AND y = '1' FOR 1 us
- Delay signal assignment