VHDL
1
VHDL Digital Systems 1 The designers guide to VHDL Peter J. - - PowerPoint PPT Presentation
VHDL Digital Systems 1 The designers guide to VHDL Peter J. Andersen Morgan Kaufman Publisher Bring laptop with installed Xilinx 2 HDL Introduction VHDL (DoD project) and Verilog (private project) High level languages for
1
2
«The designer’s guide to VHDL» Peter J. Andersen Morgan Kaufman Publisher Bring laptop with installed Xilinx
complex systems design etc.)
Integrated Circuits) design and test – (Processors are ASIC)
language will be presented, sometimes with some inaccuracies for a simplified FPGA design
modifications required by the specific context
4
The FPGA e HDL modern technologies allow to reduce dramatically the time to market: the complete prototype development can be implemented on a computer.
5
The production cost of a FPGA design can be more expensive of an ASIC
VHDL program used for the FPGA prototype is always possible. A FPGA can be field reconfigured (a new program) in case of bugs or for improved functionality
Signals propagation uses wires and is NOT istantaneous because of the physical characteristics of conductors/components (parasite phenomena, gates delays, etc)
6
In order to describe the signal z propagation with a high level language (i.e. C) we could write a <=x;
z<=a and c; -- assign z With these two statements it seems that x=a e z=ac occur at the same time!!!! False!! z will change after the NAND delay
Z C
Consider for instance the following logical network:
be executed one after the other with the same sequence of the program. But physically the electric signal x propagates concurrently towards a and b (NOT towards a and then towards c as the previous C program would implicate). Real network: different wires lenghts imply that a and b are not simultaneous. In the FPGA design systems the delays depend on the circuit technology and how the signals are «routed» within the integrated circuit
7
propagation delay (never zero !!) and the gates delay
an instruction set which will be sequentially executed (sequential programming paradigm)..
8
Timing The capacity of modelling the propagation times within a circuit Concurrency The possibility of “executing” several operations in parallel, typical of the hardware behaviour
react to «events» and produce in turn «events»; the «events» are the signal transitions. This implies that all blocks whose behaviour depends on those events are parallel evaluated according to the new signals values. In VHDL the statements are parallel (simultaneously) executed as is the case for the real systems (all blocks of a system evolve in parallel and not serially)
is the blocks evaluation order the overall status of the system once all events have been handled must be always the same).
must be independent from the sequence of the statements execution all statements can be executed in parallel without any statement waiting for the end of another
Let’s analyse the following combinatorial ciruit and let’s suppose that the delays (gates, wires etc) are identical. The code which describes the behaviour of this circuit must produce a result (the ouptut of each gate) which depends on the input only and not on the order of the AND and OR evaluation
T1 <= A and B; T2 <= C and D; TN <= E and F; U <= T1 or T2 or T3; U <= T1 or T2 or T3; T1 <= A and B; T2 <= C and D; TN <= E and F;
Equivalent The statements which describe the blocks can be coded according to the VHDL paradigm (<= indicates the signal modification):
9
In VHDL entities (objects) are available. Each one of them has a data type and a value (strongly typified language). Now we analyse how all these entities must be declared and how a value can be assigned to them
10
Entities which cannot change their values. Useful to make the code well readable Careful: always use the symbol «;» as an end of a statement constant delay: time := 13 ns;
11
A «constant» is always defined within an «architecture» (see later) Type Value
Assignment of a value Careful: VHDL is extremely rigorous for the syntax
12
Objects which can modify their values during the simulation. They can be declared only within a process (see later) and are local to the process (the initial value is optional) variable name: type [:= initial_value]; Example variable IJK: integer := 10; Usage example(IJK variabile) – [N.B «for» clause can be used only within a process (see later)] for IJK in 7 downto 3 loop – execute 5 times (values 7 to 3 included) !!! Double «-» is a comment X(IJK) := Y(IJK ); -- X and Y are variables vectors [arrays (see later)] end loop; -- all loop statements are executed concurrently NB a variable has no hardware meaning and is used only to define the execution flow of the
(NOT signals !!!) NB variables can be declared or have values to be assigned only within a process – see
later – and are local to that block
The assignment is performed through the operator := and has immediate effect Examples z:= y; -- z and y variables (not signals!!)
assignment
Physical entities (signals, actually…) which can modify their values during the simulation (an initial value is optional) with a delay depending either from the technology or from a synchronism signal (typically the clock signal – see later the synchronous circuits - process). A signal is defined within an «architecture» - (see later). signal name: type [:= initial_value]; Examples signal A : std_logic := ‘1’; -- N.B. single apex signal B : std_logic := ‘0’; signal C : std_logic := ‘1’; C <= A and B;
13
after a delay depending on the technology and the nature of the circuit – sequential, combinatorial etc.). std_logic is a technology type of the signal which defines its electrical
Important!
In the VHDL language (Standard Package) the following data types are also defined:
14
N.B. The use of std_logic is unavoidable in Xilinx if a simulation must be executed when all networks and their interconnections are mapped
delays of the circuit
A std_logic signal can have logical values ‘0’ and ‘1’ It is possible to define vectors of signal signal vector_example : std_logic_vector (7 downto 0) := “ 01001001“; (definition) (name) (type) (size) (initial value – double apex) For binary values of a single bit the single apex «’» symbol is used while for binary configurations of 2
15
Examples a <= ‘1’; vector_example <= “10011100”; vector_example <= x“9C” -– (hexadecimal notation) for IJK in 4 to 10 loop -- executes 7 times (values 4 and 10 included) !!! (IJK is an integer variable) A(IJK) <= B(IJK) ; -- A and B are signal vectors (arrays) end loop; -- all loop statements are executed at the same time Important! Double apex!!
Integer range depends on the platform and is [-231-1, +231-1]. Example constant data_bus_width: integer := 32; -- integer constant of decimal value 32
Positive are integer numbers from 1 to 231-1.
16
To the time type an attribute is associated (ms, ns, ps, etc). In Xilinx it can be used only for the simulations (testbench programs – see later) . Esempio constant delay: time:= 5 ns; (definition) (name) (type) (value)
Using indexes the single elements of an array can be accessed. For instance y(2) <= a(1) To a set of contiguous elements a value can be assigned y <= “01”; y(4 downto 2) <= “101”
1
17
Chain operator &
& operator (concatenation) allows to define bit strings Example: signal y <= “101” & “011” & ‘1’; -- the result is 1010111 – Comments in Xilinx are green A:=“101”; -- constant or variable B:= “011”; C:= ‘1’; y <= A&B&C; -- would have produced the same result And: and Or:
Not: not Nand: nand Nor: nor Xor: xor Xnor: xnor
y <= not a; z <= a and b; w <= x or (not y); k(8 downto 5) <= h(10 downto 7);
Logical operators in VHDL (signals and variables)
18
Chaining is NOT a logical action with physical meaning but a tool to express more clearly an expression by underlining its components
Compilation Design Entry Simulation - testbench Simulated Behaviour OK? SI
FPGA Mapping
19
library IEEE; use IEEE.std_logic_1164.all; -- necessary when std_logic is used
Libraries declarations
architecture architecture_entity of name_entity is begin <processing statements> end architecture_entity ;
Architectural specification Typical VHDL code structure (design - not testbench)
20
entity name_entity is Port (signal_name : direction type); end name_entity;
A B S z
Interface specification Entity
entity example is port ( sign_1 : inout std_logic:='0'; ---- notice inout sign_2 : in std_logic_vector (7 downto 0) := “01001001“; enable : in std_logic:='0'; ck : in std_logic:='0'; z : out std_logic:='0‘ -- last element - no semicomma ); end example; Port allows to specify:
21
«Entity»: defines the network «externally visible» input and output signals
the architecture
architecture Behavioural of Example is begin <processing statements> end Behavioural ;
Within the architecture section the network logic (behaviour) is specified Within the architecture (in the <architecture declarations>) it is possible to define objects. They are typically signals (signals internal to the architecture in addition to those externally defined in the entity) which can be used (scope) only between the clauses «architecture» and «end»)
22
signal T1,T0 : std_logic; signal T3,T4 : std_logic; It must be noticed that the signal declaration has a form different from that implicit in Port where the direction is mandatory. The section within which the network logic is defined is between begin and end.
port ( a : in std_logic_vector (3 downto 0); y :
(1 downto 0));
A[3..0] Y[1..0]
LSB MSB
ENTITY
23
port ( a3,a2,a1,a0 : in std_logic; y1,y0 :
a3 a2 a1 a0 y1 y0 ENTITY
Notice the position of the character ; and of the parenthesis
library ieee; use ieee.std_logic_1164.all;
entity file_vhdl is port ( x : in std_logic; y : in std_logic; z : out std_logic); end file_vhdl;
architecture behavioural of file_vhdl is begin z <= x and y; end behavioural;
Architecture: network behaviour
24
Interface specification (black box - entity) Hello_vhdl
x y z
Blue colour: “reserved words”
Network input/output signals Network internal structure
25
26
Component
«component» (as is the case wih the integrated circuits)
dummy input and output variables are defined in the PORT and the links to the higher level circuit are defined in the PORT MAP -- See next slide
A testbench is a specific VHDL code (a program for the simulation of the circuit under test) which allows the analysis of the behaviour of the circuit upon specific input stimuli. 27
Stimuli
Testbench E N T I T Y
Out signals Simulation N.B. The network under test is istantiated with the command “component”. The circuit is in fact a component of the test system. In the FPGA design programs commands “after” and “wait” can be used only for the testbench stimuli while the system (entity) delays depend only on the technology of the chosen FPGA and on the placement and route. In Xilinx when a new VHDL file is inserted the designer must declare whether the «new source» is a source or a testbench file Istantiated as a“component”
E N T I T Y
Circuit under test A testbench can be schematized as follows
VHDL allows to define the testbench stimuli delays through the command wait N.B. The statements blocks of a VHDL testbench – differently from the circuit under test – are executed sequentially - that is all the statements between two wait are executed in parallel while those after a wait are executed once the wait period ended wait for 15 ns; statement 1; -- all these statement 2; -- statements
statement n; -- in parallel wait for 50 ns; -- here the test program stops for 50 ns
28
N.B. the wait command in Xilinx can be used only in the testbenches
29
entity testbench_of_hello_vhdl is -- n.b. in the testbenches no port end testbench_of_hello_vhdl; architecture behavior of testbench_di_hello_vhdl is
component hello_vhdl port (x : in std_logic; -- input and output signals declaration y : in std_logic
z : out std_logic );
end component;
signal x_test : std_logic ; -- testbench internal signals declaration signal y_test : std_logic ; -- part of the architecture
signal z_test : std_logic;
«HELLO» testbench
Component testbench architecture internal signals
begin
uut: hello_vhdl port map ( x => x_test, -- corrispondence between the y => y_test, -- testbench signals and the z => z_test ); -
stim_proc: process begin wait for 5 ns; -- wait 5 nanoseconds
x_test<='1'; y_test<='1'; wait for 10 ns; x_test<='1'; y_test<='0'; wait for 10 ns; wait; -- wait forever – test end end process; end;
30 Port map Correspondence
and the testbench signals (x_test, y_test, z_test.) N.B.The internal signals can have the same name used in the circuit under test (easier to remember)
Process !
Red signal: undefined value AND gate delay Time set
N.B. In the testbench the command process is used which will be better explained later
31 library ieee; use ieee.std_logic_1164.ALL; entity xyz is port ( A : in std_logic; B : in std_logic; C : in std_logic; D : in std_logic; F : in std_logic; O : out std_logic); end xyz; architecture BEHAVIORAL of xyz is O <= (A and B ) or (B and (not(C))) or (D and F) ; end BEHAVIORAL; Derive the truth table Design and simulate in Xilinx Vivado !!!!
to remember that a signal is NOT immediately updated BUT after a delay which depends on the FPGA technology
32
I := I+1 -- immediate a <= b -- after the intrinsic network delay
is to assign a value to a signal and then test immediately the value of that signal. The test provides an incorrect result since it is executed at the same time of the assignment
(in case of synchronous networks one clock period – see later)
<signal_name> <= <signal/value> when <condition-1> else <signal/value> when <condition-2> else . . . . . . . . <signal/value> when <condition-n> else <signal/value>;
multiple conditions are verified the first value is assigned to the signal_name which satisfies the when condition
33
entity and2 is port (a, b : in std_logic; y :
std_logic); end and2; architecture architecture_and2 of and2 is begin y<='1' when (a='1' and b='1') else '0'; end architecture_and2; Example (and2)
2 AND2
VHDL core for modelling a two-inputs AND using when-else
34
Example (and2)
2 AND2
entity and2whenelse1 is port (a : in std_logic_vector (1 downto 0); -- vector notation y : out std_logic); end and2whenelse1; architecture arch_and2whenelse1 of and2whenelse1 is begin y <= ‘0' when a(0)=‘0’ else ‘0' when a(1)=‘0’ else ‘1’; end arch_and2whenelse1; Alternative VHDL code using when-else again
35
Example (and2)
2 AND2
entity and2whenelse2 is port (a : in std_logic_vector (1 downto 0); y : out std_logic); end and2whenelse2; architecture arch_and2whenelse2 of and2whenelse2 is
begin y <= ‘0' when a(0)=‘0’ else ‘1' when a(1)=‘1’ else -- a(0) already verified not 0 ‘0’; end arch_and2whenelse2; Another when-else alternative
36
Example (and2)
2 AND2
entity and2whenelse3 is port (a : in std_logic_vector (1 downto 0); y : out std_logic); end and2whenelse3; architecture arch_and2whenelse3 of and2whenelse3 is begin y <= ‘1' when a=“11” else -- notice the double apex:
‘0’; -- two values are assigned end arch_and2whenelse3; Or…….
37
Important!
with <expression> select <signal_name> <= <signal/value> when <condition1>, <signal/value> when <condition2>, . . . . . . . . <signal/value> when others;
be mutually exclusive
38
Typically a signal or a vector
(otherwise an illicit multiple assignment could take place with unpredictable result)
entity and2with is port (a : in std_logic_vector (1 downto 0); y : out std_logic); end and2with; architecture arch_and2with of and2with is begin with a select y <= ‘1' when "11", ‘0' when “00”, ‘0' when “01”, ‘0' when “10”; end arch_and2with; Example (and2)
2 AND2
AND2 VHDL using with-select-when
39
entity and2withothers is port (a : in std_logic_vector (1 downto 0); y : out std_logic); end and2withothers; architecture arch_and2withothers of and2withothers is begin with a select y <= ‘1' when ”11", ‘0' when others; end arch_and2withothers; Example (and2)
2 AND2
Or…
40
These operators can be used for operands of the same type and produce a BOOLEAN value (TRUE
Equal: = Different: /= Less than: < Less than or equal: <= Greater than: > Greater than or equal: >= Example: a_boolean <= op_1 <= operand_2; -- (a true when op1 > op2 or op1=op2) b_boolean <= op_1 /= operand_2; -- (b true if op1 different from op2)
41
Assignments Less than or equal
Careful ! It looks like the signals assignment but in this case these are variables . All depends on the context
42 fe = A + !BC using the algebra theorems (see next slide) (If fe = 1 the segment is off) A,B,C,D negative true (L)
45
(for instance a microprocessor)
circuit is defined.
the case for the signals assignment (already seen in the testbench)
possibily provokes a change in the internal expressions of the process. If none of these events takes place the process keeps inactive. In Xilinx sensitivity list all input signals (no matter if they act or not) must be in any case indicated
triggers all the activities of the process. (The only exception is the testbench which has no sensitivity list). In the following example a new value of a takes place ONLY if there are events for b or c that is if b or c change. In the synchronous sequential networks a typical event is the clock (see later) compute_xor: process (b,c) begin a<=b xor c; end process;
46
signal changes is value). For instance b’event means that either b changes from 0 to 1 or from 1 to 0). Event attributes is typically used to indicate a signal edge. For instance a positive edge of signal b can be detected with: (b’event) and (b= ‘1’) multiple condition on signal b, true if b is changed and b is become 1 (a transition from 0 to 1)
A <= B‘last_value There are many other attributes here not presented
With others it is possible to set the content of some or of all elements of a vector not otherwise explicitly set. For instance vector <= (0=>'1', others =>'0'); (the right arrow means always assignment). This statement set to 1 the LSbit and all others to 0 (How many ? With others it is not necessary to know this information).
In VHDL there are also array attributes. For instance for a vector VECTOR: std_logic_vector(4 downto 0); VECTOR’length provides value 5 (like «sizeof» in C)
47
Conversion functions In the IEEE libraries some functions are defined to convert values. For instance in the IEEE.std_logic_arith a function is defined to convert from integer to STD_LOGIC_VECTOR (and many others) <slv_sig> = CONV_STD_LOGIC_VECTOR(<int_sig>, <int_size>); For instance if half_word is a signal type STD_LOGIC_VECTOR(15 downto 0) and value is type integer, the conversion of value to a STD_LOGIC_VECTOR can be achieved through: half_word = CONV_STD_LOGIC_VECTOR(value, 16); In Xilinx ISE the functions are displayed when the toolbar icon is clicked. With the same command the precompiled components can be used.
48 Integer with or withou sign Bits number Vettore
expressions within begin and end of an architecture are computed simultaneously independently from the order they appear in the VHDL code
49
– i.e. if-then-else – «blocks») which are executed upon the change of a sensitivity list signal
from the top downward. All blocks of a process are concurrently executed (but for wait or after -
architecture.
common to all processes
and before begin (of each process). Variables with the same name in different processes have no mutual relation. Multiple processes can coexist within an architetture N.B. within the processes the previously examined structures (when-else, with-select-when etc.) CANNOT be used. They are allowed externally to processes. These structures and processes can coexist within an architecture (although very unlikely)
Sequential statements can be used only within processes (PROCESS) (also in functions (FUNCTION) and procedures (PROCEDURE) ) The set of instructions of a process are concurrent statements
50
51
process_example_1: process(sensitivity list) begin assignment
if then else -- operations b assignment
for loop
case when others
In example 1 a,b,c,d,e etc. are executed in parallel but the statements within if then else and for loop are executed sequentially. The same for the example 2 but d,e operations because of wait are delayed.
N.B. wait and after in Xilinx only in the testbenches process_example_2: process(sensitivity list) begin assignment
if then else -- operations b assignment
wait for 10 ns -- testbench only for loop
case when others
end process process_example_2;
if <condition> then <instruction_1>; else <instruction_2; end if;
The statement if-then-else is used to execute an instruction block following the value of a boolean expression (<condition>). Example: process_1: process(b) begin if (b'event) and (b='1') then – transition of b from 0 to 1 z <=‘1’; -- statements else z <=‘0’; -- sequentially end if; -- executed end process process_1; -- In practice a positive edge of signal b provokes z=1
The “condition” can test also a variable (for instance within a loop )
52
entity mux_2_ways_if_then_else is port ( a : in std_logic; b : in std_logic; s : in std_logic; z : out std_logic); end mux_2_wys_if_then_else; architecture behavioral of mux_2_ways_if_then_else is begin process_mux_2: process(a,b,s) begin -- of the process if s='1' then z<= a ; else z<=b; end if; end process process_mux_2; end behavioral;
1
A B Z S
53
How would you design a 2-ways MUX without a process ?
Z <= A and S or B and notS
What would happen if A and B signals were not inserted in the sensitivity list of the process ? Xilinx sends an error message if all input signals (no matter if they are used) are not inserted in the sensitivity list !!!
54
The statement if-then-else can be further expanded in order to allow multiple conditions evaluations using elsif. Nested if are obviously allowed It must be underlined that the execution
<instruction_i> is activated ONLY if the previous conditions (1,2 …,i-2, i-1) are not met. Sequential evaluation !!!
if <condition_1> then <instruction_1>; elsif <condition_2> then <instruction_2>; . . . . . . . . elsif <condition_n-1> then <instruction_n-1>; else <instruction_n>; end if;
55
11 10
A B Z S(1) S(0)
01 00
C D
entity mux_4_ways_if_then_else_elseif is port ( s : in std_logic_vector (1 downto 0); a : in std_logic; b : in std_logic; c : in std_logic; d : in std_logic; z : out std_logic); end mux_4_ways_if_then_else_elseif; architecture behavioral of mux_4_ways_if_then_else_elseif is begin process_mux_4: process(a,b,c,d,s) begin if s="11" then z<=a; elsif s="10“ then z<=b; elsif s="01“ then z<=c; else z<=d ; end if; end process process_mux_4; end behavioral;
56
It must be noticed that Xilinx simulator displays vectors using eye notation. These «eyes» can be always splitted showing the single signals.
57
case <selection_signal> is when <value_1> => <instruction_1>; when <value_2> => <instruction_2>; when <value_3> => <instruction_3>; .. .. .. .. .. .. when <value_n-1> => <instruction_n-1>; when others => <instruction_n>; end case;
The statement case-when is used for executing a set of instructions on the basis of the value of the signal <selection_signal>. The options must be mutually exclusive With others it is possible to execute the <instruction_n> when none of the previous conditions are
58 N:B: notice the arrow direction
entity mux_4_ways_case_when_others is port ( s : in std_logic_vector (1 downto 0); d : in std_logic_vector (3 downto 0); z : out std_logic); end mux_4_ways_case_when_others; architecture behavioral of mux_4_ways_case_when_others is begin process_mux_4: process(s,d) begin case s is when "11" => z <= d(3); when "10" => z <= d(2); when "01" => z <= d(1); when "00" => z <= d(0); when others => z <= d(0);-- always necessary even
end case; end process process_mux_4; end behavioral; 11 10
D(3) D(2) Z S(1)S(0)
01 00
D(1) D(0)
59
60
N.B. STD_LOGIC can assume 9 values but in our context we use only 4: ‘U’ (undefided) , ‘0’ , ‘1’ and ‘Z’ (high impedance – tristate). The statement type indicates the possible values of an «object» 61 type std_logic is (‘U’, -- not initialized ‘X’, -- unknown ‘0’, -- 0 ‘1’, -- 1 ‘Z’, -- high impedance– tristate….. ‘W’, -- unkown (weak) ‘L’, -- 0 (weak) ‘H’, -- 1 (weak) ‘-’), -- indifferent NB Important !!! With this «type ” (std_logic) it is possible in Xilinx to execute additions and subtractions with vector (even of different size !) which are interpreted in this case as their binary values (they are in fact internally converted) provided IEEE library is used. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Example signal: addend_6 std_logic_vector (5 downto 0) := “010010”; -- 18 signal : addend_2 std_logic_vector (1 downto 0) := “11”;
signal : result std_logic_vector (5 downto 0) ; result <= addend_6 – addend_2; -- in result we find “001111” that is 15
62
This statement for <variable> in <initial_value> downto <final_value> loop
<initial_value> to <final_value> loop is easily interpreted. All operations within the loop are simultaneously executed. Example (I is an integer variable and val_max_index a constant integer)
for I in 0 to val_max_index -1 loop -- I variable.
A(I) <= B(I) exor B(I+1); -- A and B std_logic_vector end loop;
ck_process :process begin for i in 735 downto 0 loop ck <= '0'; wait for 5 ns; ck <= '1'; wait for 5 ns; end loop; end process ck_process; The statement wait can be used (only in the testbench) to generate periodical signals (no sensitivity list). For instance:
t CK
10 ns ck_process :process begin for i in 623 downto 449 loop ck <= not(ck); wait for 5 ns; end loop; end process ck_process; Or..
63
64
Vivado templates
In Vivado select tools and then templates: you will find a wealth of information and thousands examples of constructs ready-to-use. An example for loop (while)