1 / 45

VHDL-Synthese für Fortgeschrittene

VHDL-Synthese für Fortgeschrittene. Ronald Hecht ronald.hecht@etechnik.uni-rostock.de. Motivation. Synthese-Tools werden immer leistungsfähiger Abstraktionslevel steigern! Lesbarkeit Wartbarkeit Design-Reuse Robustheit des Codes erhöhen!. Überblick. ieee.numeric_std und integer

karis
Download Presentation

VHDL-Synthese für Fortgeschrittene

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. VHDL-Synthese für Fortgeschrittene Ronald Hecht ronald.hecht@etechnik.uni-rostock.de

  2. Motivation • Synthese-Tools werden immer leistungsfähiger • Abstraktionslevel steigern! • Lesbarkeit • Wartbarkeit • Design-Reuse • Robustheit des Codes erhöhen!

  3. Überblick • ieee.numeric_std und integer • Packages • Clock und Reset • Technologie-Mapping • Flexible Interfaces • 2-Prozess-Methode

  4. Das Paket numeric_std • std_logic_arith/signed/unsigned sind Synopsys Pakete • Defacto Industrie Standard, aber nicht standardisiert • numeric_std ist IEEE 1076.3 Standard • Strenger typisierte Operatoren • Für neue Designs streng empfohlen type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC;

  5. Typumwandlungstd_logic_vector • Es ist nicht definiert, ob std_logic_vector signed oder unsigned ist • Deshalb explizite Typumwandlung variable slv : std_logic_vector(7 downto 0); variable u : unsigned(7 downto 0); variable s : signed(7 downto 0); slv := std_logic_vector(u); slv := std_logic_vector(s); u := unsigned(slv); s := signed(slv);

  6. Typumwandlunginteger • Konvertierungsfunktionen to_... • Bei Umwandlung von std_logic_vector nach integer signed/unsigned beachten! variable ui : integer range 0 to 255; variable si : integer range -128 to 127; ui := to_integer(u); si := to_integer(s); ui := to_integer(unsigned(slv)); u := to_unsigned(ui, u'length); s := to_signed(si, s'length); slv := std_logic_vector(to_unsigned(ui, slv'length));

  7. Operatoren in numeric_std • Alle gängigen Integeroperationen • Schiebeoperationen • Operationen mit std_logic_vector etwas umständlich aber eindeutig + - * / mod rem = /= < > <= >= shift_left shift_right rotate_left rotate_right sll srl rol ror u := u + 1; s := s + 1; slv := std_logic_vector(unsigned(slv) + 1);

  8. integer und boolean versus std_logic_vector • signed/unsigned, std_logic_vector oft etwas umständlich • Basieren auf neunwertigem std_logic • Langsam in der Simulation im Vergleich zu integer und boolean • Verwende nach Möglichkeit integer und boolean für • Zähler, Adressen, Arithmetische Operationen • Interne Statussignale • Synthetisierbar!

  9. Integer für die Synthese • Immer range angeben! • Alles optimal synthesefähig! variable a, b, c : integer range 0 to 255; variable addr : integer range 0 to depth - 1; c := a + b; c := a * b; -- shift left/right c := a * 4; c := a / 8; -- wrap counter c := (a + 1) mod 256; -- get some bits c := (a / 4) mod 16; -- access memory variable mem : mem_type; o := mem(addr); -- binary to one-hot o := (others => '0'); o(addr) := '1';

  10. Verwende Variablen! • Hohe Simulationsgeschwindigkeit • Einfaches Debugging • Auch im Waveform-Viewer darstellbar • Sequentielle Darstellung • Sofortige Aktualisierung • Besser verständlich und wartbar • Sehr gute Syntheseergebnisse

  11. Verwende Packages! • Design-Reuse, Wartbarkeit • Modularität, Abstraktion package package_name is -- Deklaration von: -- Typen und Untertypen -- Konstanten, Aliase -- Signalen, Files -- Funktionen -- Prozeduren -- Attributen -- Komponenten -- Definition von: -- Konstanten -- Attributen end package_name; package body package_name is -- Definition von vorher -- deklarierten Objekten: -- Funktionen -- Prozeduren -- Konstanten -- Deklaration/Definition -- von zusaetzlichen -- Objekten end package_name;

  12. Beispiel CRC-Package • Beschreibung der komb. Logik -- CRC32 Generator: "CRC-32", Ethernet, AAL5 constant CRC32_GEN : std_logic_vector(31 downto 0) := "00000100110000010001110110110111"; -- CRC-CCITT Generator: HDLC constant CRC_CCITT_GEN : std_logic_vector(15 downto 0) := "0001000000100001"; -- calculates next crc value, data vector function next_crc ( crc : std_logic_vector; -- current CRC value data : std_logic_vector; -- incoming data gen : std_logic_vector) -- generator Polynom w/o x^n return std_logic_vector; begin ... ... end next_crc;

  13. Weitere Anwendungen von Packages • Kombinatorische Logik • Interfaces, Komponenten • Helper-Funktionen, Typumwandlung • Design Konfiguration • Verhaltensmodelle • Logging

  14. rising_edge(clk) • Zwei Möglichkeiten in VHDL für flankensensitive Elemente • rising_edge() ist in der Simulation robuster • Kürzer und einfacher aufzuschreiben • Verwende rising_edge() clk'event and clk = '1' rising_edge(clk) FUNCTION rising_edge (SIGNAL s : std_ulogic) RETURN BOOLEAN IS BEGIN RETURN (s'EVENT AND (To_X01(s) = '1') AND (To_X01(s'LAST_VALUE) = '0')); END;

  15. Register mit und ohne Reset • Problem: Einige Register werden nicht zurückgesetzt • Gated Clock oder Clock Enable regs_wrong: process (clk, rst) begin if rst = '0' then r1 <= '0'; elsif rising_edge(clk) then r1 <= x; r2 <= y; end if; end process regs_wrong;

  16. Alternative synthesefähige Beschreibung des Resets • Ausnutzung der Priorität durch Beschreibungsreihenfolge • Synchrones und asynchrones Reset regs_s: process (clk) begin if rising_edge(clk) then r1 <= x; r2 <= y; if rst = '0' then r1 <= '0'; end if; end if; end process regs_s; regs_as: process (clk, rst) begin if rising_edge(clk) then r1 <= x; r2 <= y; end if; if rst = '0' then r1 <= '0'; end if; end process regs_as;

  17. Reset – Synchron oder Asynchron? • Beides hat Vor- und Nachteile • Synchrone Resets häufig für FPGAs • Asynchrone Resets oft für ASICs • Konfigurierbar? • Externes Reset immer einsynchronisieren! rst_sync: process (clk, pad_rst) begin if rising_edge(clk) then r <= '1' & r(r'high downto 1); end if; if pad_rst = '0' then r <= (others => '0'); end if; end process rst_sync; rst <= r(0);

  18. Konfigurierbares Reset • Konfigurations-Package constant USE_SYNC_RESET : boolean := TRUE; constant USE_ASYNC_RESET : boolean := NOT(USE_SYNC_RESET); function sync_reset(rst : std_logic) return boolean is begin if (USE_SYNC_RESET) then return (rst = '0'); else return false; end if; end; function async_reset(rst : std_logic) return boolean is begin if (USE_ASYNC_RESET) then return (rst = '0'); else return false; end if; end;

  19. Konfigurierbares Reset • Verwendung der Reset-Funktionen • Redundante Reset-Anweisungen vermeidbar durch Prozedur reg: process (clk, rst) begin if rising_edge(clk) then q <= d; if sync_reset(rst) then q <= '0'; end if; end if; if async_reset(rst) then q <= '0'; end if; end process regs;

  20. Technologie Mapping • Schaltungen enthalten architektur-spezifische Komponenten • Pads • RAMs, Registerfiles • Spezielle Beschleunigende Hardware • Schlechte Portierbarkeit • Lösung: Technologie-Wrapper für diese Elemente

  21. Technologie MappingDateien • Wrapper in tech_map • Ausnutzung von Designhierarchie

  22. Technologie MappingVHDL-Implementierung package tech_map is component inpad port (pad : in std_logic; q : out std_logic); end component; ... end tech_map; entity inpad ... architecture rtl of inpad is begin ... ip0 : if TARGET_TECH = virtex generate ipx : virtex_inpad port map (q => q, pad => pad); end generate; ip4 : if TARGET_TECH = atc18 generate ipx : atc18_inpad port map (q => q, pad => pad); end generate; ... end rtl; type target_tech_type is (gen, virtex, virtex2, apex, atc18, ...); constant TARGET_TECH : target_tech_type := apex;

  23. Flexible Interfaces • Probleme bei großen Designs: • Entities haben viele Signale • Änderung der Entities bedeutet Modifikationen in vielen Dateien • Schwierige Namensgebung • Schlecht wartbar • Lösung: Definition flexibler Signaltypen mit Records

  24. Flexible Interfaces – in/out • Entity-in/out erzwingt zwei Datentypen • Deklaration von name_in_type und name_out_type type mem_in_type is record data : mem_data_type; end record; type mem_out_type is record address : mem_address_type; data : mem_data_type; data_tri : std_logic; csn : std_logic; oen : std_logic; writen : std_logic; end record; -- Memory controller entity mem_ctrl is port ( clk : in std_logic; rst : in std_logic; memi : in mem_in_type; memo : out mem_out_type -- noch weitere Signale -- Steuer- und -- Datenleitungen ); end mem_ctrl;

  25. Flexible Interfaces – inout? • Pads können inout sein • Bei Verwendung von „drive“-Signalen kein inout-Typ notwendig -- Top Entity, Signale -- repraesentieren Pads entity top is port ( clk : in std_logic; rst : in std_logic; data : inout mem_data_type; address : out mem_address_type; csn : out std_logic; oen : out std_logic; writen : out std_logic -- noch weitere Signale ); end top; mem_ctrl_i: mem_ctrl port map ( clk => clk, rst => rst, memi => memi, memo => memo); data <= memo.data when memo.data_tri = '0' else (others => 'Z'); memi.data <= data;

  26. Flexible Interfaces • Keine Records in den Ports der Top-Entity • Tristate-Buffer nur in der Top-Entity • Bei bidirektionalen On-Chip-Bussen Tristate-Buffer in der Bus-Entity • On-Chip-Tristate aber stets vermeiden! • Testbarkeit • Geschwindigkeit • inout-Type nicht nötig

  27. Flexible InterfacesStrategien • IPCore-Schnittstellen ähneln sich • System, Steuer- und Statussignale, RX und TX

  28. Flexible Interfaces – Tipps • Takt und Reset nicht in Records • Hierarchische Records entity hdlc_layer is port ( clk : in std_logic; rst : in std_logic; rx_clk : in std_logic; tx_clk : in std_logic; ctrli : in hdlc_ctrl_in_type; ctrlo : out hdlc_ctrl_out_type; clienti : in hdlc_client_in_type; cliento : out hdlc_client_out_type; hdlci : in hdlc_in_type; hdlco : out hdlc_out_type); end hdlc_layer; type hdlc_client_in_type is record rx : hdlc_client_rx_in_type; tx : hdlc_client_tx_in_type; end record; type hdlc_client_out_type is record rx : hdlc_client_rx_out_type; tx : hdlc_client_tx_out_type; end record;

  29. Flexible InterfacesVorteile • Wenige Signale in der Entity und in Sensitivity-Listen • Einfaches Hinzufügen von Ports • Einfaches route-through • Gute Wartbarkeit • Hoher Abstraktionsgrad • Hierarchische Schnittstellen

  30. Abstraktion digitaler Logik • Synchrones Design (Modul) besteht aus: • Kombinatorischer Logik • Registern (Flip-Flops, Speicher) • Register an den Ausgängen oder nicht? • Moore/Mealy haben im Normalfall keine Register am Ausgang

  31. Nichtabgetaktete Ausgänge • Problematische Timinganalyse • Kombinatorische Schleifen möglich • Undefinierte Eingangssignallaufzeit für angeschlossene Module • Glitches Vorsicht, Probleme!

  32. Abgetaktete Ausgänge! • Am Ausgang nach Möglichkeit immer Register • Ausnahme: Single-Cycle Handshake • req mit Register • ack ohne Register

  33. Traditionelles RTL-VHDL • Viele kleine parallele Anweisungen und Prozesse • Viele Signale • state/next_state-Signalnamen • Unflexible Designpattern • Kombinatorische Logik • Register, FSMs • „Schematic-VHDL“

  34. Traditionelles RTL-VHDL Probleme • Langsame Simulation, da viele Signale und Prozesse • Schwer und meist nur mit Hilfe eines Schaltplans zu verstehen • Schwieriges Debugging • Algorithmus nicht erkennbar • Fehleranfällig • Latches • Mehrfachtreiber

  35. 2-Prozess Methode • Modul besteht nur aus 2 Prozessen • Sequentieller Prozess r = rin • Kombinatorischer Prozess rin = f(r, in) • Ausgänge outreg = g(r) undoutunreg = h(r, in)

  36. 2-Prozess Methode • Zwei lokale Signale als Record für alle Register • Register Eingang rin • Register Ausgang r • Algorithmus • Kombinatorischer Prozess f(r, in) • Lokale Variable v für den neuen Registerinhalt rin = v • Weitere lokale Variablen für kombinatorische Ausgänge und Zwischenergebnisse

  37. 2-Prozess Methode VHDL Beispiel • Neuer Typ für alle Register • Zwei Signale und ein Prozess für alle Register • Einfaches Entfernen und Hinzufügen von Registern type state_type is (low, high); type reg_type is record state : state_type; o : std_logic; end record; signal r, rin : reg_type; reg : process (clk, rst) begin if rising_edge(clk) then r <= rin; end if; if async_reset(rst) then reset(r); end if; end process reg;

  38. 2-Prozess Methodereset(r) • Bei Registerdeklaration auch die reset-Prozedur definieren • Vermeidung von Redundanz procedure reset ( signal r : inout reg_type) is begin -- reset r.state <= low; r.o <= '0'; end reset; reg : process (clk, rst) begin if rising_edge(clk) then r <= rin; if sync_reset(rst) then reset(r); end if; end if; if async_reset(rst) then reset(r); end if; end process reg;

  39. 2-Prozess MethodeVHDL Beispiel • Variable zur Berechnung des neuen Register-wertes • Defaultzuweisung • Algorithmus • Zuweisung an den Registereingang • Treiben der Aus-gänge comb : process (r, i) variable v : reg_type; begin -- process comb -- Defaultzuweisung v := r; -- Ausgang meist '0' v.o := '0'; -- Zustandsmaschine case r.state is when low => if i = '1' then v.state := high; v.o := '1'; end if; when high => if i = '0' then v.state := low; end if; end case; -- Ausgaenge treiben rin <= v; o <= r.o; end process comb;

  40. 2-Prozess MethodeDebugging

  41. 2-Prozess MethodeVorteile • Sequentielle Beschreibung des Algorithmus • Konsistenter Coding-Style • Einfach zu verstehen • Sehr gut wartbar • Schnell in der Simulation • Problemlose Synthese • Kaum Fehleranfällig

  42. 2-Prozess Methode – Tipps • Defaultwerte für v.xyz • Variablen für Zwischenergebnisse und kombinatorische Ausgänge • Kombinatorische Ausgabe auch mit o<=v.ack möglich • Funktionen und Prozeduren für häufig wiederkehrende Aufgaben • Mut zum einfacher lesbaren Code! • Beispiele: www.gaisler.com und LAPV5DL

  43. Duplizieren von LogikSchleifen oder „generate“? • Grenzen müssen zur Compile-Time bekannt sein • Viele weitere Anwendungen • Mut zu Schleifen! for i in r.count'range loop v.count(i) := (r.count(i) + 1) mod 8; if v.count(i) = 0 then v.tick(i) := '1'; else v.tick(i) := '0'; end if; end loop;

  44. Auswahl von Logikif-then oder „generate“? • Bedingung muss zur Compile-Time bekannt sein if CALIBRATE then -- remove this logic when -- CALIBRATE = false v.period_counter := r.period_counter + 1; if rising then v.period := v.period_counter; v.period_counter := 0; end if; else -- remove this logic when -- CALIBRATE = true v.period := CLK_RATE / FREQUENCY; end if;

  45. Zusammenfassung • ieee.numeric_std verwenden • Integer, Variablen, Packages • Takt und Reset • Technologie Mapping • Flexible Interfaces • 2-Prozess-Methode

More Related