Key takeaways:
VHDL stands for very high-speed integrated circuit hardware description language. It is a programming language used to model a digital system by dataflow, behavioral and structural style of modeling.
There are the following three basic elements of VHDL:
1. Entity
The Entity is used to specify the input and output ports of the circuit.
An Entity usually has one or more ports that can be inputs (in), outputs (out), input-outputs (inout), or buffer.
An Entity may also include a set of generic values that are used to declare properties of the circuit.
Entity Declaration
You can declare an entity using the following syntax:
Simplified syntax
entity entity_name is
port (
port_1_name : mode data_type;
port_2_name : mode data_type;
.......
Port_n_name : mode data_type
);
end entity_name;
Example:
entiyorgate is
port (
a : in std_logic;
b : in std_logic;
c : out std_logic
);
end orgate;
Using generic
If an entity is generic, then it must be declared before the ports. Generic does not have a mode, so it can only pass information into the entity.
Syntax:
entity entity_name is
generic (
generic_1_name :data_type;
generic_2_name :data_type;
........
generic_n_name :data_type
);
port (
port_1_name : mode data_type;
port_2_name : mode data_type;
........
Port_n_name : mode data_type
);
end entity_name;
Example:
entity Logic_Gates is
generic (Delay : Time := 10ns);
port (
Input1 : in std_logic;
Input2 : in std_logic;
Output : out std_logic
);
end Logic_Gates;
Rules for writing Port name:
- Port name consist of letters, digits, and underscores.
- It always begins with a letter.
- Port name is case insensitive.
Modes of Port
in Input port
out Output port
inout Bidirectional port
buffer Buffered output port
2. Architecture
Architecture is the actual description of the design, which is used to describe how the circuit operates. It can contain both concurrent and sequential statements.
Architecture Declaration
An architecture can be declared using the following syntax:
architecture architecture_name of entity_name is
begin
(concurrent statements )
end architecture_name;
Example:
architecture synthesis of andgate is
begin
c <= a AND b;
end synthesis;
3. Configuration
A configuration defines how the design hierarchy is linked together. It is also used to associate architecture with an entity.
Configuration Declaration
configuration configuration_name of entity_name is
--configuration declarations
for architecture_name
for instance_label :component_name
use entity library_name.entity_name(architecture_name);
end for;
--
end for;
end [configuration] [configuration_name];
Example:
configuration demo_config of even_detector_testbench is
for tb_archi
for uut :even_detector
use entity work.even_detector (sop_archi);
end for;
end for;
end demo_config;
Key Take Aways:
VHDL includes a number of language elements, called objects, that can be used to represent and store data in the system being modeled.
Three type of Modeling Style in VHDL -
• Data Flow Modeling Style.
• Structural Modeling Style.
• BehaviorModeling Style.
Data Flow Modeling Style - Data Flow Modeling Style Shows that how the data signal flows from input to output through the registers
Components. Data Flow Modeling Style works on Concurrent Execution.
Structural Modeling Style - Structural Modeling Style shows the Graphical Representation of modules/ instances / components with their Interconnection.
In Structural Modeling Style we define how components / Registers / Modules are Connected to each other using Nets/ Wires.
Structural Modeling Style is based on Net-List Language. Structural Modeling Style works on Concurrent Execution.
BehaviorModeling Style - BehaviorModeling Style shows that how the system performs according to current input values. In behaviour Modeling, we define that what value we get at the output corresponding to input values. BehaviorModeling Style works on Sequential Execution.
3.3.1 Sequential
Sequential VHDL code is executed line by line.
“when/else” statement, the “if” statement incorporates priority-encoded logic. This means that the expressions of an “if” statement are evaluated successively, with higher priority given to the earlier expressions.
The “if” statement is more general than the “when/else” statement.
When using a process to describe a combinational circuit, we need to include all of the inputs in the sensitivity list.
The “case” statement as the sequential equivalent of the “with/select” statement; however, the “case” statement is more general.
The options of a “case” statement must be mutually exclusive, and all possible values of the control_expression must be included in the set of options.
Key TakeAways:
A sequential circuit uses memory elements, such as registers, to store the internal state of the circuit. The output of a sequential circuit depends on both the inputs to the circuit and the circuit’s internal states.
3.3.2 Behavioural
Example
entity half_adder is
port(a,b: in std_logic);
end half_adder;
architecture behaviour of half_adder is
begin
ha: process(a,b)
begin
ha: process(a,b)
begin
if ‘a’ = 1 then
sum <= not b;
carry_out<= b;
else
sum <=b;
carry_out<=0;
end if;
end process ha;
end behaviour;
The entity declaration is same as dataflow architecture. The architecture consists of single process statement.
The process statement starts with the label ha followed by the keyword process.
Following the keyword process is a list of signal parentheses called sensitivity list. Between the second begin and keyword and the keyword end process is a sequential if statement. This if statement is executed whenever the process executes.
Key takeaways:
The behavioral modeling describes how the circuit should behave.
3.3.3 Structural
This approach allows each design entity to be independently designed and verified before being used in higher level description.
entity half_adder is
Port ( a, b: in std _logic);
Sum, carry_out : out std_logic);
end half_adder;
Architecture structure of half_adder is
component xor gate
port(i1,i2:in std_logic);
end component;
component and_gate
port (i1,i2:in std_logic)
o1:out std_logic);
end component;
begin
u1; xor_gate port map(i1 =>a, i2 =>b,o1 => sum);
u2: and_gate port map(i1 =>a, i2 => b, o1 =>carry_out);
= > u1: xor_gate port map(a,b,sum);
= > u1: and_gate port map(a,b,carry_out);
end structure
Key takeaways:
The VHDL structural style describes the interconnection of components within an architecture.
3.3.4 Data Flow Modeling
A dataflow description directly implies corresponding gate level implementation.
Dataflow descriptions consists of one or more concurrent signal assignments.
entity half_adder is
port(a,b: in std_logic);
sum, carry_out: out std_logic);
end half_adder;
architecture dataflow of half_adder is
begin
sum <= a xor b;
carry_out < =a and b ;
end dataflow;
The first assignment statement describes how input data flows from inputs a and b through an XOR function to create sum.
The second assignment statement describes hoe input data flows through an AND function to produce carry_out.
The concurrent signal assignment statements in this descriptions directly imply a hard ware implementation
Key Take Aways:
Dataflow modelling describes the architecture of the entity under design without describing its components in terms of flow of data from input towards output.
Architecture body
Simplified syntax
architecture arch_name of entity_name is declarations;
begin
concurrent statement;
concurrent statement;
concurrent statement;
………..
end arch_name;
syntax:
signal_name<= projected_waveform;
Example
y <= a+b+1 after 10ns;
- status <= ‘1’
- even <=(p1 and p2) or (p3 and p4);
- arith_out< = a + b+c -1 ;
Conditional assignment statement
Syntax
signal_name< = value_expr-1 when boolean_expr_1 else
value-expr_2 when boolean_expr_2 else
value_expr_3 when Boolean_expr_3 else
…….
value_expr_n
Example 4:1 mux
library ieee;
use ieee.std_logic_1164.all;
entity mux4 is
port(
a,b,c,d: in std_logic_vector(7 downto 0);
a: in std_logic_vector(1 downto 0);
x: out std_logic_vector(7 downto 0)
);
end mux 4;
architecture cond-arch of mux4 is
begin
x<=a when (a=”00”) else
b when (a=”01”) else
c when(a=”10”) else
d;
end cond_arch;
Sequential statements
Syntax
Signal_name<= value_expression;
Syntax is identical to the simple concurrent signal assignment.
Eg
process(a,b,c,d)
begin y<= a or c;
y<= a and b;
y<= c and d;
end process;
It is same as
process(a,b,c,d)
begin
y<= c and d;
end process;
IF statement
Syntax
if boolean_expr-1 then
sequential statements;
elsif Boolean_expr_2 then
sequential statements ;
elsif Boolean_expr_3 then
sequential statements ;
…………
else
sequential_statements;
end if;
Example 4-to-1 mux
architecture if_arch of mux4 is
begin
process (a,b,c,d,s)
begin
if(s=”00”) then
x<=a;
elsif (s=”01”) then
x<=b;
elsif (s=”10”) then
x<=c;
else
x<=d;
end if;
end process;
end if-arch;
Key Take Aways:
The primary concurrent statement in VHDL is a process statement. ... Within a process, sequential statements specify the step-by-step behaviour of the process
The first step in the design process is to input your design into a machine-readable format. To do this use a Computer Aided Design (CAD) tool. In CMPE 480 Xilinx Foundation is used. A typical CAD tool supports many design entry methods, such as a schematic capture, HDL entry (VHDL/Verilog) or a component netlist
STEP 2 – Functional Simulation
Once a design has been captured, the next step is to simulate it. This is done to ensure that the design will meet the requirements of its specification. The first type of simulation that is performed is a Functional Simulation. This is also referred to as a Behavioral simulation in Xilinx Foundation.
A behavioral simulation is used to verify the logical behaviour of the circuit. It is important to realize that some statements in VHDL are not synthesizable and therefore included for simulation purposes only.
Consider the following example: Z <= A and B after 2ns; The after statement is an arbitrary delay that cannot be realized in hardware, thus it is not synthesizable. It is included to model expected delays in a behavioral simulation.
STEP 3 - Synthesis
During synthesis, the CAD tool will interpret your VHDL design information and infer standard building blocks to implement your design (registers, multiplexers, lookup tables, adders, etc.). Subtle differences in your VHDL description can result in different hardware being inferred at this stage. Different hardware inferences will result in variances in system performance.
STEP 4 – Implementation
The Xilinx implementation process takes your design through to TRANSLATE, MAP, and PLACE AND ROUTE sub-processes. The TRANSLATE process convert the netlist generated from the synthesis process, into a form specific to the target device. The MAP process translates the standard building blocks into the specific resources available in the target hardware. The PLACE & ROUTE process picks up where the MAP process leaves off by allocating specific resources (placing) and interconnecting (routing) the placed design. At the end of this process you can perform a post-place and route simulation. This is the most accurate simulation available through the Xilinx toolset. It will give you an indication of what to expect of your design once it is actually implemented.
STEP 5 – Device Configuration
After the design has been verified, a binary hardware configuration file is generated (bitstream). This file is then downloaded into the FPGA via the JTAG interface.
Key takeaways:
Various steps are involved to obtain the device configuration.
A data objects hold the value of specified type, which is created by means of an object declaration.
In the following example signal is one of the type of data object.
e.g. signal sl: std- logic
Type of data objects:
(i) Constant
(ii) File
(iii) Variable
(iv) Signals
Constant
A constant is an object whose value may never be changed during the simulation process. The constant declaration contains one or more identifiers. The Syntax of constant is,
constant constant_name : type := value;
Example :
constant width: integer:= 8;
constant x: std_logic:= 16;
constant delay: time:= 10ns;
File
A sequence of value called file. The value can be read or write to file using read procedures and write procedures respectively. The Syntax of file is :
file identifier :subtype_indication [ file_open_information ];
Example :
type IntegerFile is file of INTEGER;
file F1: IntegerFile;
Variables:
A variable is an object with single current value. A signal value of given type having different values assigned to different times called as variable. The Syntax of variable is,:
variable variable_name : type;
variable variable_name : type := initial_value;
Example :
variable A,B: bit;
variable sum :std_logic_vector(7 downto 0);
Signal
Signal is an object with a past history of values. The term signal refers to objects declared by signal declarations and port declarations. The Syntax of signal is :
signal signal_name : type;
signal signal_name : type := initial_value;
Example 1 :
signal A,B: std_logic;
signal DELAY: time:=10ns;
Example 2 :
entity testing is
port (A,B: in Std_Logic;
C: out Std_logic);
end entity VK;
architecture Ex_testing of testing is
signal Temp :Std_Logic;
begin
Temp<= A xorB;
C<= not Temp;
end architecture Ex_testing;
Data Types:
VHDL has a set of standard data types (predefined / built-in).
Some of the predefined data types in VHDL are: BIT, BOOLEAN and INTEGER.
The STD_LOGIC and STD_LOGIC_VECTOR data types are not built-in VHDL data types but are defined in the standard logic 1164 package of the IEEE library. We therefore need to include this library in our VHDL code and specify that the STD_LOGIC_1164 package must be used in order to use the STD_LOGIC data type:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
BIT
The BIT data type that has value 0 or 1. When assigning a value of 0 or 1 to a BIT in VHDL code, the 0 or 1 must be enclosed in single quotes: '0' or '1'.
BIT_VECTOR
The BIT_VECTOR data type is the vector version of the BIT type consisting of two or more bits. Each bit in a BIT_VECTOR can only have the value 0 or 1.
When assigning a value to a BIT_VECTOR, the value must be enclosed in double quotes, e.g. "1011" and the number of bits in the value must match the size of the BIT_VECTOR.
STD_LOGIC
The STD_LOGIC data type can have the value X, 0, 1 or Z. There are other values that this data type can have, but the other values are not synthesizable – i.e. they can not be used in VHDL code that will be implemented on a CPLD or FPGA.
These values have the following meanings:
When assigning a value to a STD_LOGIC data type, the value must be enclosed in single quotes: 'X', '0', '1' or 'Z'.
STD_LOGIC_VECTOR
The vector version of the STD_LOGIC data type. Each bit in the set of bits that make up the vector can have the value X, 0, 1 or Z.
When assigning a value to a STD_LOGIC_VECTOR type, the value must be enclosed in double quotes, e.g. "1010", "ZZZZ" or "ZZ001". The number of bits in the value must match the size of the STD_LOGIC_VECTOR.
Key Take aways:
A data object holds a value of a specified type, created by using object declaration
Logical Operators
NOT, AND, NAND, OR, NOR, XOR and XNOR.
Arithmetic Operators
Comparison Operators
Shift Operators
Logical Operators
Logical operators can operate on:
BIT and BIT_VECTOR
STD_LOGIC and STD_LOGIC_VECTOR
(also on other data types: STD_ULOGIC and STD_ULOGIC_VECTOR)
Arithmetic Operators
The STD_LOGIC_VECTOR data type can be used in addition and subtraction operations (+ and -) if the STD_LOGIC_SIGNED or the STD_LOGIC_UNSIGNED package of the IEEE library is used.
(Otherwise the arithmetic operators can only be used with INTEGER, SIGNED and UNSIGNED data types)
Comparison Operators
BIT and BIT_VECTOR
STD_LOGIC and STD_LOGIC_VECTOR
(also on STD_ULOGIC, STD_ULOGIC_VECTOR, INTEGER, SIGNED and UNSIGNED)
Shift Operators
Shift operators can only be used on BIT_VECTOR data types.
Key takeaways:
The main purpose of any code is to implement some kind of logic. Having a variety of operators helps in that endeavor.
The sequential statements that appear in a process or subprogram are presented: sequential signal assignment, variable assignment, if statement, case statement, loop statements (loop, while loop, for loop, next, exit), and the sequential assert statement. Besides these statements, other sequential statements are the procedure call statement and the return statement from a procedure or function.
A process may appear anywhere in an architecture body. The basic structure of process declaration is the following:
[name:] process [(sensitivity list)]
[ type_declarations]
[constant_declarations]
[variable_declarations]
[subprogram_declarations]
begin
sequential_statements
end process [name];
The process declaration is contained between the keywords process and end process. A process may be assigned an optional name for simpler identification of the process in the source code. The name is an identifier and must be followed by the ':' character. This name is also useful for simulation, for example, to set a breakpoint in the simulation execution. The name may be repeated at the end of the declaration, after the keywords end process.
Key takeaways:
The sequential domain is represented by a process or subprogram that contains sequential statements. These statements are exe- cuted in the order in which they appear within the process or subprogram, as in programming languages.
With Verilog and VHDL, engineers can represent the desired functionality as a software program. Then the model is simulated to confirm the design will work as intended. Any problems can be corrected in the model, and simulation will verify the correction.
Sample VHDL Code
reg1: process (rst, clk)
begin
if rst = '1' then
q_reg<= (others => '0');
q_i<= (others => '0');
elsifrising_edge(clk) then
if s_l = '1' then
q_i(0) <= q_i(7);
loop1: for i in 6 downto 0 loop
q_i(i + 1) <= q_i(i);
end loop loop1;
q_reg<= y;
else
q_i<= q_reg;
q_reg<= y;
end if;
end if;
end process reg1;
Verilog is weakly typed and more concise with efficient notation. It is deterministic. All data types are predefined in Verilog and each has a bit-level representation. Syntax is C-like.
Sample Verilog Code
always @(posedge CLK or posedge RST)
begin
if (RST) begin
q_reg = 0;
Q = 0;
end else if (S_L) begin
Q[7:0] = {Q[6:0],Q[7]};
q_reg = Y;
end else begin
Q = q_reg;
q_reg = Y;
end
end
SystemVerilog includes a set of extensions to the Verilog HDL to help engineers design and verify larger and more complex designs
Sample SystemVerilog Code
property p_push_error;
@ (posedgeclk)
not (b_if.push&&b_if.full&& !b_if.pop);
endproperty :p_push_error
ap_push_error_1 : assert property (p_push_error);
property p_pop_error;
@ (posedgeclk)
not (b_if.pop&&b_if.empty);
endproperty :p_pop_error
ap_pop_error_1 : assert property (p_pop_error);
always_ff @ (posedgeclk) begin
b_if.error<= (b_if.pop&&b_if.empty) || (b_if.push&&b_if.full&& !b_if.pop);
Key takeaways:
Because of its structure, VDHL catches most errors early in the design process. Verilog, on the other hand, enables engineers to quickly write models. SystemVerilog attempts to capture the best features of both, and includes features of HVLs to support testbench development and formal verification techniques.
VHDL test bench (TB) is a piece of VHDL code, which purpose is to verify the functional correctness of HDL model.
The main objectives of TB is to:
– Instantiate the design under test (DUT)
– Generate stimulus waveforms for DUT
– Generate reference outputs and compare them with the outputs of DUT
– Automatically provide a pass or fail indication
Test Bench Structures
• TB should be reusable without difficult modifications.
• The structure of the TB should be simple enough so that other people understand its behaviour.
• Good test bench propagates all the generics and constants into DUT.
Testing a design by simulation
• Use a test bench model
– an architecture body that includes an instance of the design under test
– applies sequences of test values to inputs
– monitors values on output signals
• either using simulator
• or with a process that verifies correct operation
For example ,
entity test_bench is
end entity test_bench;
architecture test_reg4 of test_bench is
signal d0, d1, d2, d3, en, clk, q0, q1, q2, q3 : bit;
begin
dut : entity work.reg4(behav)
port map ( d0, d1, d2, d3, en, clk, q0, q1, q2, q3 );
stimulus : process is
begin
d0 <= ’1’; d1 <= ’1’; d2 <= ’1’; d3 <= ’1’; wait for 20 ns;
en<= ’0’; clk<= ’0’; wait for 20 ns;
en<= ’1’; wait for 20 ns;
clk<= ’1’; wait for 20 ns;
d0 <= ’0’; d1 <= ’0’; d2 <= ’0’; d3 <= ’0’; wait for 20 ns;
en<= ’0’; wait for 20 ns;
…
wait;
end process stimulus;
end architecture test_reg4;
Key Take Away:
VHDL test bench (TB) is a piece of VHDL code, which purpose is to verify the functional correctness of HDL model.
References:
Fundamentals of Modern VLSI Devices Book by Tak H. Ning and Yuan Taur
Introduction to VLSI systems Book by Carver Mead
VLSI physical design automation Textbook by Sadiq Sait
Cmos Digital Integrated Circuits Book by Sung-Mo Kang and Yusuf Leblebici