Synthetisierbares VHDL Regeln & Empfehlungen
Kombinatorische Prozesse Grundstruktur Comb : PROCESS(<alle Eingänge der Logik>) BEGIN <sequential statements>; END PROCESS Comb; Regeln Alle Eingänge müssen in der Sensitivity Liste stehen „If“- , „case“ statements müssen auskodiert werden, sonst werden Speicherelemente synthetisiert Kein „wait“-Statement Kein „clk‘event“ darf verwendet werden Sonderform: concurrent statement (direkte Zuweisung in der Architecture) x <= not a and b or c and not a; Entspricht einem kombinatorischen Prozess mit den Eingängen a,b, c und wird vom Simulator genauso behandelt
Clocked Process Der “Clocked Process” wird benutzt um die Funktionalität von flankengetriggerten Speicherelementen nachzubilden. Grundform ohne Reset: DFF: process (clk) begin if clk’event and clk=‘1’ then q <= d; end if; end process DFF; Grundform mit Reset: DFF: process (clk,reset) begin if reset=‘1’ then q <= ‘0’; elsif clk’event and clk=‘1’ then q <= d; end if; end process DFF;
Clocked Process (2) Nicht synthetisierbare Varianten Verboten !! DFF: process (clk) begin if clk’event and clk=‘1’ and a=‘1’ then q <= d; end if; d <= d + 1; end process DFF; Kein sequentielles statement ausserhalb der Taktflanken-Abfrage! Die Abfrage der Taktflanke darf nicht mit einer anderen logischen Abfrage verknüpft werden Wichtig: Diese Konstrukte sind erlaubt in VHDL, werden aber von den Synthese-Tools nicht richtig interpretiert.
Übung2, Aufgabe 3
VHDL Kapitel 5 Zähler
Zähler mit nicht gewichtetem Code Inhalt Zähler Grundprinzip Beispiel Dekadenzähler Umwandlungsroutinen Ein Prozess Zähler Up/Down Zähler Zähler mit nicht gewichtetem Code
Definition des Zählers 2 3 1 4 6 5 Ein Zähler ist eine Schaltung, die nach einem Taktimpuls von einem Ausgangszustand in einen vorbestimmten anderen Zustand übergeht
RTL Beschreibung eines synchronen Zählers (RTL = Register Transfer Level) Q D !Q Q0 L0 L1 D Q Q1 !Q D Q Q2 L2 !Q Takt
Zustandsdiagramm des Würfel-Zählers Folge- Zustand Gegenwärtiger Zustand 2 3 1 4 6 5
Gegenwärtiger Zustand Zustandsdiagramm des Würfel-Zählers Gegenwärtiger Zustand Folge- Zustand 2 3 1 4 6 5
Zustandsdiagramm des Würfel-Zählers Gegenwärtiger Zustand Folge- Zustand 2 3 1 4 6 5
Grundstruktur eines synchronen Zählers Q D !Q Q0 L0 L1 D Q Q1 !Q D Q Q2 L2 !Q Takt
Prozesse des Zählers 4 4 cnt_folge cnt_gegenwart clk reset Prozess mit Kombinatorischer Logik comb_ Prozess mit getakteter Logik reg_ cnt_gegenwart 4 clk reset 4
Grundprinzip des Zählers in VHDL LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY zaehl_einfach IS PORT( clk,reset : IN std_logic; cnt_out : OUT std_logic_vector(3 downto 0) ); END zaehl_einfach; Paket mit std_logic, std_logic_vector Paket mit arithmetischen Funktionen
Grundprinzip des Zählers in VHDL ARCHITECTURE rtl OF zaehl_einfach IS SIGNAL cnt_folge: integer range 0 to 15; SIGNAL cnt_gegenwart: integer range 0 to 15; BEGIN logik : PROCESS(cnt_gegenwart) BEGIN cnt_folge <= cnt_gegenwart + 1 ; END PROCESS logik; flip_flops : PROCESS(clk, reset) BEGIN IF reset = '1' THEN cnt_gegenwart <= 0; ELSIF clk'EVENT AND clk = '1' THEN cnt_gegenwart <= cnt_folge ; END IF; END PROCESS flip_flops; cnt_out <= std_logic_vector(to_unsigned(cnt_gegenwart,4)); END rtl; Logik:Process Takt:Process Umwandlung Integer zu Vektor + Zuweisung Zwischen-Signal zum Ausgangssignal
Beispiel: Dekadenzähler Aufgabenstellung: Der Zähler soll 4-bit breit sein. Bei Reset soll der Zähler synchron auf den Hexadezimalwert 0x5 gesetzt werden. Die Zählfolge ist 0->1->2->3..9->0
Beispiel: Dekadenzähler ARCHITECTURE RTL of DekadenZaehler SIGNAL cnt_folge, cnt_gegenwart: integer range 0 to 9; BEGIN comb_logik : PROCESS(cnt_gegenwart,reset) BEGIN IF reset = '1' THEN cnt_folge <= 5 ; ELSE IF cnt_gegenwart < 9 THEN cnt_folge <= cnt_gegenwart + 1 ; ELSE cnt_folge <= 0; END IF; END IF; END PROCESS comb_logik; reg_flip_flops : PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN cnt_gegenwart <= cnt_folge ; END IF; END PROCESS reg_flip_flops; END ARCHITECTURE RTL: Handelt es sich hier um einen synchronen oder asynchronen Reset ?
Übung1 RTL Diagram vom Code zeichnen Mit getrennten Prozessen umschreiben Synchronen Reset einfügen
Übung1- Lösung
Umwandlungsroutinen
Umwandlung von Type integer in Type std_logic_vector 2 Konvertierungsroutinen: IntegerUnsignedstd_logic_vector integer std_logic_vector LIBRARY ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; signal cnt_out : std_logic_vector(3 downto 0)); signal cnt : integer RANGE 0 to 15; Anzahl bits zur Umwandlung integer Eingangswert std_logic_vector Ausgangswert cnt_out <= std_logic_vector(to_unsigned(cnt,4)); Umwandlungsfunktionen (Aufruf von 2 Subroutinen)
Beispiel am Dekadenzähler ARCHITECTURE RTL OF DekadenZaehler SIGNAL cnt_folge: INTEGER RANGE 0 to 15 ; SIGNAL cnt_gegenwart: INTEGER RANGE 0 to 15; BEGIN logik : PROCESS (cnt_gegenwart) BEGIN cnt_folge <= cnt_gegenwart + 1 ; END PROCESS logik; flip_flops : PROCESS (clk, reset) BEGIN IF reset = '1' THEN cnt_gegenwart <= 0; ELSIF clk'EVENT AND clk = '1' THEN cnt_gegenwart <= cnt_folge ; END IF; END PROCESS flip_flops; cnt_out <= std_logic_vector(to_unsigned(cnt_gegenwart,4)); END ARCHITECTURE rtl; Achtung: Einschränken mit Range, da Sonst Synthesizer unnötig viele FF zuteilt Handelt es sich hier um einen synchronen oder asynchronen Reset
Dekadenzähler Alternative mit Datentyp Unsigned ARCHITECTURE rtl of DekadenZaehler is signal cnt_folge : unsigned (3 downto 0); signal cnt_gegenwart : unsigned (3 downto 0); constant increment : natural range 0 to 3 :=1; BEGIN logik : PROCESS (cnt_gegenwart) BEGIN cnt_folge <= cnt_gegenwart + increment ; END PROCESS logik; flip_flops : PROCESS (clk, reset) BEGIN IF reset = '1' THEN cnt_gegenwart <= “0000“; ELSIF clk'EVENT AND clk = '1' THEN cnt_gegenwart <= cnt_folge ; END IF; END PROCESS flip_flops; cnt_out <= std_logic_vector(cnt_gegenwart); END architecture rtl;
IEEE numeric_std Konvertierungsroutinen Achtung: Nicht zusammen mit conv_std Routinen verwenden
Convertierung std_logic_vector -> signed Umgekehrte Umwandlung: std_logic_vector in Integer Convertierung std_logic_vector -> signed cnt <= to_integer(signed(data)); Convertierung signed -> integer Ausgang: Integer Eingang: std_locic_vector
Zähler mit einem Prozess LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY counter IS PORT (clk, reset : IN std_logic; cnt_out : OUT std_logic_vector(3 downto 0)); END counter; ARCHITECTURE rtl OF counter IS signal cnt: integer range 0 to 9; BEGIN cnt_out <= cnt; cntr : PROCESS (clk, reset) BEGIN IF reset = '1' THEN cnt <= 0 ; ELSIF clk'EVENT AND clk = '1' THEN cnt <= cnt + 1 ; END IF; END PROCESS cntr; cnt_out <= std_logic_vector(to_unsigned(cnt, 4)); END rtl; Takt und Logik in einem Prozess (möglichst vermeiden)
Up/down Zähler
Vorwärts/Rückwärtszähler 0000 1 0001 5 0101 3 0011 2 0010 4 0100 6 0110 9 1001 Up = 0 Up = 1
Geschachtelte if-else statements beim up/down counter IF reset = '1' THEN cnt_folge <= 0; ELSE IF up = '1' THEN IF cnt_gegenwart < 9 THEN cnt_folge <= cnt_gegenwart + 1 ; ELSE cnt_folge <= 0; END IF; ELSE IF cnt_gegenwart > 0 THEN cnt_folge <= cnt_gegenwart - 1 ; ELSE cnt_folge <= 9; END IF; END IF; END IF;
Geschachtelte if-else statements beim up/down counter IF reset = '1' THEN cnt_folge <= 0; ELSE IF up = '1' THEN IF cnt_gegenwart < 9 THEN cnt_folge <= cnt_gegenwart + 1 ; ELSE cnt_folge <= 0; END IF; ELSE IF cnt_gegenwart > 0 THEN cnt_folge <= cnt_gegenwart - 1 ; ELSE cnt_folge <= 9; END IF; END IF; END IF;
Geschachtelte if-else statements beim up/down counter IF reset = '1' THEN cnt_folge <= 0; ELSE IF up = '1' THEN IF cnt_gegenwart < 9 THEN cnt_folge <= cnt_gegenwart + 1 ; ELSE cnt_folge <= 0; END IF; ELSE IF cnt_gegenwart > 0 THEN cnt_folge <= cnt_gegenwart - 1 ; ELSE cnt_folge <= 9; END IF; END IF; END IF;
Mux Diagramm UP-Down Zähler
Zähler mit nicht gewichteten Code
Zustandsfolgetabelle Zähler in Graycode Q(2) Q(1) Q(0) N+1 -> 1 2 3 4 5 6 7
Zustandsdiagramm des Gray Zählers 000 1 001 5 111 3 010 2 011 4 110 6 101 7 100 Zustand Graycode
Blockschaltplan Gray Zähler .q .d gray_out(0) gray_out(1) gray_out(2) clk L0 L1 L2 .ar reset gray_gegenwart(0) gray_folge(0) gray_folge(1) gray_folge(2) gray_gegenwart(1) gray_gegenwart(2) Gegenwärtiger Zustand Folge Zustand
Prozesse des Gray Zählers gray_folge logik: Prozess gray_gegenwart 4 flip_flops: Prozess clk reset 4
Logik Process des Gray Zähler gray_logic: process (gray_gegenwart) BEGIN CASE gray_gegenwart IS when "000" => gray_folge <= "001"; when "001" => gray_folge <= "011"; when "011" => gray_folge <= "010"; when "010" => gray_folge <= "110"; when "110" => gray_folge <= "111"; when "111" => gray_folge <= "101"; when "101" => gray_folge <= "100"; when OTHERS => gray_folge <= "000"; END case; END PROCESS gray_logic; Gegenwärtiger Zustand Folge Zustand
Getakteter Process des Gray Zählers ARCHITECTURE rtl OF graycnt IS signal gray_gegenwart: std_logic_vector(2 downto 0) signal gray_folge: std_logic_vector(2 downto 0); BEGIN gray_out <= gray_gegenwart ; count: process (clk, reset) BEGIN IF reset = '1' THEN gray_gegenwart <= "000"; ELSIF clk'EVENT AND clk = '1' THEN gray_gegenwart <= gray_folge; END IF; END PROCESS count; Gegenwärtiger Zustand Folge Zustand