From VHDL to FPGA

36  Download (0)

Full text

(1)

From VHDL to FPGA

#1: VHDL simulation

Jason Agron

University of Kansas

Enno Lübbers

University of Paderborn

jagron@ittc.ku.edu, enno.luebbers@upb.de

(2)

Field-Programmable Gate Arrays (FPGAs)

Fine-grained reconfigurable hardware

Gate-Array: regular structure of “logic cells”, connected

through an interconnection network

Configuration stored in SRAM, must be loaded on startup

(3)

Modern FPGAs provide lots of logic resources

Virtex-5: up to 330,000 logic cells

DSP blocks, multipliers, block RAM, ...

Manual design simply unmanageable

(4)

What is VHDL?

VHDL (Very high speed integrated logic Hardware

Description Language)

Developed in the 1980s and 1990s as a documentation language for

(digital) hardware as an alternative to complex manuals

Soon logic simulators appeared to simulate (= verify the behaviour)

these ‘documents’

Now mainly used as a design entry language for digital logic

synthesizers to generate hardware

document

= describe

simulate

= verify

(5)

Overview

VHDL as a modelling language

Modules

Testbenches

VHDL simulation

Tools

Xilinx ISE

ModelSim

VHDL synthesis

Tool Flow

Hardware

Spartan-3E development board

Tools

Xilinx ISE

Xilinx iMPACT

(6)

VHDL modules

my_module

A module can have

Ports

Inputs

Outputs

Parameters (“generics”)

This interface is described by an

entity my_module is

in

pu

ts

i_a

i_b

ou

tp

ut

s

o_c

o_d

parameters

G_MYPARAM

port (

i_a : in std_logic;

i_b : in std_logic;

o_c : out std_logic;

o_d : out std_logic

);

generic (

G_MYPARAM : integer

);

(7)

Functional description

The function of a module is defined

By a VHDL description of the module’s

behaviour, or

By assembling the module from other modules

(which is a description of its structure)

my_module

in

pu

ts

ou

tp

ut

s

architecture behavioural

of my_module is

begin

c <= a xor b;

d <= a and b;

end behavioural;

(8)

my_module

VHDL testbenches

To verify a modules operation, we need to

Stimulate the module’s inputs

Let the module process the inputs internally

Observe the outputs

i_a

i_b

o_c

o_d

G_MYPARAM

?

my_module_tb

!

(9)

Introduction to the Xilinx

Toolset: Project Navigator (ISE)

(10)

What is Project Navigator (ISE)?

ISE is a tool that is used for…

Organizing design files.

Running processes to implement a design.

Compilation

Simulation

Synthesis

ISE is an integrated development environment (IDE).

You can create/edit sources

Create tests

Configure implementation parameters

Optimization levels

(11)

IDEs: Hardware vs. Software

Software IDE

Sources describe programs and libraries.

Testing can be done via debugging/simulation.

Usually done by stepping through the code line by line.

Compilation results in an executable.

Hardware IDE.

Sources describe entities and libraries.

Blocks with I/O ports.

Testing is done via debugging/simulation.

Usually done by providing stimulus to input ports, and watching behavior of

internal state and output ports.

The result of simulation is a waveform and I/O.

Compilation (synthesis) results in a bitstream, not an executable.

A “program” for an FPGA.

(12)

How To Get Started

Open up ISE.

Create a new ISE project.

Select “File”, “New Project”

Select the proper FPGA target, language, etc.

Click “Next” repetitively, and then click “Finish”.

(13)

Setting Up the Project Parameters

Specify the location and name of the project.

Specify the parameters of the project.

FPGA target.

Synthesis tool.

(14)

Adding Sources to the Project

Add HDL sources to the

project.

First, Create a subdirectory within

the project for the HDL sources to

be placed in (maybe called

/src/hdl).

Now, add the sources to the

project.

Select the FPGA within the

“Sources in Project” window.

Right click and select “Add

Source” or “New source”.

Add existing sources and new

sources as needed.

NOTE: Some sources can

only be made visible by

altering the “Sources For:”

parameter!

(15)

What Can Be Simulated?

An entity cannot be

simulated!

It has I/O ports

What should the simulator do for

inputs?

It is like “simulating” a video game

console without a game or

controller.

A testbench can be simulated!

A testbench is a wrapper around

an entity.

It stimulates the input ports.

The testbench itself has no I/O

ports.

It acts as a “driver”.

(16)

Starting a Simulation

Select “Behavioral Simulation”

from the “Sources For:” menu

in the top-left.

This allows the user to see:

Project testbenches.

Project UUTs = Units Under Test.

Select the testbench that is to

be simulated.

The “Processes” menu should

now have a “Simulation”

option.

Expand this option and double

click on “Simulate Behavioral

Model”.

(17)

Simulation Output: Waveform

The output of simulation is usually a waveform.

A clock-cycle accurate representation of signal behavior in the system.

A simulator “executes” the testbench.

Allowing the testbench to “drive” the UUT.

The waveform shows the behavior of signals…

As input to the UUT.

(18)

Anatomy of a Testbench

A testbench must do the

following:

Instantiate a UUT.

Define the component.

Instantiate the component.

Provide stimulus to the UUT.

Input signals

Clocks

A testbench must not do the

following:

Must not have any I/O ports.

I/O can be done via special

print statements (screen I/O

and file I/O).

These are usually simulator

(19)

Anatomy of a Testbench - Clocks

Purpose of a clock:

Periodic signal used for synchronization.

Used as a “gating” mechanism for storage devices

Registers use a clock as a signal to store.

On “every” clock edge store a new value.

Edges can be rising, falling, or both.

The clock model above is encapsulated in a process

(20)
(21)

Example: Queue (FIFO)

FIFO = First In First Out.

Operations:

Enqueue (Add to queue)

Dequeue (Remove from queue)

Status:

(22)
(23)

Datentypen

VHDL bietet spezielle Datentypen und Operatoren zur

Hardwarebeschreibung

z.B. std_logic als digitales Signal mit den Zuständen

‚U‘ : nicht initialisiert

‚X‘ : unbekannt

‚0‘ : logisch 0

‚1‘ : logisch 1

‚Z‘ : hochohmig

‚W‘ : schwaches Signal (0 oder 1)

‚L‘ : schwaches Signal, wahrscheinlich 0

‚H‘ : schwaches Signal, wahrscheinlich 1

‚-‘ : Wert irrelevant (don‘t care)

Skalare Typen

integer, natural, unsigned...

Arrays

std_logic_vector, array of integer...

Benutzerdefinierte Datenstrukturen (records)

(24)

Entity

VHDL-Modelle bestehen aus Modulen, sogenannten Entities

ähnlich wie Klassendeklarationen

beschreiben Schnittstelle der Module

entity half_adder is

port ( x : in std_logic;

-- x input

y : in std_logic;

-- y input

s : out std_logic;

-- sum output

c : out std_logic

-- carry output

);

(25)

Architecture

Die Implementation einer „entity“ wird durch eine

„architecture“ definiert:

Hier handelt es sich um eine sogenannte

Verhaltensbeschreibung

architecture behavioural of half_adder is

begin

s <= x xor y;

c <= x and y;

(26)

Strukturbeschreibung

Aus zwei Halbaddierern lässt sich ein Volladdierer

zusammensetzen:

entity full_adder is

port (

x : in std_logic;

-- x input

y : in std_logic;

-- y input

c_in : in std_logic;

-- carry input

s : out std_logic;

-- sum output

c_out : out std_logic

-- carry output

);

end full_adder;

architecture structural of full_adder is

signal a, b, c : std_logic;

begin

ha1 : half_adder port map (x => x, y => y, s => a, c => b);

ha2 : half_adder port map (x => a, y => c_in, s => s, c => c);

c_out <= b or c;

(27)

Komplexe Operatoren

Zum Addieren zweier Zahlen in Binärdarstellung können

mehrere Volladdierer zusammengeschaltet werden

VHDL kennt aber auch arithmetische Operatoren

s <= a + b;

s <= a * b;

...

Außerdem lassen sich Funktionen definieren, z.B.

crc <= crc16(x);

(28)

Prozesse

Grundlegendes Konstrukt zur Verhaltensbeschreibung:

Prozesse werden „ausgeführt“, sobald sich eines der Signale in

der sensitivity list ändert

Getaktete (synchrone) Logik

rising_edge(clk) ⇔ clk‘event and clk = ‚1‘

process(clk, reset)

begin

if reset = ‚1‘ then

output <= ‚0‘;

elsif rising_edge(clk) then

output <= input + 1;

end if;

end process;

+

Register

1

input

output

clk

reset

clear

D

Q

(29)

Parallelität

In VHDL „passiert alles gleichzeitig“

signal a, b, c, d : std_logic;

process(clk)

begin

if rising_edge(clk) then

a <= input;

b <= a;

c <= b;

d <= c;

end if;

end process;

a

b

clk

0 1 2 3 4 5 6 7 8

input(0) input(1) input(2) input(3) input(4) input(5) input(6) ...

X input(0) input(1) input(2) input(3) input(4) input(5) ...

a

Register

input

b

Register

c

Register

d

Register

clk

Signal-Zuweisung

(30)

Parallelität

Signal-Zuweisungen erfolgen “nicht-blockierend” (parallel)

Variablen-Zuweisungen erfolgen “blockierend” (sequentiell)

außerdem existieren Variablen nur innerhalb eines Prozesses

process(clk)

variable a, b, c, d : std_logic;

begin

if rising_edge(clk) then

a := input;

b := a;

c := b;

d := c;

end if;

end process;

process(clk)

variable a, b, c, d : std_logic;

begin

if rising_edge(clk) then

d := input;

end if;

end process;

Variablen-Zuweisung

(31)
(32)

Demonstration

reset

clk

bcd2seg

delay-counter

toplevel

disp

dp

an

display-counter

Daten

Dezimal-punkt

Chip

Select

50 MHz

Zähler auf

7-Segment-Anzeige

(33)

bcd2seg.vhd

-- $Id$

---- bcd2seg.vhd: BCD to 7-segment display encoder

---- Converts a BCD-coded signal to seven-segment-display

---- Author : Enno Luebbers <enno.luebbers@upb.de> -- Created: 24.04.2006

---- Major changes:

-- 24.04.2006 Enno Luebbers File created. --library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.NUMERIC_STD.ALL; entity bcd2seg is port (

i_bcd : in integer range 0 to 15; o_7seg : out std_logic_vector(6 downto 0) );

end bcd2seg;

architecture behavioral of bcd2seg is -- A -- --- F| |B -- | G | -- --- E| |C -- | D | --

---type slv_array is array(0 to 15) of std_logic_vector(6 downto 0); constant conversionTable : slv_array :=

( -- ABCDEFG "1111110", -- 0 "0110000", -- 1 "1101101", -- 2 "1111001", -- 3 "0110011", -- 4 "1011011", -- 5 "1011111", -- 6 "1110000", -- 7 "1111111", -- 8 "1111011", -- 9 "1110111", -- A "0011111", -- B "1001110", -- C "0111101", -- D "1001111", -- E "1000111" -- F ); begin o_7seg <= conversionTable(i_bcd);

(34)

counter.vhd

-- $Id$

---- counter.vhd: Counter / Generics example

---- Provides a simple up/down counter. Parameters can -- be set through generics

---- Author : Enno Luebbers <enno.luebbers@upb.de> -- Created: 24.04.2006

---- Major changes:

-- 24.04.2006 Enno Luebbers File created. --library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity counter is generic (

G_MAX : natural := 15; -- maximum range G_INIT : natural := 15; -- initial value G_UP : boolean := true -- count up? );

port (

i_clk : in std_logic; i_reset : in std_logic; i_enable : in std_logic;

o_value : out natural range 0 to G_MAX );

end counter;

architecture Behavioral of counter is signal value : natural range 0 to G_MAX; begin

-- check generics

assert G_MAX >= G_INIT report "G_INIT greater G_MAX" severity FAILURE;

count : process(i_clk, i_reset) begin

if i_reset = '1' then value <= G_INIT;

elsif rising_edge(i_clk) and i_enable = '1' then if G_UP then value <= value + 1; else value <= value - 1; end if; end if; end process; o_value <= value; end Behavioral;

(35)

toplevel.vhd

-- $Id$

---- toplevel.vhd: VHDL tutorial top level entity

---- Top level entity for Digilent Spartan-3 evaluation board

---- Author : Enno Luebbers <enno.luebbers@upb.de> -- Created: 24.04.2006

---- Major changes:

-- 24.04.2006 Enno Luebbers File created. --library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity toplevel is port ( clk : in std_logic; reset : in std_logic; -- LED display

disp : out std_logic_vector(6 downto 0); dp : out std_logic;

an : out std_logic_vector(3 downto 0) );

end toplevel;

architecture structural of toplevel is component bcd2seg

port (

component counter generic (

G_MAX : natural := 15; -- maximum range

G_INIT : natural := 15; -- initial value G_UP : boolean := true -- count up? );

port (

i_clk : in std_logic; i_reset : in std_logic; i_enable : in std_logic;

o_value : out natural range 0 to G_MAX );

end component;

constant DELAY_INIT : integer := 50000000; signal counterEnable : std_logic;

signal counterValue : integer range 0 to 15 := 0;

signal delay : integer range 0 to DELAY_INIT-1 := DELAY_INIT-1; signal displayData : std_logic_vector(6 downto 0);

begin delayCounter : counter generic map ( G_MAX => DELAY_INIT-1, G_INIT => DELAY_INIT-1, G_UP => false ) port map ( i_clk => clk, i_reset => reset, i_enable => '1', o_value => delay );

(36)

toplevel.vhd

displayCounter : counter generic map ( G_MAX => 15, G_INIT => 0, G_UP => true ) port map ( i_clk => clk, i_reset => reset, i_enable => counterEnable, o_value => counterValue ); encoder : bcd2seg port map ( i_bcd => counterValue, o_7seg => displayData );

counterEnable <= '1' when delay = 0 else '0';

disp <= NOT displayData; -- the LED display is active-low driven dp <= '1';

an <= "1010"; end structural;

Figure

Updating...

References

Related subjects :