-- 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);