vhdl in digital circuit synthesis (tutorial)

58
VHDL in digital circuit synthesis (tutorial) dr inż. Miron Kłosowski EA 309 [email protected] l

Upload: shina

Post on 31-Jan-2016

92 views

Category:

Documents


1 download

DESCRIPTION

VHDL in digital circuit synthesis (tutorial). dr inż. Miron Kłosowski EA 309 [email protected]. Library declaration. library IEEE; use IEEE.std_logic_1164.all;. all - use all elements of the package. Obligatory IEEE library. std_logic_1164 package usage. Other IEEE packages: - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: VHDL in digital circuit synthesis (tutorial)

VHDL in digital circuit synthesis (tutorial)

dr inż. Miron KłosowskiEA 309

[email protected]

Page 2: VHDL in digital circuit synthesis (tutorial)

Library declaration

Other IEEE packages:

IEEE.std_logic_signed.allIEEE.std_logic_unsigned.allIEEE.std_logic_arith.allstd.text_io.allIEEE.numeric_std.all;

std_logic_1164 package usage

Obligatory IEEE library

all - use all elements of the package

For example std_logic_vector adder

For example: type conversion: integer to std_logic_vector

For text file support (for simulation).

Package included by default: std.standard.all contains definitions of basic types like: boolean, bit, character, string, integer, real, natural, positive, bit_vector.

For example: function std_match for vector compare.

library IEEE;

use IEEE.std_logic_1164.all;

Page 3: VHDL in digital circuit synthesis (tutorial)

Sample design

library IEEE;use IEEE.std_logic_1164.all;

entity multiplexer isport (

signal s : in std_logic;signal x0,x1 : in std_logic_vector(7 downto 0);signal y : out std_logic_vector(7 downto 0)

);end entity multiplexer;

architecture data_flow of multiplexer is begin

y <= x1 when ( s = '1' ) else x0;end architecture data_flow;

Page 4: VHDL in digital circuit synthesis (tutorial)

Design simulation – testbench (1)

Sample TESTBENCH (template is usually generated automatically):

LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;

ENTITY fpgalab1_tb_vhd ISEND fpgalab1_tb_vhd;

ARCHITECTURE behavior OF fpgalab1_tb_vhd IS

-- Component Declaration for the Unit Under Test (UUT)COMPONENT projekt1PORT(

clk : IN std_logic;reset : IN std_logic;sw0 : IN std_logic;sw1 : IN std_logic;sw2 : IN std_logic;sw3 : IN std_logic;an : OUT std_logic_vector(3 downto 0);seg : OUT std_logic_vector(7 downto 0);ld0 : OUT std_logic;ld1 : OUT std_logic);

END COMPONENT;

Testbench generates and tests all signals therefore port is not used.

Simulated Circuit (UUT) is connected using component declaration mechanism (described in details later). Here declaration of names, types and directions of tested signals is present (signals which would be visible at the pins of synthesized physical FPGA circuit).

Page 5: VHDL in digital circuit synthesis (tutorial)

Design simulation – testbench (2)SIGNAL sw0 : std_logic := '0';SIGNAL sw1 : std_logic := '0';SIGNAL tst : std_logic := '1';SIGNAL trx : std_logic := '1';SIGNAL an : std_logic_vector(3 downto 0);SIGNAL seg : std_logic_vector(7 downto 0);SIGNAL ld0 : std_logic;SIGNAL ld1 : std_logic;

signal clk : std_logic := '0';signal clk_p : std_logic := '0';signal clk_n : std_logic := '1';constant PERIOD : time := 10 ns;constant DUTY_CYCLE : real := 0.25;signal reset : std_logic := '1';

BEGIN-- Instantiate the Unit Under Test (UUT)uut: projekt1 PORT MAP(

clk => clk,reset => reset,sw0 => sw0,sw1 => sw1,sw2 => tst,sw3 => trx,an => an,seg => seg,ld0 => ld0,ld1 => ld1

);

Definitions of signals used for component testing – signals are connected to the inputs of UUT and should be initialized.

Definitions of additional signals and constants needed for testing. Initialization of those signals is usually recommended.

Real connection to UUT component is created here, PORT MAP describe connections between component signals and testbench signals.

Page 6: VHDL in digital circuit synthesis (tutorial)

Design simulation – testbench (3)-- clk_simple <= not clk_simple after PERIOD/2;

clk_p <= not clk_p after PERIOD/2;clk_n <= not clk_n after PERIOD/2;

clk <= '1' after (PERIOD - (PERIOD * DUTY_CYCLE)) when clk = '0' else '0' after (PERIOD * DUTY_CYCLE);

reset <= '0' after 5 ns;

tb : PROCESSBEGIN

-- Wait 10 ns for global reset to finishwait for 10 ns;-- Place stimulus heresw0 <= '1';sw1 <= '0';wait for 20 ns;sw0 <= '0';wait for 10 ns;sw1 <= '1';wait; -- will wait forever

END PROCESS;

Simple clock generator.

Differential clock generator.

Arbitrary duty cycle clock generator.Reset signal

deassertion.

Process – instructions inside the process are executed sequentailly.

Signal values are sequentially modified.

wait instruction without arguments waits forever (without it the process would start again).

Delay.

Page 7: VHDL in digital circuit synthesis (tutorial)

Design simulation – testbench (4)tb1 : PROCESSvariable x : integer;BEGIN

wait for 10 ns;loop x := 1; while x < 11 loop tst <= not tst; wait for x*2 ns; x := x + 1; assert x /= 11 report „Last iteration finished" severity NOTE; end loop; wait until rising_edge(clk);end loop;

END PROCESS;

tb2 : PROCESSBEGIN

wait on clk_p;trx <= transport clk_p after (PERIOD/2)+3 ns;

END PROCESS;

END;

Conditional loop instruction

Infinite loop instruction

Assert instruction – generates warning and error messages and stops a simulation

‘wait until’ instruction waits for a logic condition to be satisfied (in this example it waits for the rising edge of the clk signal)

‘wait on’ instruction waits for a signal change

This assign instruction registers future change of the signal trx. This is an example of a transport delay.

Page 8: VHDL in digital circuit synthesis (tutorial)

Design simulation – testbench (5)

Page 9: VHDL in digital circuit synthesis (tutorial)

Signal assignment (concurrent)

Is this a problem ?Signal_1 <= Signal_2;Signal_1 <= Signal_3;

Sequence of assignments is irrelevant (architecture body is an concurrent instruction area).

signal_2 <= signal_3;

signal_1 <= signal_2;

It can be solved using the resolution function !

Signal_2

Signal_3

Signal_1

Important !!!

Resolution function is defined for type std_logic and std_logic_vector. Type std_ulogic is a logic type without resolution function. Using std_logic and std_logic_vector types is recommended.

signal_1 <= signal_2;

signal_2 <= signal_3;

Page 10: VHDL in digital circuit synthesis (tutorial)

• Std_logic is a most frequently used logic type. It can be assigned 0 i 1 values and more:Z high impedance state (for top level signals only); - don't care (for example used by function std_match);Other values are useful in simulation:U uninitialized (at the beginning of simulation);X undefined strong signal; W undefined weak signal;L, H week 0 and 1 signals.

  Resolution function for std_logic: U  X  0  1  Z  W  L  H  -  ---------------------------------  U U U U U U U U U | U |   U X X X X X X X X | X |   U X 0 X 0 0 0 0 X | 0 | U X X 1 1 1 1 1 X | 1 | U X 0 1 Z W L H X | Z | U X 0 1 W W W W X | W | U X 0 1 L W L W X | L | U X 0 1 H W W H X | H | U X X X X X X X X  | - |

Resolution function

Page 11: VHDL in digital circuit synthesis (tutorial)

• Sample vector (one-dimensional array):signal x: std_logic_vector(7 downto 0);

x <= "11001010";

x(7) <= '1'; x(6) <= '1'; x(5) <= '0'; x(4) <= '0';x(3) <= '1'; x(2) <= '0'; x(1) <= '1'; x(0) <= '0';

• Vector with rising index:signal y: std_logic_vector(0 to 7);

y <= "11001010";y <= x;Previous assignment automatically perform 8 one-bit assignments:y(0) <= x(7); y(1) <= x(6); y(2) <= x(5); y(3) <= x(4);y(4) <= x(3); y(5) <= x(2); y(6) <= x(1); y(7) <= x(0);

• Vector assignment is possible when the number and type of vector’s elements is the same in RHS and LHS.

Vectors (1)

Page 12: VHDL in digital circuit synthesis (tutorial)

• Because many library functions use vectors with MSB on the left side it is recommended to use downto indexing (index 0 is a LSB)

signal q: std_logic_vector(1 downto 0);

• You can address smaller subvectors using parenthesis:

x(7 downto 6) <= q;x(5 downto 3) <= y(2 to 4);

• You cannot change index direction of the vector, assignment: x(5 downto 3) <= y(4 downto 2); is not correct!!!

• You can create vectors from logic signals or smaller vectors using the concatenation operator &:signal s: std_logic;

x <= "10" & q & '1' & q & '0';vec_from_sig <= s & s & s & s & s & s & s & s;

Vectors (2)

Page 13: VHDL in digital circuit synthesis (tutorial)

• You can create vectors using aggregates:x <= ('1', '0', q(1), q(0), '1', q(1), q(0), others => '0');x <= (6=>'0', 7=>'1', 4=>q(0), 5=>q(1), 0=>'0', 2=>q(1), 1=>q(0), others => '1');zero_vector <= ( others => '0');vec_from_sig <= ( others => s );vec_from_sig1 <= ( s1, s2, s3, s4, others => s );vec_from_sig2 <= ( 0=>'1', 6 downto 2 => s2, 7|1 => s1 );

Logical operations on vectors:signal temp: std_logic_vector(7 downto 0);temp <= ( others => s );y <= ( temp and x1 ) or ( not temp and x0 );• You can perform following logic operations: not, and, or, nand, nor, xor, xnor. • Logic operation is performed on bits taken from the same position of operand vectors. Result is placed in the same position in the LHS vector.• Vectors used for the operation must have the same length.

Word ‘others’ can be used only at the end of the aggregate.

Vectors (3)

Page 14: VHDL in digital circuit synthesis (tutorial)

Sample design (2)library IEEE;use IEEE.std_logic_1164.all;

entity multiplexer isport (

signal s : in std_logic;signal x0,x1 : in std_logic_vector(7 downto 0);signal y : out std_logic_vector(7 downto 0)

);end entity multiplexer;

architecture logic of multiplexer is signal temp : std_logic_vector(7 downto 0);begin temp <= ( others => s ); y <= ( temp and x1 ) or ( not temp and x0 );end architecture logic;

Page 15: VHDL in digital circuit synthesis (tutorial)

• You can perform arithmetic operations not only on integer types. Std_logic_vector type can be also used for this task but only when one the following packages are used:use IEEE.std_logic_unsigned.all;use IEEE.std_logic_signed.all;• If in the same design entity signed and unsigned vectors are present you can use the signed and unsigned vector types defined in package IEEE.std_logic_arith• You can also used the IEEE.std_logic_signed.all package for all vectors but prefix the unsigned vectors with ‘0’ & to make them non negative.• Carry in and out synthesis (in addition and subtraction output vector length is equal to the longest input vector):

signal res, x, y: std_logic_vector(7 downto 0);signal a: std_logic_vector(8 downto 0);signal cin, cout : std_logic;

a <= ('0' & x) + ('0' & y) + cin;res <= a(7 downto 0);cout <= a(8);

Arithmetic operations on vectors

Page 16: VHDL in digital circuit synthesis (tutorial)

Frequently used type conversion functions:• Packages IEEE.std_logic_unsigned and IEEE.std_logic_signed contain conversion function from type Std_logic_vector to type Integer:CONV_INTEGER(ARG: STD_LOGIC_VECTOR)• Package IEEE.std_logic_arith contains following conversion functions:- Integer to Std_logic_vector (you have to specify the size of the vector): CONV_STD_LOGIC_VECTOR(ARG: INTEGER; SIZE: INTEGER)- Integer to Unsigned/Signed:CONV_UNSIGNED(ARG: INTEGER; SIZE: INTEGER)CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER)- Unsigned/Signed to Integer:CONV_INTEGER(ARG: UNSIGNED)CONV_INTEGER(ARG: SIGNED)- Std_logic_vector extension to length size:EXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER)- Std_logic_vector signed extension to length size:SXT(ARG: STD_LOGIC_VECTOR; SIZE: INTEGER)• Package IEEE.std_logic_1164 contains conversion functions for Bit_Vector:TO_BITVECTOR(S: STD_LOGIC_VECTOR)TO_STDLOGICVECTOR(B: BIT_VECTOR)

Type conversion (examples)

Page 17: VHDL in digital circuit synthesis (tutorial)

Processes are used for behavioral description of the hardware. Instructions inside the process are executed sequentially to calculate the values of signals assigned in the process.

architecture behavioral of multiplexer is begin

mux: process (x0, x1, s) isbegin

if s = '1' theny <= x1;

elsey <= x0;

end if;end process mux;

end architecture behavioral;

Optional label

Sensitivity list

Processes

Page 18: VHDL in digital circuit synthesis (tutorial)

• In processes describing combinatorial logical circuits the body of the process (the algorithm) should be started only at the change of the signals present on the sensitivity list.• If the process has to describe the behavior of combinatorial circuit (i.e. Logic circuit without the latches or flip-flops) two conditions must be satisfied:

1. All the input signals of the logic circuit must be present on the sensitivity list of the process.2. All the output signals of the logic circuit must be assigned a value at least once in every possible flow of the algorithm used in the body of the process.Good process example:mux: process (x0, x1, s) isBegin

y <= x0;if s = '1' then

y <= x1;end if;

end process mux;

Bad process example:mux: process (s) isbegin

if s = '1' theny <= x1;

end if;end process mux;

Combinatorial processes (1)

Page 19: VHDL in digital circuit synthesis (tutorial)

• When there is a possibility that output signal is not assigned during the process run as the result of the synthesis a latch will be inferred – the process is no longer combinatorial. • You can use for example ‘else’ construct to avoid this.• Another method is to use default value for all output signals (see below):

mux: process (x0, x1, s) isbegin

y <= x0;if s = '1' then

y <= x1;end if;

end process mux;

Signal assignment in the process is not performed at the same time when the <= instruction is found. This assignment is rather programmed to be performed later – when the process finishes the algorithm and stops waiting for signals change. Therefore if more than one assignment to the signal is found during the process run only the last assignment is valid. All the programmed assignments are finalized at the same time when the process stops. Read value of the signal cannot be changed during the process run – when the signal is read it always returns the same value (even when the new value has been asserted).

Combinatorial processes (2)

Page 20: VHDL in digital circuit synthesis (tutorial)

• It is possible that output signal of the process is used at the same time as input signal of the same process. It is of course not allowed to create the combinatorial loop in any way – but you can create the chain logic.• In this situation remember that output signals which are used as an input also should satisfy both conditions from the previous page (sensitivity list and obligatory assignment):process(a, b, c, x, y) isbegin

x <= a and b;y <= x or c;z <= y xor a;

end process;

Delta cycles for process execution:t=0 ns (a=0, b=1, c=0, x=0, y=0, z=0)t=1 ns (a=1, b=1, c=0, x=0, y=0, z=0)t=1 ns + 1d (a=1, b=1, c=0, x=1, y=0, z=1)t=1 ns + 2d (a=1, b=1, c=0, x=1, y=1, z=1)t=1 ns + 3d (a=1, b=1, c=0, x=1, y=1, z=0)

• Sometimes process is started several times because the input signal has been changed during process execution (delta cycles). In this situation last assignment to the output signal along all the delta cycles is valid.• Interesting property: different signals can be assigned in any sequence in the process.• Remember that you cannot assign the same signal in different processes without activating the resolution function (which is usually prohibited during synthesis).

Combinatorial processes (3)

Page 21: VHDL in digital circuit synthesis (tutorial)

• Signals are used to communicate between the process and the rest of the system (concurrent). But to create algorithms inside the process you will need variables.• Variables are defined at the beginning of the process (just before ‘begin’) and they are visible within the process only.• Variables preserve its value between process runs (they can model the memory).• Variables change at the same time when the variable assignment is found (they behave like you would expect in a software programming language).

process(a, b, c) isvariable x,y:std_logic_vector(7 downto 0);begin

x := a and b;y := x or c;z <= y xor a;

end process;

Delta cycles for process execution:t=0 ns (a=0, b=1, c=0, x=0, y=0, z=0)t=1 ns (a=1, b=1, c=0, x=0, y=0, z=0)t=1 ns + 1d (a=1, b=1, c=0, x=1, y=1, z=0)

Contrary to signals, different variables must be assigned in the proper sequence – like in a software programming language. When you exchange the first line with the second the result will be different:(x=1, y=0, z=1)

Variables (1)

Page 22: VHDL in digital circuit synthesis (tutorial)

• You can assign the initial value to the variable:

variable x: std_logic_vector(7 downto 0) := "00100010";variable i: integer range 0 to 7 := 4;

• The initial value is assigned to the variable only at the beginning of the synthesis or simulation. It means that if you want to assign the initial value every time the process is started you have to do it in the process body just after the ‘begin’ word.

• Be careful – when you use the variable’s value before you assign the initial value to it you read the value from the previous process execution. This creates a memory element (usually latch).

Variables (2)

Page 23: VHDL in digital circuit synthesis (tutorial)

• Processes can be used to describe sequential circuits if they use signals or variables as a memory.• signal memory – if signal assertion is not continuous but depends on input signals’ states (for example if you forgot about default value assertion like in the example below).• variable memory – if variable is not initialized at the beginning of the process and contents of the variable from previous process run is used.• Sequential processes use memory elements available in the target FPGA (FF, latches, etc.) – you cannot build them using gates. It is important to use strict design rules to achieve synthesizable sequential processes.

Example of sequential process (q is not asserted continuously):latch: process (ena, d) isbegin if ena = '1' then q <= d; end if;end process latch;

D-latch. When the ena signal is active q output is connected to the d input, when ena is inactivated q output is frozen.

Sequential processes (1)

Page 24: VHDL in digital circuit synthesis (tutorial)

• Latches are not used frequently, but they are available in most FPGAs.• Usually latch synthesis is caused by an error (for example: not asserting default value to the output signal in combinatorial process). Synthesizer software usually warns about latches: „Warning: latch inferred ... ”• Classic method to build sequential circuits is to use edge-triggered flip-flops. • Recall all the properties of the synchronous digital circuits, we will use this design paradigm in the VHDL and FPGAs.

Edge triggered D-type flip-flop:dff: process (clk) isbegin if clk = '1' and clk'event then q <= d; end if;end process dff;

D-type flip-flop (rising edge triggered). If clk logic value changes, value of the attribute ‘event of the clk signal is set to the ‘1’ for the moment. If clk changes to ‘1’ (i.e. rising edge occurred) the signal value from the d input is transferred to the q output, and q is frozen till the next clk edge.'0' for falling edge

Sequential processes (2)

Page 25: VHDL in digital circuit synthesis (tutorial)

’event attribute detects every change of the signal, it is suggested to userising_edge() or falling_edge() functions which detect only changes from ‘0’ to ‘1’ or ‘1’ to ‘0’ respectively. Those functions do not detect changes between other std_logic type’s values like ‘U’,’X’,’Z’, etc.

dff: process (clk) isbegin if rising_edge(clk) then q <= d; end if;end process dff;

dff: process (clk) isbegin if falling_edge(clk) then q <= d; end if;end process dff;

Synchronous circuit clocked with rising / falling edge of the clock:

circuit_name: process (clock) isbegin if rising/falling_edge(clock) then .. –- Sequential description of .. –- the digital synchronous circuit, .. –- all signals assigned here are .. -- synthesized as D-type flip-flops’ .. -- outputs. .. –- All logic expressions, conditionals, .. -- etc. are synthesized as combinatorial .. -- logic driving D inputs of flip-flops. end if;end process circuit_name;

Sequential processes (3)

Page 26: VHDL in digital circuit synthesis (tutorial)

• Usually flip-flops in FPGAs are designed with asynchronous reset and set inputs.

drff: process (clk, rst) isbegin if rst = '1' then q <= '0'; elsif rising_edge(clk) then q <= d; end if;end process drff;

dsff: process (clk, set) isbegin if set = '1' then q <= '1'; if rising_edge(clk) then q <= d; end if;end process dsff;

Synchronous circuit clocked with rising / falling edge of the clockwith asynchronous reset input:

circuit_name: process (clock, reset) isbegin if reset = '1' then -- or '0' sig1 <= "00110"; sig2 <= const; .. –- Values asserted to flip-flops .. –- when reset is active. .. –- Must be constant because .. –- asynchronous load of the signal .. –- is not usually supported. elsif rising/falling_edge(clock) then .. -- Sequential description of .. –- the digital synchronous circuit: sig1 <= ... sig2 <= ... end if;end process circuit_name;

Sequential processes (4)

Page 27: VHDL in digital circuit synthesis (tutorial)

• Global reset of entire system should be performed with disabled clock. When clock is running some flip-flops can miss a clock when the reset signal deassertion is delayed because of signal propagation.• Using the hardware reset input of the FPGA (PROG input in Xilinx) is recommended (use initial values of the signals).• Never drive asynchronous set/reset from combinatorial logic – it can contain hazards and therefore spikes are possible – use direct output of the flip-flops or use synchronous reset.• Avoid suggesting clock gating in process description (it is usually not supported), rather use synchronous clock enable:

-- clock gating process !!!dceff: process (clk, rst) isbegin if rst = '1' then q <= '0'; elsif clk_ena = '1' then if rising_edge(clk) then q <= d; end if; end if;end process dceff;

Sequential processes (5)

Synchronous reset and clock enable:circuit_name: process (clock) isbegin if rising/falling_edge(clock) then if sync_reset=‘1’ then q <= ‘0’; elsif clock_enable=‘1’ then q <= ..... end if; end if;end process circuit_name;

Page 28: VHDL in digital circuit synthesis (tutorial)

• You can assign initial value to the signal:signal x: std_logic_vector(7 downto 0) := "00100010";signal i: integer range 0 to 7 := 4;

• When the signal with initial value is used as the output of the sequential process (i.e. it represents the flip-flop) the initial value will be assigned to the flip-flop during the configuration process of the FPGA. • Most FPGAs have got the flip-flop initialization during configuration functionality.

• When the initial value is not defined the flip-flop will be set to ‘0’ (Xilinx FPGAs’ property).

Initial values of signals

Page 29: VHDL in digital circuit synthesis (tutorial)

In processes conditional instruction execution is performed using following reserved words: if, then, elsif, else, end if. See example below:

-- signal s:std_logic_vector(2 downto 0);-- signal y:std_logic_vector(1 downto 0);priority_encoder: process (s) isbegin

if s(2) = '1' theny <= "11";

elsif s(1) = '1' theny <= "10";

elsif s(0) = '1' theny <= "01";

elsey <= "00";

end if;end process priority_encoder;

Conditional instruction (1)

Page 30: VHDL in digital circuit synthesis (tutorial)

Expression after the ‘case’ word is calculated and then instructions assigned to the calculated value are executed. All possible expression values must be enumerated. If it is impossible or difficult use word ‘others’ (especially needed for std_logic_vector type).

-- signal s:std_logic_vector(2 downto 0);-- signal y:std_logic_vector(1 downto 0);priority_encoder: process (s) isbegin

case s is when "111" | "110" | "101" | "100" => y <= "11"; when "011" | "010" => y <= "10"; when "001" => y <= "01"; when others => y <= "00";end case;

end process priority_encoder;

Case instruction (1)

Page 31: VHDL in digital circuit synthesis (tutorial)

For scalar and enumeration types it is allowed to use ranges (to, downto). It is allowed to use many instructions in one choice but at least one instruction must be used (it may be null instruction). After ‘when’ only constants or constant expressions can be used.

-- signal s:std_logic_vector(2 downto 0);-- signal y:std_logic_vector(1 downto 0);-- constant jeden:integer := 1;priority_encoder: process (s) isbegin

y <= "10";case CONV_INTEGER(s) is when 7 downto 4 => y <= "11";

if s = 5 then z <= 123;

end if; when 3 downto jeden + 1 => null; when jeden => y <= "01"; when others => y <= "00";end case;

end process priority_encoder;

Null instruction

Case instruction (2)

Page 32: VHDL in digital circuit synthesis (tutorial)

• Loop instruction is used for easy synthesis of many similar elements.• Synthesizable loop must have limited number of iterations.• While loop is executed when condition after ‘while’ word is true.• While and For loops can be broken using ‘exit’ instruction.

priority_encoder: process (s) isvariable i:integer;begin

i := 2;y <= "00";

L1: while i >= 0 loopif s(i) = '1' then

y <= CONV_STD_LOGIC_VECTOR(i+1, 2);exit L1;

end if;i := i - 1;

end loop L1;end process priority_encoder;

Loop instruction (1)

Page 33: VHDL in digital circuit synthesis (tutorial)

• It is not obligatory to define the iteration variable in the For loop.• Synthesizable loop must have limited number of iterations.• You can use 'range attribute to define the loop iteration range.

bit_counter: process (s) isvariable num_bits:integer range 0 to s'length;begin

num_bits := 0;L1: for i in s'range loop

if s(i) = '1' thennum_bits := num_bits + 1;

end if; end loop L1;

q <= num_bits;end process bit_counter;

Loop instruction (2)

Page 34: VHDL in digital circuit synthesis (tutorial)

• Use the ‘next’ instruction to brake single iteration without exiting the loop – just next iteration is started.• Synthesizable loop must have limited number of iterations.

-- signal s:std_logic;-- signal crc_in, crc_out:std_logic_vector(31 downto 0);crc32_logic: process (s, crc_in) isconstant coef:std_logic_vector(31 downto 0) := "0000_0100_1100_0001_0001_1101_1011_0111";variable tmp:std_logic;begin for i in 0 to 31 loop if i = 0 then tmp := crc_in(31); else tmp := crc_in(i-1); end if; crc_out(i) <= tmp; if coef(i) = '0' then next; end if; crc_out(i) <= tmp xor s; end loop;end process crc32_logic;

c(x) = 1 + x + x2 + x4 + x5 + x7 + x8 + x10 + x11 + x12 + x16 + x22 + x23 + x26 + x32

Loop instruction (3)

Page 35: VHDL in digital circuit synthesis (tutorial)

Shift registers• Using sll, srl, sla, sra, rol, ror operators for shift registers synthesis is not recommended (those operators work for bit_vector type only).• Below a recommended method of shift register synthesis is presented (16-bit right and left shift registers with serial input/output and parallel load). Rotating registers can be synthesized in the same way.

shift_regs: process(clk, rst)begin if rst = '1' then reg_l <= (others => '0'); reg_r <= (others => '0'); elsif rising_edge(clk) then if load = '1' then reg_l <= data_l; reg_r <= data_r; else serial_data_out_l <= reg_l(15); reg_l(15 downto 1) <= reg_l(14 downto 0); reg_l(0) <= serial_data_in_l; serial_data_out_r <= reg_r(0); reg_r(14 downto 0) <= reg_r(15 downto 1); reg_r(15) <= serial_data_in_r; end if; end if;end process;

Page 36: VHDL in digital circuit synthesis (tutorial)

Clocks in FPGAs have to be designed carefully:

1. Use one clock in the design if possible.2. Use external clock or generate it using single divider.3. When using divider remember to generate clock directly from FF

output not from combinatorial logic!4. If you need more clock domains use Digital Clock Managers to

generate needed clocks and keep them synchronous.5. Remember that clock resources are limited.6. If you need clock domains from independent clock sources

remember to carefully design the data transfer between those clock domains (use FF synchronizers, asynchronous FIFO, two-port memories etc.).

Clocks in FPGA

Page 37: VHDL in digital circuit synthesis (tutorial)

State machines (1)

Transition function

State

registers

Output function

Input

CLK RESET

Output

Connection for Mealy

state machine

• Moore and Mealy state machines can be easily implemented in VHDL.

• Blue blocks are implemented using sequential synchronous processes.

• Orange blocks are implemented using combinatorial processes.

• Two orange blocks can be implemented in one combinatorial process.

Page 38: VHDL in digital circuit synthesis (tutorial)

State machines (2)

• To synthesize state variable enumerated type is usually used:

type StateType is (idle, operate, finish);signal present_state, next_state : StateType;

• It is possible to change the default state representation:- globally using synthesizer options,- locally using attributes of state variable (Xilinx example):attribute fsm_encoding: string;attribute fsm_encoding of present_state: signal is "compact";-- "{auto|one-hot|compact|gray|sequential|johnson|user}"

• It is possible to use user defined state representation (for fsm_encoding = user):type statetype is (ST0, ST1, ST2, ST3);attribute enum_encoding of statetype : type is "001 010 100 111";signal state1 : statetype;signal state2 : statetype;

Page 39: VHDL in digital circuit synthesis (tutorial)

State machines (3)

-- Moore state machine-- example

type StateType is (idle, operate, finish);signal present_state : StateType;signal next_state : StateType;

seq: process (reset, clk) isbegin if (reset = '1') then present_state <= idle; elsif rising_edge(clk) then present_state <= next_state; end if;end process seq;

comb: process (present_state, go, brk, cln, rdy) isbegin case present_state is when idle => if (go = '1') then next_state <= operate; else next_state <= idle; end if; power <= '0'; direction <= '0'; when operate => if (brk = '1') then next_state <= idle; elsif (cln = '1') then next_state <= finish; else next_state <= operate; end if; power <= '1'; direction <= '0'; when finish => if (rdy = '1') then next_state <= idle; else next_state <= finish; end if; power <= '1'; direction <= '1'; end case;end process comb;

Page 40: VHDL in digital circuit synthesis (tutorial)

State machines (4)

-- Mealy state machine-- example

type StateType is (idle, operate, finish);signal present_state : StateType;signal next_state : StateType;

seq: process (reset, clk) isbegin if (reset = '1') then present_state <= idle; elsif rising_edge(clk) then present_state <= next_state; end if;end process seq;

comb: process (present_state, go, brk, cln, rdy, emergency_off) isbegin -- default value to avoid latches: next_state <= present_state; case present_state is when idle => if (go = '1') then next_state <= operate; end if; power <= '0'; direction <= '0'; when operate => if (brk = '1') then next_state <= idle; elsif (cln = '1') then next_state <= finish; end if; power <= not (emergency_off or brk); direction <= '0'; when finish => if (rdy = '1') then next_state <= idle; end if; power <= not emergency_off; direction <= '1'; end case;end process comb;

Page 41: VHDL in digital circuit synthesis (tutorial)

State machines (5)

Transition function

State

registers

Output function

input

CLK RESET

output

Output registers

synchronous output Mealy state machine

• Blue blocks are implemented using sequential synchronous processes.

• Orange blocks are implemented using combinatorial processes.

• It is possible to synthesize synchronous output Mealy machine in one sequential process because machine’s output is taken directly from the FF outputs.

Page 42: VHDL in digital circuit synthesis (tutorial)

State machines (6)

-- synchronous output Mealy-- state machine example-- (coded in single process)

type StateType is (idle, operate, finish);signal fsm_state : StateType;

sync_mealy: process (reset, clk) isbegin if reset = '1' then fsm_state <= idle; power <= '0'; direction <= '0'; elsif rising_edge(clk) then

case fsm_state is when idle => if (go = '1') then fsm_state <= operate; power <= '1'; end if; when operate => if (brk = '1') then fsm_state <= idle; power <= '0'; elsif (cln = '1') then fsm_state <= finish; direction <= '1'; end if; when finish => if (rdy = '1') then fsm_state <= idle; power <= '0'; direction <= '0'; end if; end case;end process sync_mealy;

Page 43: VHDL in digital circuit synthesis (tutorial)

State machines (7)

Forbidden states

• Usually state machines are not synthesized to automatically get out of forbidden states. For mission-critical systems it is possible to enable special option in synthesizer to enable safe machine synthesis (but usually that means much larger transition logic and slower clock).

• Other methods for safe state machine synthesis:

1. Use direct state encoding (use user defined states or use std_logic_vector for state definition) and specify behavior of the machine for all possible (valid and invalid) states.

2. Add logic for detection of invalid states which triggers reset.

Page 44: VHDL in digital circuit synthesis (tutorial)

State machines (8)

-- Example of direct state encoding:

signal present_state, next_state : std_logic_vector(2 downto 0);constant idle : std_logic_vector(2 downto 0) := "000";constant prepare : std_logic_vector(2 downto 0) := "001";constant operate : std_logic_vector(2 downto 0) := "010";constant finish : std_logic_vector(2 downto 0) := "100";constant failure : std_logic_vector(2 downto 0) := "111";

-- specify behavior for forbidden states:when others => next_state <= idle;

-- you can easily revert to optimal (not safe) version of machine:when others => next_state <= "---";

Page 45: VHDL in digital circuit synthesis (tutorial)

State machines (9)

-- Detection of forbidden states-- for state machines with one-hot state encoding:

idl <= state = idle;prepar <= state = prepare;operat <= state = operate;finis <= state = finish;failur <= state = failure;

inv <= (idl and (prepar or operat or finis or failur)) or (prepar and (operat or finis or failur)) or (operat and (finis or failur)) or (finis or failur) or (not (idl or prepar or operat or finis or failur));

....if (inv = '1') then state <= idle;else ........

Page 46: VHDL in digital circuit synthesis (tutorial)

State machines (10)

How to avoid entering forbidden or wrong state ?Most common causes of state machine failures:• Clock frequency is too high (reduce critical path delay or clock frequency).• Signals entering state machine are not synchronous to the machine’s clock (signals generated from external devices like pushbuttons, sensors, interrupt lines, busses are usually asynchronous).

Different propagation delays of signals inside the combination logic can cause the asynchronous signal change not to achieve all the FF inputs before active clock edge.

Asynchronous input

D

D

Q

Q

3-gate path: high delay

1-gate path: low delay

Page 47: VHDL in digital circuit synthesis (tutorial)

State machines (11)

How to avoid entering forbidden or wrong state ?

To avoid wrong FF operation you have to synchronize the input signal with the local clock domain. To achieve that you have to send the asynchronous signal through a pipe of two FFs. One FF is not enough because the metastability event in FF can occur.

If you send multibit (vector) signals in this way use Gray coding or use any other method for error checking.

Asynchronous input

D Q D

D Q

Q D Q

Page 48: VHDL in digital circuit synthesis (tutorial)

• Constants can be defined inside entities, architectures, processes and packages:

constant x: std_logic_vector(7 downto 0) := "00100010";constant y: std_logic_vector(7 downto 0) := ( others => '1');constant i: integer := 4;type state_type is (clear, initiate, run, stop);constant state_stop: state_type := stop;

• Constants are useful for design configuration. You can define the size of the busses, counters, etc.

• Alias names can be assigned to a part of the vector to make a partial vector access easier:

signal iw: std_logic_vector(28 downto 0);alias opcode: std_logic_vector(4 downto 0) is iw(28 downto 24);alias src: std_logic_vector(7 downto 0) is iw(23 downto 16);alias dst: std_logic_vector(7 downto 0) is iw(15 downto 8);alias arg: std_logic_vector(3 downto 0) is iw(7 downto 4);alias option: std_logic_vector(2 downto 0) is iw(3 downto 1);alias reserved: std_logic_vector(3 downto 0) is iw(3 downto 0);

Constants and aliases

Page 49: VHDL in digital circuit synthesis (tutorial)

• Attributes can be defined for entities, architectures, types and signals.type cnt is integer range 0 to 127;type state is (idle, start, stop, reset);type word is array(15 downto 0) of std_logic;• Sample attributes predefined for types and signals: 'left 'right 'high 'low 'lengthcnt'left = 0; state'left = idle; word'left = 15;cnt'right = 127; state'right = reset; word'right = 0;cnt'high = 127; state'high = reset; word'high = 15;cnt'low = 0; state'low = idle; word'low = 0;cnt'length = 128; state'length = 4; word'length = 16;• Sometimes the 'range attribute can be useful – it reveals the range and direction of the vector indexing, for example: word'range = 15 downto 0;• Another useful attribute 'event allows detection of a signal change. It can be used for synchronous circuits synthesis.• 'pos attribute returns the position the argument holds on the enumerated type list, for example: state'pos(start) = 1; character'pos('A') = 65;• 'val attribute is for the reverse operation, for example: state'val(2) = stop; character'val(66) = 'B';• 'pos and 'val attributes can be used for character to ASCII code conversion and for reverse operation.

Attributes

Page 50: VHDL in digital circuit synthesis (tutorial)

3-state buffers can be implemented on the external interface signals of the FPGA only. These buffers can be used for a bidirectional communication with external ICs. For 3-state buffers use a combinatorial process and a metalogic value ‘Z’:

-- signal i,o,ena:std_logic;process (i,ena) isbegin

if ena = '1' theno <= i;

elseo <= 'Z';

end if;end process;

You can also use a conditional assignment:

-- signal i,o:std_logic_vector(127 downto 0);-- signal ena: std_logic;o <= i when ena = '1' else 'Z';

3-state buffers implementation

Page 51: VHDL in digital circuit synthesis (tutorial)

• Design entities can be used mutiple times in the same project.• Entire design can be composed of components implemented using different abstraction levels.• Design entities – components – can be implemented in separate files, packages and included in the project when needed.• „entity” construct is an interface of the design unit.• „component” construct is a usage declaration of the previously created entity.• „port map” construct is an instantiation of the previously declared component.

component bufor port( d, enable: in std_logic; q: out std_logic);end component bufor;.....begin.....buf1: bufor port map(res,ena,outp(0));buf2: bufor port map(ack,ena,outp(1));

Entity A

Entity B

Entity C Entity B

Entity D

Top level entity

Entity C

Design hierarchy (1)

Page 52: VHDL in digital circuit synthesis (tutorial)

• Example – 1-bit adder:entity fulladder is port( a,b,cin: in std_logic; sum,cout: out std_logic);end entity fulladder;architecture dataflow of fulladder isbegin sum <= a xor b xor cin; cout <= (a and b) or (a and cin) or (b and cin);end architecture dataflow;

• 1-bit adder used for synthesis of 4-bit adder:entity adder_4 isport(a,b: in std_logic_vector(3 downto 0); cin: in std_logic; sum: out std_logic_vector(3 downto 0); cout: out std_logic);end entity adder_4;architecture structural of adder_4 iscomponent fulladder port(a,b,cin:in std_logic; sum,cout:out std_logic);end component fulladder;signal c0,c1,c2: std_logic;beginfa0: fulladder port map(a(0),b(0),cin,sum(0),c0);fa1: fulladder port map(a(1),b(1),c0,sum(1),c1);fa2: fulladder port map(a(2),b(2),c1,sum(2),c2);fa3: fulladder port map(a(3),b(3),c2,sum(3),cout);end architecture structural;

Design hierarchy (2)

Page 53: VHDL in digital circuit synthesis (tutorial)

• Component port signals can be connected in any sequence when port names are specified.• „open” means that component’s output signal is not used.• Input signals when left open must have a default value defined in the component declaration.

fa2: fulladder port map(a(2),b(2),c1,sum(2),c2);fa2: fulladder port map(b=>b(2), a=>a(2), sum=>sum(2), cout=>c2, cin=>c1);fa2: fulladder port map(a(2),b(2),c1,sum(2),open);fa2: fulladder port map(b=>b(2), a=>a(2), sum=>sum(2), cout=>open, cin=>c1);

• Types and vector ranges of component signals and local signals must match (like in assignment instruction).

entity borg is port(a: in std_logic_vector(3 to 7));end entity borg;------------------------------------------------------------component borg port(a:in std_logic_vector(10 downto 6));end component borg;

Design hierarchy (3)

Page 54: VHDL in digital circuit synthesis (tutorial)

• When „unconstrained” vector is used in the component declaration you can connect a vector of the same base type but with any length and index range. The architecture of the component must be aware of this and must use attributes to synthesize the component automatically matched to the input and output vectors.

entity borg is port(a: in std_logic_vector);end entity borg;

------------------------------------------------------------

component borg port(a:in std_logic_vector(567 downto 123));end component borg;

• Remember to properly set the direction specifiers when connecting components (in, out, inout, buffer).• You can pass parameters to the components using the „generic” declaration.

Design hierarchy (4)

Page 55: VHDL in digital circuit synthesis (tutorial)

entity adder_n is generic (size : integer := 4 ); port (a,b :in std_logic_vector(size-1 downto 0); sum :out std_logic_vector(size-1 downto 0); cout :out std_logic);end adder_n;

• Default parameters value can be changed in the component declaration:component adder_n is generic (size : integer := 8 ); port (a,b :in std_logic_vector(size-1 downto 0); sum :out std_logic_vector(size-1 downto 0); cout :out std_logic);end adder_n;

• You can change parameters during component instantiation: fa2: adder_n generic map(size=>12) port map(a,b,sum,carry);

fa3: adder_n generic map(14) port map(sum=>s, a=>d1, b=>d2, carry=>p);

Default value of the parameter (optional).

You can use parameters as soon as they are defined.

Parameters in design units

Page 56: VHDL in digital circuit synthesis (tutorial)

• To automatically repeat synthesis of the instructions in the concurent part of the architecture you can use the „generate” instruction (this is equivalent to the „for” loop in processes). You can automatically instantiate components this way.

entity fulladder_n is generic (size : integer := 4); port(a,b : in std_logic_vector(size-1 downto 0); sum:out std_logic_vector(size-1 downto 0); cin:in std_logic; cout:out std_logic);end entity fulladder_n;

architecture dataflow of fulladder_n issignal c:std_logic_vector(size downto 0);beginc(0) <= cin;G: for i in 0 to size-1 generate sum(i) <= a(i) xor b(i) xor c(i); c(i+1) <= (a(i) and b(i)) or (a(i) and c(i)) or (b(i) and c(i)); end generate;cout <= c(size);end architecture dataflow;

The label is mandatory!

The i variable is automatically defined

Generate instruction (1)

Page 57: VHDL in digital circuit synthesis (tutorial)

• The „generate” instruction is used to automatically generate regular structures based on a template structure.• Inside the „generate” loop any concurent instruction can be used including the „generate” itself.• There is also the concurent ”if” instruction which can be used for irregular structures and conditional synthesis.

Generate instruction (2)

Page 58: VHDL in digital circuit synthesis (tutorial)

• Generation of irregular structures (half adder used for LSB – no carry input):

entity adder_n is generic (size : integer := 4 ); port (a,b: in std_logic_vector(size-1 downto 0); sum: out std_logic_vector(size-1 downto 0); cout: out std_logic);end adder_n;

architecture dataflow of adder_n iscomponent fulladder port(a,b,cin:in std_logic; sum,cout:out std_logic);end component fulladder;signal c:std_logic_vector(size downto 1);beginG1: for i in 0 to size-1 generateG2: if i=0 generate sum(i)<=a(i) xor b(i); -- halfadder c(i+1)<=a(i) and b(i); end generate; -- else and elsif are not allowed!!!G3: if i>0 generatefa: fulladder port map(a(i),b(i),c(i),sum(i),c(i+1)); end generate; end generate; cout <= c(size);end architecture dataflow;

Generate instruction (3)