Vous êtes sur la page 1sur 97

OPERATORS

LOGICAL OPERATORS
• Priority
• not (top priority)
• and, or, nand, nor, xor, xnor
• (equal priority)
• Predefined for
• bit, bit_vector
• boolean
• Data types have to match
entity LOGIC_OP is
port (A, B, C, D : in bit;
Z1: out bit;
EQUAL : out boolean);
end LOGIC_OP;
architecture EXAMPLE of LOGIC_OP is
begin

Z1 <= A and (B or (not C xor D)));

EQUAL <= A xor B; -- wrong

• end EXAMPLE;
Logical Operations with Arrays
• Operands of the same length and type
• Assignment via the position of the
elements
(according to range definition)
architecture EXAMPLE of LOGICAL_OP is
signal A_BUS, B_BUS : bit_vector (3
downto 0);
signal Z_BUS : bit_vector (4 to 7);
begin
Z_BUS <= A_BUS and B_BUS;
end EXAMPLE;
Shift Operators: Examples
Arithmetic Operators

• Operands of the same type


• Predefined for
integer
real (except mod and rem)
physical types (e.g. time)
Not defined for bit_vector
• The typical algebraic operators are
available for integers, such as +,-,*
(multiplication), and / (division). Although
these operations are not built-in for
bit_vectors, they are often provided in
libraries that come with your VHDL
software. They are used with bit_vectors
by interpreting them as a binary
representation of integers, which may be
added, subtracted, multiplied, or divided.
Relational operators
• They are =, /=, <, <=, > and >= and have
their usual meanings (/= denotes the not
equal operator). The result of all these
operators is a boolean value (TRUE or
FALSE).
• The arguments to the = and /= operators
may be of any type. The arguments of the
<, <=, > and >= operators may be any
scalar type (integer, real, and physical
types) or the bit_vector type. If the
arguments are bit_vectors, then the
arguments must be the same length
and the result is TRUE only if the
relation is true for each corresponding
element of the array arguments.
When operands are discrete array types ,
comparison is performed one element at a
time from left to right .

BIT_VECTOR “011” <BIT_VECTOR “101”


Since the first element in the first array is
less than the first element in the second.
architecture EXAMPLE of COMPARISON is
signal NIBBLE: bit_vector(3 downto 0);
signal BYTE: bit_vector(0 to 7);
begin
NIBBLE <= "1001";
BYTE <= "00001111";

COMPARE: process (NIBBLE, BYTE)


begin
if (NIBBLE < BYTE) then
-- evaluated as:
-- if (NIBBLE(3) < BYTE(0)) or
-- ((NIBBLE(3) = BYTE(0)) and
-- (NIBBLE(2) < BYTE(1))) or
-- ((NIBBLE(3) = BYTE(0)) and
-- (NIBBLE(2) = BYTE(1)) and
-- (NIBBLE(1) < BYTE(2))) or
...
-- better:
if (( "0000"& NIBBLE) <= BYTE) then
• Operands of the same type
• Arrays:
may differ in length
• left-alignment prior to comparison
• are compared element after element
• No numerical interpretation
• (unsigned, 2-complement, etc.)


• When comparing array types it must be
considered that the comparison is carried
out from the left side to the right.
• That means for arrays of varying length
that "111" is greater than "1001", for
example. If it is not desired, hence shall be
compared right-aligned, then the arrays
will have to be brought upon the equal
length by hand,
• e.g. by means of concatenation: '0'&"111"
is then smaller than "1001".
BEHAVIORAL MODELING
• The IF statement
The if condition must evaluate to a boolean value ('true' or
'false'). After the first if condition, any number of elsif
conditions may follow. Overlaps may occur within
different conditions. An else branch, which combines all
cases that have not been covered before, can optionally
be inserted last. The if statement is terminated with 'end
if'.

• The first if condition has top priority: if this condition is


fulfilled, the corresponding statements will be carried out
and the rest of the 'if - end if' block will be skipped.
• if CONDITION then
-- sequential statements
end if;


if CONDITION then
-- sequential statements
else
-- sequential statements
end if;

if CONDITION then
-- sequential statements
elsif CONDITION then
-- sequential statements
···
else
-- sequential statements
end if;
IF Statement: Example
entity IF_STATEMENT is
port (A, B, C, X : in bit_vector (3 downto
0);
Z : out bit_vector (3 downto 0);
end IF_STATEMENT;
architecture EXAMPLE1 of IF_STATEMENT is
begin
process (A, B, C, X)
begin
Z <= A;
if (X = "1111") then
Z <= B;
elsif (X > "1000") then
Z <= C;
end if;
end process;
end EXAMPLE1;
architecture EXAMPLE2 of IF_STATEMENT is
begin
process (A, B, C, X)
begin
if (X = "1111") then
Z <= B;
elsif (X > "1000") then
Z <= C;
else
Z <= a;
end if;
end process;
end EXAMPLE2;
• The example code shows two different
implementations of equivalent behaviour.
The signal assignment to the signal Z in
the first line of the left process
(architecture EXAMPLE1) is called a
default assignment, as its effects will only
be visible if it is not overwritten by another
assignment to Z.

• Note that the two conditions of the 'if' and
'elsif' part overlap, because X="1111" is
also true when X>"1000". As a result of
the priority mechanism of this if construct,
Z will receive the value of B if X="1111".
IF -EXAMPLE

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;
• Architecture BEH of DEMUX is
begin
process (e,s)
begin
if e<=‘1’ then
if s <=“00”
then d(0) <=e;
elsif s<=“01”
then d(1) <=e;
elsif s<= “10”
then d(2)<=e;
else d(3) <=e;
endif;
else d<=“0000”;
endif;
end process;
end beh;
Comparator
entity Comparator is

port(A:in std_logic_vector(3 downto 0);


B:in std_logic_vector(3 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;
D FF
library ieee ;
use ieee.std_logic_1164.all;
use work.all;

entity dff is
port(data_in:in std_logic;
clock:in std_logic;
data_out:out std_logic);

end dff;
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;
JK FF

library ieee;
use ieee.std_logic_1164.all;
entity JK_FF is
port (clock:in std_logic;
J, K:in std_logic;
reset:in std_logic;
Q, Qbar:out std_logic);
end JK_FF;
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)
begin
if (reset='1') then
state <= '0';
elsif (clock=‘1’ and clock’event)
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;
CASE Statement
case EXPRESSION is

when VALUE_1 =>


-- sequential statements

when VALUE_2 | VALUE_3 =>


-- sequential statements

when VALUE_4 to VALUE_N =>


-- sequential statements

when others =>


-- sequential statements
end case ;
• Choice options must not overlap
• All choice options have to be covered
• single values
• value range
• selection of values
• ("|" means "or")
• "when others" covers all remaining choice
options
• Ranges can be defined for data types
with a fixed order, only, e.g. user
defined enumerated types or integer
values. This way, it can be decided
whether one value is less than, equal to or
greater than another value.
• For ARRAY types (e.g. a BIT_VECTOR)
there is no such order, i.e. the range
"0000" TO "0100" is undefined and
therefore not admissible.
CASE :EXAMPLE
entity CASE_STATEMENT is
port (A, B, C, X : in integer range 0 to 15
Z : out integer range 0 to 15;
end CASE_STATEMENT;
architecture EXAMPLE of CASE_STATEMENT is
begin
process (A, B, C, X)
begin
case X is
when 0 =>
Z <= A;
when 7 | 9 =>
Z <= B;
when 1 to 5 =>
Z <= C;
when others =>
Z <= 0;
end case;
end process;
end EXAMPLE;
DECODER

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 <= "0001";
when "01" => O <= "0010";
when "10" => O <= "0100";
when "11" => O <= "1000"
when others => O <= "XXXX";
end case;
end process;
end behv;
architecture when_else of DECODER is
begin
-- use when..else statement

O <= "0001" when I = "00" else


"0010" when I = "01" else
"0100" when I = "10" else
"1000" when I = "11" else
"XXXX";
end when_else;
FOR Loops

• Loop parameter is implicitly declared


• can not be declared externally
• read only access
• The loop parameter adopts all values from
the range definition
• integer ranges
• enumerated types
Loop SYNTAX
[LOOP_LABEL :]
for IDENTIFIER in DISCRETE_RANGE loop
-- sequential statements
end loop [LOOP_LABEL] ;

[LOOP_LABEL :]
while CONDITION loop
-- sequential statements
end loop [LOOP_LABEL] ;
• Optional label
• FOR loop identifier
• not declared
• read only
• not visible outside the loop
entity FOR_LOOP is
port (A : in integer range 0 to 3;
Z : out bit_vector (3 downto 0));
end FOR_LOOP;

architecture EXAMPLE of FOR_LOOP is


begin
process (A)
begin
Z <= "0000";
for I in 0 to 3 loop
if (A = I) then
Z(I) <= `1`;
end if;
end loop;
end process;
end EXAMPLE;
for identifier in range
EXAMPLE
FACTORIAL :=1;
for NUMBER in 2 to 5 loop
FACTORIAL :=FACTORIAL *NUMBER ;
end loop;

NO EXPLICIT DECLARATION FOR


NUMBER IS REQUIRED
Loop Examples

entity CONV_INT is
port (VECTOR: in bit_vector(7
downto 0);
RESULT: out integer);
end CONV_INT;
architecture A of CONV_INT is
begin
process(VECTOR)
variable TMP: integer;

begin
TMP := 0;

for I in 7 downto 0 loop


if (VECTOR(I)='1') then
TMP := TMP + 2**I;
end if;
end loop;

RESULT <= TMP;


end process;
end A;
WAIT Statement

• 'wait' statements stop the process


execution
• The process is continued when the
instruction is fulfilled
Different types of wait statements:
• wait for a specific time
wait for 5 ns;
wait for a signal event
wait for SUM;
wait for a true condition (requires an event)
wait until SUM >100;
indefinite (process is never reactivated)
wait;
WAIT
• Wait statements must not be used in
processes with sensitivity list
Latch model

entity FF is
port (D, CLK : in bit;
Q : out bit);
end FF;
LATCH
architecture BEH_1 of FF is
begin
process
begin
wait on CLK;
if (CLK = '1') then
Q <= D;
end if;
end process;
end BEH_1;
LATCH
architecture BEH_2 of FF is
begin
process
begin
wait until CLK=`1`;
Q <= D;
end process;
end BEH_2;
Testbench:
stimuli generation
STIMULUS: process
begin
SEL <= `0`;
BUS_B <= "0000";
BUS_A <= "1111";
wait for 10 ns;
SEL <= `1`;
wait for 10 ns;
SEL <= `0`;
wait for 10 ns;
wait;
end process STIMULUS;
WAIT
• Wait constructs, in general, are an
excellent tool for describing timing
specifications.
• For example it is easy to implement a bus
protocol for simulation. The timing
specification can directly be translated to
simulatable VHDL code.
• But keep in mind that this behavioural
modelling can only be used for simulation
purposes as it is definitely not
syntheziable
Entity of CPU
Entity CPU is
Port(CPU_DATA_VALID: in std_logic;
CPU_DATA_READ: in std_logic;
LOCAL_BUFFER : in
std_logic_vector(0 to 7);
CPU_DATA: out
std_logic_vector(0 to 7);
end CPU;
READ_CPU : process
begin
wait until CPU_DATA_VALID = `1`;
CPU_DATA_READ <= `1`;
wait for 20 ns;
LOCAL_BUFFER <= CPU_DATA;
wait for 10 ns;
CPU_DATA_READ <= `0`;
end process READ_CPU;
Variables
• Variables are available within processes,
only
• named within process declarations
• known only in this process
• VHDL 93: shared variables
• immediate assignment
• keep the last value
VARIABLES
• Possible assignments
• signal to variable
• variable to signal
• types have to match
Variables
architecture RTL of XYZ is
signal A, B, C : integer range 0 to 7;
signal Y, Z : integer range 0 to 15;
begin
process (A, B, C)
variable M, N : integer range 0 to 7;
begin
M := A;
N := B;
Z <= M + N;
M := C;
Y <= M + N;
end process;
end RTL;
VARIABLE –EXAMPLE
Process (A)
variable EVENTS: integer =-1;
Begin
EVENTS:=EVENTS +1;
end process;
Signal A,Z:INTEGER;
process (A)
variable V1,V2 :INTEGER;
begin
V1:=A-V2;
Z<=-V1;
V2:=Z+V1*2;
end process;
VARIABLE
• If an event occurred on signal A at time T1
,and variable V2 was associated a value
,say 10 ,in statement 3 ,then the next time
an event occurs on signal A, say at time
T2 ,the value of V2 used in statement 1
would still be 10.
SIGNALS
• Signal values are assigned after the
process execution
• Only the last signal assignment is carried
out
signal-object <=expression[after delay
value];
• A signal assignment can appear outside a
process.Then it is considered to be a
concurrent signal assignment statement.
• Within a process, it is a sequential signal
assignment and is executed in sequence
with other statements.
• When a signal assignment is excuted,the
value of the expression is computed, and
this value is scheduled to be assigned to
the signal after the specified delay.
• It is important to note that the expression
is evaluated at the time the statement is
executed which is the current simulation
time ,and not after the specified delay.
• e.g . Z<= M+N after 5 ns;
• Z<= M+N;
• If no after clause (e.g. after delay) is
specified ,the delay is assumed to be a
default delay.

• DELTA DELAY
• is a very small delay ,and actual
simulation time does not advance .
Process (A,B,C,D);
variable T1,T2,T3:bit;
Begin
T1:=A and B;
T2:=C and D;
T3:=T1 or T2;
Z<=not T3;
End process;
• T1,T2 and T2 get their values immediately
• But Z gets its value only after a delta delay
• In the process ..if an event occurs on A at
time T, execution of statement 1 causes
V1 to get a value,
• Signal Z is then scheduled to get a value
at time T+delta, and statement 3 is
executed in which the old value of Z is
used .The reason is ,new value of Z
comes only after the delta delay
Global Variables (VHDL'93)

• Accessible by all processes of an architecture


• (shared variables)
• Can introduce non-determinism

• Not to be used in synthesizable code


architecture BEHAVE of SHARED is
shared variable S : integer;
begin
process (A, B)
begin
S := A + B;
end process;

process (A, B)
begin
S := A - B;
end process;
end BEHAVE;
Variables and Signals
• Variables and signals show a fundamentally
different behaviour.
• In a process, the last signal assignment to a
signal is carried out when the process execution
is suspended.
• Value assignments to variables, however, are
carried out immediately.
• To distinguish between a signal and a variable
assignment different symbols are used: ' <= '
indicates a signal assignment and ' := ' indicates
a variable assignment.
SIGNAL ASSIGNMENT
Signal-object<=expression [after delay
value];
e.g.
Z<= X after 5 ns;
Z<=X;
• When a signal assignment statement is
executed , the value of the expression is
computed ,and this value is scheduled to
be assigned to the signal after the
specified delay .
• The expression is executed currently ,but
the signal is ‘assigned ‘ the value or
‘scheduled to be assigned the value’
after the specified delay plus a ‘delta
delay’
Delta Delay
• A delta delay is a very small delay .
• This delay models the actual hardware .
Wait for 0 ns
Process
begin
wait on DATA;
A<=DATA;
wait for 0 ns;
B<=A;
End process;
DATA
T
DATA

B without the wait statement


Creating waveforms
signal A : std_logic;
Process (A)
begin
A <= not A after 10 ns;
End process;
Example 3: D FF with Asynchronous
Reset
Declarations........
-- CLK: in STD_LOGIC;
-- RESET: in STD_LOGIC;
-- DIN: in STD_LOGIC;
-- DOUT: out STD_LOGIC;
process (CLK, RESET)
begin
if RESET='1' then --asynchronous
RESET active High
DOUT <= '0';
elsif (CLK'event and CLK='1') then --CLK
rising edge
DOUT <= DIN;
end if;
end process;
D FF with Synchronous Reset
process (CLK)
begin
if (CLK'event and CLK='1‘) then --CLK rising edge
if RESET='1' then --synchronous RESET active High
DOUT <= '0';
else
DOUT <= DIN;
end if;
end if;
end process;
3-bit Shift-Register/Shifter

entity shift_reg is
port(I:in std_logic;
clock:in std_logic;
shift:in std_logic;
Q:out std_logic);
end shift_reg;
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

if clock'event and clock='1' then


if shift = '1' then
S <= I & S(2 downto 1);
end if;
end if;
end process;
32-bit Shift Register, sync rst

entity SER_PAR_SH_REG is port (


CLK, RST, Serial_Din
: in std_logic;

Data : out std_logic_vector(31


downto 0) );
end entity SER_PAR_SH_REG;
architecture behavioral of SER_PAR_SH_REG is
Signal Internal_Data : std_logic_vector(31
downto 0);
begin
process (CLK)
begin
if CLK’event and CLK = ‘1’ then
if RST = ‘1’ then
Internal_Data <= x”00000000”;
else
Internal_Data <= Serial_Din &
Internal_Data(31 downto 1);
end if;
end if;
end process;
Data <= Internal_Data;
end behavioral;
16-bit Loadable Counter, async reset

entity CNTR_16_async is port (


CLK, RST, Load : in std_logic;
Input_Data : in
std_logic_vector(15 downto 0);
Count : out
std_logic_vector(15 downto 0) );
end entity CNTR_16_async ;
architecture behavioral of CNTR_16_async is
Signal Internal_Count : std_logic_vector(15
downto 0) := X”0000”;
begin
process (CLK, RST)
begin
if RST = ‘1’ then
Internal_Count <= ”0000”;
elsif CLK’event and CLK = ‘1’ then
if Load = ‘1’ then
Internal_Count <= Input_Data;
else
Internal_Count <= Internal_Count + 1;
end if;
end if;
end process;
Count <= Internal_Count;
end behavioral;

Vous aimerez peut-être aussi