signal s_midi_out: std_logic_vector(7 downto 0);
s_midi_out <= "1 0 0 1 1 0 1 0"; 7,6,5,4,3,2,1,0
s_midi_out(7) enthält den Wert ‚1‘
s_midi_out(0) enthält den Wert ‚0‘
s_midi_out(5 downto 3) enthält die Werte „011“
signal s_midi_out: std_logic_vector(7 downto 0);
s_midi_out <= "1 0 0 1 1 0 1 0"; 7,6,5,4,3,2,1,0
s_midi_out(7) enthält den Wert ‚1‘
s_midi_out(0) enthält den Wert ‚0‘
s_midi_out(5 downto 3) enthält die Werte „011“
In VHDL ist es üblich, vor dem Senden von Daten mehrere Informationen (Signale) in einen grossen Vektor zusammenzubauen.
Beim Empfangen wird dann der grosse Vektor wieder in seine Einzelteile zerlegt.
1. Einzelne Signalgrössen
signal s_tone_on: std_logic; signal s_note_value: std_logic_vector(7 downto 0); signal s_velocity: std_logic_vector(7 downto 0); signal s_midi: std_logic_vector(16 dowonto 0);
2. Addition zu Vektor
// Vektor für innerhalb Entity bilden
s_midi <= s_tone_on & s_note_value & s_velocity;
// oder direkt beim Port
GPIO_0 <= s_tone_on & s_note_value & s_velocity;
Man kann auch nur Teile des Vektors addieren.
Oft ist ein Vektor aus mehreren Informationen zusammengesetzt (vgl midi_in).
entity a is port( midi_in: in std_logic_vector(16 downto 0); data: out std_logic_vector(7 downto 0) );
Braucht man nun nur einen Bit-Abschnitt so geschieht dies so:
1. Signal von der gewünschten Bit-Breite definieren
signal s_tone_on: std_logic; signal s_note_value: std_logic_vector(7 downto 0); signal s_velocity: std_logic_vector(7 downto 0);
2. Vektor bitweise zuweisten
s_tone_on <= midi_in(16); s_note_value <= midi_in(15 downto 8); s_velocity <= midi_in(7 downto 0);
….
not
kann für boolean und signale gebraucht werden
std_logic_signal_1 <= not std_logic_signal_2; if (not enable_data_1) then //
std_logic_signal <= signal_a and signal_b;
natural, unsigned, integer
Typkonversionen zwischen den logischen Signalen und den natürlichen.
Bit Operationen
Signale zusammensetzen
Bist aus Vektor extrahieren
Signal Bits setzen (LSB, MSB)
Tristate ist die Zustandsbezeichnung von digitalen IOs. Diese können den Zustand ‚0‘, ‚1‘ oder (je nach Verdrahtung) ‚Z‘ oder ‚Z‚ sein. Der Grund dafür ist, dass Ausgänge getrieben werden müssen, was Transistoren bedingt. Diese können in der Luft hängen und dadurch den dritten Zustand erzeugen.
Pull up (‚Z‘)
Im Ruhezustand fehlt die Verbindung zu GND, aber die Verbindung zu VCC ist über den Widerstand gegeben.
Im Ruhezustand erhält der Ausgang aufgrund der Verbindung mit VCC einen definierten Zustand: logisch HIGH.
Pull down (‚Z‚)
Im Ruhezustand erhält die Leitung durch die Verbindung zu GND einen klaren Zustand: Logisch LOW.
Bei einem FPGA hängt die höchte Taktfrequenz vom langsten Pfad zwischen zwei FF ab.
f_max = 1 / t_pfad_max
Je länger der Pfad, desto tiefer die maximale Taktfrequenz.
t_pfad = 5 ns f_max = 200 MHz CLK_Bauteil = 200 MHz
t_pfad = 3 ns f_max = 333 MHz CLK_Bauteil = 333 MHz
Optimierung
Durch das direkte Anbinden eines FF beim Ausgang eines Speichers, wird der Pfad verkürzt.
Nachteil der Optimierung
Die Datenverarbeitung braucht insgesamt einen Takt-Zyklus mehr.
Artikel Warum es Signale braucht
wert <= next_wert
Die Signale existieren im Doppelback. Sie haben immer zwei Facetten.
Den alten Wert (wert) und den neuen (next).
Regel
– linke Seite wird am Ende des Prozesses zugewiesen
– rechte Seite wird sofort zugewiesen
Signale links erhalten den Wert am Ende des Prozesses.
Signale rechts sofort.
Signalzuweisung <= nennt man non-blocking
Variable
– Leben nur innerhalb eines Prozesses.
– Ihr Zustand kann nicht gespeichert werden.
– Sie müssen im Prozess, vor dem begin definiert werden
– Zuweisung erfolgt sofort (asynchron)
– Wird die Variable auch ausserhalb des Prozesses gebraucht, wird sie einem Signal zugewiesen.
read_file: process(all) variable token_note: std_logic_vector(7 downto 0) :=(OTHERS => '0'); variable token_velocity: std_logic_vector(7 downto 0) :=(OTHERS => '0'); begin // token einlesen (muss variable sein) read(line_in, token_type_n, good); // variable signal übergeben s_token_type <= token_type;
Signale
– Verbinden Blöcke miteinander und/oder werden innerhalb Block gebraucht
– Sie werden ausserhalb von Prozessen definiert
– Ihr Wert kann in einem FF gespeichert werden (muss aber nicht)
architecture rtl of counter is signal s_token_typ std_logic_vector(7 downto 0) := (others => '0'); begin execute_file: process (all) begin end
..