You are here

VHDL - Reference

-- Literatur: Vorlesungsunterlagen EDS2 von Markus Pfaff (FH-Hagenberg)
 
-- VHDL   Vhsic Hardware Description Language
-- VHSIC  Very High Speed Integrated Circuits
 
-- entity / architecture
        entity PieceOfHw is
            generic (
                gAddrWidth : integer := 10;
                gDataWidth : integer := 8
            );
            port (
                iClk       : in  bit;
                inResAsync : in  bit;
                iCountUp   : in  bit;
                oCounter   : out integer
                -- wie Signals zu behandeln
                -- (durch in, out, inout eingeschraenkt)
            );
        end entity PieceOfHw;
 
        architecture PieceOfHwBhv of PieceOfHw is
            -- Deklarationen
 
            signal vTemp0 : integer;
        begin
            -- Struktur und/oder Verhaltensbeschreibung
 
            CalcSomething: process is
                -- lokale Deklarationen
 
                variable vTemp1 : integer;
            begin
                vTemp1 := iTempInput + 2;       -- von Ausserhalb
                wait;
            end process CalcOtherPeople;
 
        end architecture PieceofHwBhv;
 
        -- die Architektur sollte in einem separaten Datei abgelegt werden,
        -- da es fuer eine Entity mehrere Implementierungen (Bhv, Rtl)
        -- geben kann
 
 
-- Entities "verdrahten"
        library Work;                           -- Library bekannt machen
 
        Timer1: entity Work.PieceOfHw(PieceOfHwBhv)
            generic map(
                gAddrWidth => 10,
                gDataWidth => 16
            )
            port map(
                iClk       => sClk,
                inResAsync => snRes,
                iCountUp   => sCntUp,
                oCounter   => sCntr
            );
 
 
-- diverse Deklarationen
        variable vTemp2 : integer := 0;     -- initiale Wert
        constant vTemp3 : integer := 12;    -- Konstante (muss initalisiert
                                            -- werden, ist nicht schreibbar)
 
                       -- integer              0, -2, 1E6, 1000000
                       -- real                 1.0, 0.0, 1.0E+30, -3.32E-10
                       -- character            'a', 'B', '1', '@'
                       -- boolean              false, true
                       -- string               "many characters."
                       -- bit                  '0', '1'
                       -- time                 10 ns, 20 hr, 30 ps, 40.3 s
 
                       -- character'('0')      explizite Zuordnung
                       -- bit'('0')
 
        type aOwnType1 is range -256 to 255;    -- selbst definierte Typen
        type aOwnType2 is (SideA, SideB, SideC);
        type aOwnType3 is (
            'a',
            '1',
            a,
            1,
            asdf
        );
 
                                                -- abgeleiteter Typ
        subtype aSignedByte is integer range -128 to 127;
 
        -- unconstrained array types - Array Typen ohne Bereichsangabe
        type string is array (positive range <>) of character;
        -- constrained array types - Array Typen mit Bereichsangaben
        subtype aAddress is range (0 to 255);
        type aByte   is array (7 downto 0) of bit;
        type aMemory is array (aAddress) of aByte;
 
 
-- Zuweisung
        type aRegister is array (1 to 4) of integer;
        variable vXReg : aRegister := (0, 0, 0, 0);
        vXReg := (1=>12, 2=>234, others=>0);
 
        variable vBitVector1 : bit_vector(31 downto 0);
        variable vBitVector2 : bit_vector(15 downto 0);
        variable vBitVector3 : bit_vector(1 to 4);
        vBitVector1(0) := vBitVector2(15);
        vBitVector2 := vBitVector1(15 downto 0);
        vBitVector2 := vBitVector1;     -- Zuordnung von links nach rechts
                                        -- (15) := (31)
                                        -- (14) := (30)
                                        -- ...
                                        -- (0)  := (16)
        vBitVector3 := vBitVector2;     -- (1)  := (15)
                                        -- (2)  := (14)
                                        -- (3)  := (13)
                                        -- (4)  := (12)
 
 
-- Rocord Typen
        type aRecord is record
            Description      : string;
            Code             : bit_vector (7 downto 0);
            NrOfAddressBytes : natural;
        end record aRecord;
 
        constant cRec1 : aRecord := (
            Description      => "asdf",
            Code             => "10011111",
            NrOfAddressBytes => 0
        );
        variable vRec2 : aRecord;
 
        vActDescr := cRec1.Description;
        vRec2     := cRec1;
 
 
-- Zusammenstellungen (Concatenation)
        variable vABus, vBBus, vCBus : bit_vector (3 downto 0);
        variable vA, vB, vC, vD : bit;
        vABus := vA & vB & vC & vD;         -- von links nach rechts
        vABus := vBBus(3 downto 2) & vCBus(1 downto 0);
        vABus := (vBBus(3 downto 2), vCBus(1 downto 0));
 
 
-- logische Operatoren
        -- and, or, nand, nor, xor, xnor, not
        vBit1 := vBit2 and vBit3;
        vBool1 := vBool2 nor vBool3;
        -- vBool1 := vBit2 and vBit2;       -- boolean und bit nicht mischen
 
 
-- relationale Operatoren
        -- >, >=, <, <=, =, /=   liefert boolean
        vBool1 := (1 < 3);
 
        variable vShort : bit_vector(4 to 6) := ('1', '0', '1');
        variable vLong  : bit_vecotr(0 to 7) := (1=>'1', others=>'0');
        vBool2 := vShort > vLong;
        -- von links nach rechts
        -- 1 0 1           : groesser
        -- 0 1 0 0 0 0 0 0 : kleiner
 
 
-- arithmetische Operatoren
        -- -, +, *, /, mod, rem, **(Hochfunktion), abs
        -- fuer integer, real(nicht mod, rem), time
 
        -- a mod b  -> positiver Rest
        -- a rem b  -> Rest hat Vorzeichen von a
 
 
-- Schiebeoperationen
        sll  -- shift left logical         "11110000" sll 2 => "11000000"
        srl  -- shift right logical        "00001111" srl 2 => "00000011"
        sla  -- shift left arithmetic      "00001111" sla 2 => "00111100"
        sra  -- shift right arithmetic     "00111111" sra 2 => "00001111"
             --                       bzw. "11110000" sra 2 => "11111100"
        rol  -- rotate left                "00110011" rol 2 => "11001100"
        ror  -- rotate right               "11001100" ror 2 => "00110011"
 
-- Attribute
        subtype SmallInt is integer range 0 to 2356;
        -- SmallInt'left = 0
        -- SamllInt'right = 2356
        -- SmallInt'range = 0 to 2356
 
        signal BinNr : bit_vector (31 downto 0);
        -- BinNr'left = 31
        -- BinNr'right = 0
        -- BinNr'low = 0
        -- BinNr'high = 31
        -- BinNr'range = 31 downto 0
        -- BinNr'length = 32
 
        signal Flag : bit;
        -- Flag'event      ... Event aufgetreten?
        -- Flag'stable(T)  ... waehrend des Zeitraums stabil?
        -- Flag'active     ... momentan aktiv?
        -- Flag'delayed(T) ... Kopie von Flag, um T verzoegert
        -- Flag'last_event, Flag'last_active, Flag'last_value
 
 
-- diverse Ablauf-Statements
        -- if
        if (vA > vB) and (vA < vC) then
            vGr := vA;
        elsif (vD > vF) then
            vGr := vD;
        else
            vGr := vB;
        end if;
 
 
        -- case
        type aState is (stateA, stateB, stateC, stateD);
        variable vActState : aState;
        case vActState is
            when stateA =>
                vTemp1 := 12;
            when stateB =>
                vTemp1 := 24;
            when others =>
                null;
        end case;
 
 
        -- while Schleife
        while (vIndex <= 3) loop
            -- ...
            vIndex := vIndex + 1;
        end loop;
 
        -- for Schleife
        for vIndex in 8 downto 0 loop
            -- ...
        end loop;
 
        -- endlos Schleife
        loop
            -- ...
        end loop;
 
 
-- Assertion / Report
        assert (vSomethingGoesWrong = false)
            report "output message"
            severity warning;
                -- note
                -- warning
                -- error
                -- failure
 
        report "output message"
            severity warning;
 
 
-- Funktion
        -- Werte werden eingegeben und ein Ergebnis wird zurueck geliefert
        -- Eingabewerte sind im Inneren konstant
        function Larger (cVal1, cVal2 : integer) return integer is
            variable vResult : integer;
        begin
            if cVal1 > cVal2 then
                vResult := cVal1;
            else
                vResult := cVal2;
            end if;
            return vResult;
        end function Larger;
 
        vRes := Larger(vVar1, vVar2);
 
 
-- Prozedur
        -- Werte ein- oder ausgeben
        procedure Swap ( variable vA, vB : inout integer;
                         constant cPermitSwap : boolean ) is
            variable vTemporal : integer;
        begin
            if cPermitSwap then
                vTemporal := vA;
                vA := vB;
                vB := vTemporal;
                return;
            end if;
        end procedure Swap;
 
        Swap(vVar1, vVar2, true);
 
 
-- Simulationszeit
        wait;                       -- fuer immer warten
        wait for 14 ms;             -- fuer 14ms warten
        wait on sA, sB;             -- auf Aenderung von sA oder sB warten
        wait on sA for 14 sec;      -- warte auf Event sA, max. 14 Sekunden
        wait on sA until sA > 3;    -- warte auf Event sA, mit Bedingung sA>3
        wait until sA > 3;          -- -,,-
        wait on sA, sB until sA = 10 for 16 us;
 
        sA <= transport sB after 14 us; -- Simulation von Verzoegerungs-
                                        -- zeiten (propagation delay)
                                        -- Simulation von Traegheitszeiten
                                        -- (inertial delay)
                                        -- Wert muss mindestens 5 ns lang
                                        -- anders sein, um uebernommen
                                        -- zu werden
        sA <= reject 5 ns inertial sB after 10 ns;
 
        sA <= reject 5 ns inertial sB after 5 ns; -- =
        sA <= inertial sB after 5 ns;             -- =
        sA <= sB after 5 us;
        sA <=
            '0' after 10 ns,
            '1' after 30 ns,
            '0' after 90 ns;
 
 
-- shared Variables (nicht brauchbar)
        -- Ergebnis ist nicht definiert, kommt darauf an welcher Prozess
        -- zuerst abgearbeitet wird. Es werden beide Variablen vA oder vB,
        -- da shared varible den Wert immer direkt uebernehmen.
        entity Swapper is
        end entity Swapper;
        architecture SwapperBhv of Swapper is
            shared variable vA : integer := 10;
            shared variable vB : integer := 13;
        begin
            MakeA2B: process is
            begin
                wait for 1 ms;
                vA := vB;
            end process MakeA2B;
 
            MakeB2A: process is
            begin
                wait for 1 ms;
                vB := vA;
            end process MakeB2A;
        end architecture SwapperBhv;
 
 
-- signals
        -- fuer eine bestimmte Zeit werden alle vorherigen Werte zwischen-
        -- gespeichert und mit den gespeicherten Werten werden alle Signals
        -- neu berechnet.
        entity Swapper is
        end entity Swapper;
        architecture SwapperBhv of Swapper is
            signal vA : integer := 10;
            signal vB : integer := 13;
        begin
            MakeA2B: process is
            begin
                wait for 1 ms;
                vA <= vB;
            end process MakeA2B;
 
            MakeB2A: process is
            begin
                wait for 1 ms;
                vB <= vA;
            end process MakeB2A;
        end architecture SwapperBhv;
 
 
-- postponed process
        -- Wir sind nur fuer die stabilisierten Werte interessiert.
        -- (ignoriert delta-Cycles)
        TestFinalValues : postponed process is
        begin
            assert (A < B)
                report "TM: A and  B don ’t  relate  as  desired !"
                severity warning;
            wait on A, B;
        end postponed process TestFinalValues;
 
 
-- Generate Statement
        OthrStgs : for Stage in
            FilteredThrough'left to
            FilteredThrough'right-1 generate
        begin
            OneOtherStage : entity Work.Filter(SomehowElse)
                port map (
                    iNoisy => FilteredThrough(Stage),
                    oCalm  => FilteredThrough(Stage+1)
                );
        end generate OtherStages ;
 
 
        MayDefuzzyfy : if DefuzzyfyIt generate
        begin
            Defuzzyfying : entity Work.Defuzzyfier(Anyhow)
                port map (
                    iFuzzy => FilteredThrough(FilteredThrough’length),
                    oClean => oFiltered
                );
        end generate MayDefuzzify;
 
 
-- Component Instantiation
        architecture Structure of Any is
            -- Komponente Deklarieren
            component Stacker is
                port (
                    iClk       : in bit;
                    inResAsync : in bit;
                    ...
                );
            end component Stacker;
 
            -- Konfiguration Spezifizieren
            for TheStacker1 use entity work.AStack(Somehow)
                port map (
                    iClk       => iClk,
                    inResAsync => inResAsync,
                    ...
                );
        begin
            -- Komponente Instanzieren
            TheStacker1: Stacker
                generic map (...)
                port map (...);
        end architecture Structure;
 
 
-- Package Deklarieren
        package ProjectGlobal is
            constant cBitwidth : integer := 8;
            type aBinaryNr is bit_vector (cBitWidth-1 downto 0);
            subtype aIntNr is integer range 0 to 2**cBitwidth-1;
 
            function Bin2Int (cBinary : aBinaryNr) return aIntNr;
            procedure Swap (vBinary1, vBinary2 : inout aBinaryNr);
 
            constant cDecidedOk : boolean;
        end package ProjectGlobal;
 
 
        package body ProjectGlobal is
            constant cDecidedOk : boolean := true;
 
            function Bin2Int (cBinaryNr : aBinaryNr) return aIntNr is
                variable vAccumulated : integer := 0;
            begin
                for Digit in cBinaryNr'range loop
                    if cBinaryNr(Digit) = '1' then
                        vAccumulated := vAccumulated + 2**Digit;
                    end if;
                end loop;
                return vAccumulated;
            end function Bin2Int;
 
            procedure Swap (vBinary1, vBinary2 : inout aBinaryNr) is ...
        end package body ProjectGlobal;
 
 
-- Package nutzen
        library IEEE;               -- in welcher Lib. befinded sich Package
        use IEEE.std_logic_1164;    -- Package Deklarationen sichtbar machen
        use IEEE.std_logic_1164.all;
 
        library std;                -- Standard Library fuer vordefinierte
                                    -- Sprach-Umgebung
        library work;               -- Standard User Library
        use std.standard.all;       -- Deklaration von vordefinierten
                                    -- Typen und Operationen
 
        library IEEE;               -- Standard Library fuer standardisierte
                                    -- Sprach-Erweiterung
        use IEEE.std_logic_1164.all;-- 9-wertige Logic Typen und
                                    -- verfuegbare Operationen
                                    -- 'U' ... uninitialisiert
                                    -- 'X' ... Wert unbekannt (Fehler)
                                    -- '-' ... egal ob durch '0' oder
                                    --         '1' ersetzt wird
                                    -- '0', '1'
                                    -- 'Z' ... high Impedanz
                                    -- 'L' ... low
                                    -- 'H' ... high
                                    -- 'W' ... weak
        std_ulogic_vector           -- unresolved Datentyp (wird Signal an
                                    -- mehreren Stellen geschrieben, so
                                    -- wird Error gemeldet)
        std_logic_vector            -- resolved Datentyp
 
 
-- Sensitivity List
        DoIt: process is
        begin
            -- ...
            wait on A, B, C, D, ...
        end process DoIt;                       -- =
 
        DoIt: process (A, B, C, D, ...) is
        begin
            -- ...
        end process DoIt;
 
 
-- Concurrent Assertion-Statement
        TestIt: process is
        begin
            assert (A > B)
                report "message"
                severity warning;
            wait on A, B;
        end processs TestIt;                    -- =
 
        assert (A > B)
            report "message"
            severity warning;
 
 
-- Concurrent Signal-Assignment
        LabelIt: process is
        begin
            SesamStreet <= Ernie and Bert after 20 us;
            wait on Ernie, Bert;
        end process TestIt;                     -- =
 
        LabelIt: SesamStreet <= Ernie and Bert after 20 us;
 
-- Concurrent Conditional Signal-Assignment
        Labeled: process is
        begin
            if A < B then
                SesamStreet <= Ernie and Bert;
            elsif A = B then
                SesamStreet <= Bibo;
            else
                SesamStreet <= Gonzo;
            end if;
            wait on A, B, Ernie, Bert, Bibo, Gonzo;
        end process TestIt;                     -- =
 
        Labeled: SesamStreet <=
            Ernie and Bert when (A<B) else
            Bibo           when (A=B) else
            Gonzo;
 
 
-- Concurrent Selected Signal-Assignment
        ALabel: process is
        begin
            case Month is
                when May =>
                    SesamStreet <= Ernie and Bert;
                when Jun | Oct =>
                    SesamStreet <= Bibo;
                when others =>
                    SesamStreet <= Gonzo;
            end case;
            wait on Month, Ernie, Bert, Bibo, Gonzo;
        end process TestIt;                     -- =
 
        ALabel: with Month select
            SesamStreet <= Ernie and Bert when May,
            Bibo                          when Jun | Oct,
            Gonzo                         when others;
 
 
-- Concurrent Procedure-Call
        Calling: process is
        begin
            CheckTiming (D, Clk, Reset, TSetup, THold);
            wait on D, Clk, Reset;
        end processs TestIt;                    -- =
 
        Calling: CheckTiming (D, Clk, Reset, TSetup, THold);