Echtzeitanwendungen auf Basis von HDL im Sommersemester 2025
(EN google-translate)
(PL google-translate)
ACHTUNG: In der neuesten Xubuntu-Installtion fehlen einige dynamische Bibliotheken, die notwendig sind, damit die hier benötigte Entwicklungsumgebung startet:

Laden Sie darum obigen Zip-Ordner herunter, entpacken ihn und kopieren alle Dateien darin nach /usr/lib/i386-linux-gnu/:
sudo cp libstdc++.so.5 /usr/lib/i386-linux-gnu/ sudo cp libXft.so.2 /usr/lib/i386-linux-gnu/ sudo cp libSM.so.6 /usr/lib/i386-linux-gnu/ sudo cp libICE.so.6 /usr/lib/i386-linux-gnu/ sudo cp libuuid.so.1 /usr/lib/i386-linux-gnu/ sudo cp libgthread-2.0.so.0 /usr/lib/i386-linux-gnu/ sudo cp libglib-2.0.so.0 /usr/lib/i386-linux-gnu/ sudo cp libXi.so.6 /usr/lib/i386-linux-gnu/ sudo cp libXrender.so.1 /usr/lib/i386-linux-gnu/ sudo cp libXrandr.so.2 /usr/lib/i386-linux-gnu/ sudo cp libfreetype.so.6 /usr/lib/i386-linux-gnu/ sudo cp libfontconfig.so.1 /usr/lib/i386-linux-gnu/ sudo cp libXext.so.6 /usr/lib/i386-linux-gnu/ sudo cp libX11.so.6 /usr/lib/i386-linux-gnu/ sudo cp libpcre.so.3 /usr/lib/i386-linux-gnu/ sudo cp libpng12.so.0 /usr/lib/i386-linux-gnu/ sudo cp libexpat.so.1 /usr/lib/i386-linux-gnu/ sudo cp libxcb.so.1 /usr/lib/i386-linux-gnu/ sudo cp libXau.so.6 /usr/lib/i386-linux-gnu/ sudo cp libXdmcp.so.6 /usr/lib/i386-linux-gnu/
Code 0-1: Konsolen-Befehle zum Beheben der Probleme.
|




#1 Mo 24.03.2025
Vorlesung: Einführung in FPGA und VHDL
Einige gebräuchliche Abkürzungen und Bezeichnungen:
Abkürzung | Bedeutung | Beschreibung |
---|---|---|
FPGA | Field Programmable Gate Array | Chip der diskrete Schaltungen abbilden kann |
VHSIC | Very High Speed Integrated Circuit | Beispiel: FPGA |
VHDL | VHSIC Hardware Description Language | Programmiersprache für FPGAs |
Verilog | Bezeichnung | Alternative Programmiersprache für FPGAs |
DARPA | Defense Advanced Research Projects Agency | Forschungsbehörde des US amerikanischen Militärs |
Xilinx | Firma | Stellt FPGA-Chips her und stellt Entwicklungsumgebungen zu ihrer Programmierung bereit |
Tabelle 0-1: Einige gebräuchliche Abkürzungen und Bezeichnungen
Geschichtlicher Hintergrund
|
|




Wie ist ein FPGA aufgebaut?


Vorberetung der ersten Übung mit einem FPGA-Board
|





Übung: Umgang mit der Entwicklungsumgebung ISE von Xilinx
Führen Sie die in der Vorlesung dargestellten Schritte selber aus, um sich mit der Xilinx IDE und dem dspFPGA-Board vertraut zu machen:
|
#2 Mo 31.03.2025
In dieser Lehrveranstaltung sollen die zuvor eingeführten Sprachelemente selbsttätig verwendet werden und der Umgang mit der Entwicklungsumgebung von Xilinx praktisch geübt werden. Dem vorangestellt werden wir die wichtigsten Inhalte dazu wiederholen:
|


ÜBUNG 1
|
ÜBUNG 2
|
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity and_gate is Port ( A : in STD_LOGIC; B : in STD_LOGIC; C : out STD_LOGIC); end and_gate; architecture Behavioral of and_gate is begin C <= A and B; end Behavioral;
Code 0-2: VHDL-Code zum UND-Gatter.
NET "A" LOC = "P139" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "B" LOC = "P135" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "C" LOC = "P131" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ;
Code 0-3: Constraints (.ucf-Datei) zum UND-Gatter.
Beachten Sie die Pullup-Einträge bei den Eingängen (Besprechung im Unterricht).
|
ÜBUNG 3
Variieren Sie das Beispiel mit der blinkenden LED so, dass diese nun mit 4 Hertz blinkt.
ÜBUNG 4 (Zusatzaufgabe)
Versuchen Sie ein Programm und eine zugehörige Schaltung zu realisieren, bei der über zwei Eingänge A und B die Blinkfrequenz einer LED gesteuert werden kann:
|
#3 Mo 07.04.2025
Themen
|
1. Musterlösungen zu Aufgabe 4
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity blinkled is Port ( MEINECLOCK : in STD_LOGIC; MEINELED : out STD_LOGIC; a : in STD_LOGIC; b : in STD_LOGIC); end blinkled; -- Clock-In == 6MHz, Toggeln nach 3000000 Schritten ergibt 1Hz Blinkfrequenz. architecture Behavioral of blinkled is constant w0: integer := 2999999; constant w1: integer := 1499999; constant w2: integer := 999999; constant w3: integer := 749999; signal zaehler : integer range 0 to 2999999 := 0; signal logikpegel : std_logic := '0'; signal asig : std_logic := '0'; signal bsig : std_logic := '0'; begin process begin wait until rising_edge(MEINECLOCK); if ( ((zaehler<w0) and (((not bsig) and (not asig)) = '1')) or ((zaehler<w1) and (((not bsig) and ( asig)) = '1')) or ((zaehler<w2) and ((( bsig) and (not asig)) = '1')) or ((zaehler<w3) and ((( bsig) and ( asig)) = '1')) ) then zaehler <= zaehler+1; else zaehler <= 0; logikpegel <= not logikpegel; end if; end process; MEINELED <= logikpegel; asig <= a; bsig <= b; end Behavioral;
Code 0-4: zu testende Lösung VHD
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; ## IO_L05P_0 ist auf FPGA-Chip Pin 125 NET "MEINELED" LOC = "P125"; NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "MEINELED" IOSTANDARD = LVCMOS33; NET "a" LOC = "P140" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "b" LOC = "P139" | PULLUP | IOSTANDARD = LVCMOS33 ;
Code 0-5: zu testende Lösung UCF

...weitere Lösung unter Verwendung einer Lookup-Tabelle:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity blinkled is Port ( MEINECLOCK : in STD_LOGIC; MEINELED : out STD_LOGIC; a : in STD_LOGIC; b : in STD_LOGIC); end blinkled; -- Clock-In == 6MHz, Toggeln nach 3000000 Schritten ergibt 1Hz Blinkfrequenz. architecture Behavioral of blinkled is constant w0: integer := 2999999; constant w1: integer := 1499999; constant w2: integer := 999999; constant w3: integer := 749999; signal zaehler : integer range 0 to 2999999 := 0; signal obergrenze : integer range 0 to 2999999 := 0; signal logikpegel : std_logic := '0'; signal wort : std_logic_vector(1 downto 0); signal wert : integer range 0 to 3 := 0; begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<obergrenze) then zaehler <= zaehler+1; else zaehler <= 0; logikpegel <= not logikpegel; end if; end process; MEINELED <= logikpegel; wort <= b & a; wert <= to_integer(unsigned(wort)); with wert select obergrenze <= w0 when 0, w1 when 1, w2 when 2, w3 when others; end Behavioral;
Code 0-6: VHD-Datei

2. Einführung Zu Neuronalen Netzen

3. Identifikation geeigneter Probleme zur Umsetzung mit einem FPGA
4. Anpassung der Struktur eines Neuronalen Netzes an die Möglichkeiten eines FPGAs
5. Verwendung des Elements LUT

6. Übung -- Konfigurierbares Lauflicht mittels LUT4
Nun soll der gezielte Einsatz eines Moduls aus der UNISIM-Library erübt werden.
Arbeiten Sie gerne in Zweiergruppen.
Das Konzept "Lauflicht" soll auf die Verwendung von Lookup-Tabellen übertragen werden.
|
Übung 2:
|
Übung 3:
|
#4 Mo 14.04.2025
Themen
Um die Implementierung eines Neuronalen Netzes auf dem FPGA voranzutreiben, wird heute eine passende Struktur modellhaft am PC entwickelt und getestet. Eine Implementierung auf dem FPGA erfolgt beim nächsten Termin.
|
1. Entwurf einer speziell für den FPGA gut geeigneten Neuronen-Variante
Eigenschaften eines einzelnen Neurons:
Anforderungen:
|
|
2. Implementierung eines minimalen Netzes

Bild 0-1: Entwurf des FPGA-fähigen, genetisch optimierbaren Neuronalen Netzes am Beispiel eines Äquivalenzgatters.
|
3. Optimierung des Netzes um ein Äquivalenzgatter zu repräsentieren als Übungsaufgabe
import java.util.Random; Random zzz = new Random(); public int zufall() { return zzz.nextInt(16)-8; // [-8,7] } public double fehler(int[] gen) { int out0 = netz(-8,-8,gen); int out1 = netz(-8,7,gen); int out2 = netz(7,-8,gen); int out3 = netz(7,7,gen); int err = (out0-7)*(out0-7) + (out1+8)*(out1+8) + (out2+8)*(out2+8) + (out3-7)*(out3-7); return Math.sqrt((double)err); } public int netz(int in0, int in1, int[] gen) { int w0=gen[0]; int w1=gen[1]; int w2=gen[2]; int w3=gen[3]; int w4=gen[4]; int w5=gen[5]; int u0 = ( ((w0*in0)/2) + ((w1*in1)/2) )/8; // [-7,8] int u1 = ( ((w2*in0)/2) + ((w3*in1)/2) )/8; u0+=7; // [0..15] int out0 = gen[6+u0]; u1+=7; // [0..15] int out1 = gen[6+16+u1]; int u2 = ( ((w4*out0)/2) + ((w5*out1)/2) )/8; u2+=7; // [0..15] int out2 = gen[6+16+16+u2]; return out2; } public void setup() { int[] gen = new int[54]; for(int i=0;i<gen.length;i++) gen[i]=zufall(); double aktueller_fehler = fehler(gen); println("err="+aktueller_fehler); } public void draw() { }
Code 0-7: Processing-Sketch als Ausgangspunkt, der die Grundlage für das Optimierungsprogramm liefert.
MUSTERLÖSUNG (nur setup-Methode)
public void setup() { int[] gen = new int[54]; int[] genN = new int[54]; for(int i=0;i<gen.length;i++) gen[i]=zufall(); for(int DURCHLAUF=0;DURCHLAUF<500;DURCHLAUF++) { int a = zzz.nextInt(gen.length); int b = gen[a]; double bb=fehler(gen); gen[a]=zufall(); double cc = fehler(gen); if(bb<cc) { gen[a]=b; } else { if(cc<bb) println("err="+cc); } } double aktueller_fehler = fehler(gen); println("err="+aktueller_fehler); println(); // Codegenerator als Unterstützung für die Erstellung des FPGA-Programms String EINRUECKUNG = " "; // constant w0: integer := -77; for(int i=0;i<6;i++) println(EINRUECKUNG+"constant w"+i+": integer := "+gen[i]+";"); for(int i=0;i<48;i++) println(EINRUECKUNG+"constant l"+i+": integer := "+gen[6+i]+";"); println(); println(EINRUECKUNG+"with u0 select out0 <="); for(int i=0;i<15;i++) println(EINRUECKUNG+"l"+i+" when "+(i-7)+", "); println(EINRUECKUNG+"l15 when others;"); println(); println(EINRUECKUNG+"with u1 select out1 <="); for(int i=0;i<15;i++) println(EINRUECKUNG+"l"+(16+i)+" when "+(i-7)+", "); println(EINRUECKUNG+"l31 when others;"); println(); println(EINRUECKUNG+"with u2 select out2 <="); for(int i=0;i<15;i++) println(EINRUECKUNG+"l"+(32+i)+" when "+(i-7)+", "); println(EINRUECKUNG+"l47 when others;"); }
Code 0-8: Optimierer und Codegenerator, um die Programmteile im VHDL-Quelltext nutzen zu können.
constant w0: integer := -6; constant w1: integer := -2; constant w2: integer := 2; constant w3: integer := 2; constant w4: integer := -1; constant w5: integer := -4; constant l0: integer := -8; constant l1: integer := 6; constant l2: integer := -4; constant l3: integer := -5; constant l4: integer := 1; constant l5: integer := 2; constant l6: integer := -7; constant l7: integer := -7; constant l8: integer := 1; constant l9: integer := -3; constant l10: integer := -1; constant l11: integer := -1; constant l12: integer := -4; constant l13: integer := 2; constant l14: integer := 3; constant l15: integer := 3; constant l16: integer := 0; constant l17: integer := 2; constant l18: integer := 4; constant l19: integer := -6; constant l20: integer := -6; constant l21: integer := 4; constant l22: integer := -6; constant l23: integer := -4; constant l24: integer := -1; constant l25: integer := -4; constant l26: integer := 3; constant l27: integer := -8; constant l28: integer := 4; constant l29: integer := -5; constant l30: integer := -1; constant l31: integer := -6; constant l32: integer := -1; constant l33: integer := 3; constant l34: integer := -1; constant l35: integer := 0; constant l36: integer := -7; constant l37: integer := 6; constant l38: integer := 7; constant l39: integer := 7; constant l40: integer := -8; constant l41: integer := -6; constant l42: integer := 4; constant l43: integer := -8; constant l44: integer := -2; constant l45: integer := -4; constant l46: integer := 7; constant l47: integer := 2; with u0 select out0 <= l0 when -7, l1 when -6, l2 when -5, l3 when -4, l4 when -3, l5 when -2, l6 when -1, l7 when 0, l8 when 1, l9 when 2, l10 when 3, l11 when 4, l12 when 5, l13 when 6, l14 when 7, l15 when others; with u1 select out1 <= l16 when -7, l17 when -6, l18 when -5, l19 when -4, l20 when -3, l21 when -2, l22 when -1, l23 when 0, l24 when 1, l25 when 2, l26 when 3, l27 when 4, l28 when 5, l29 when 6, l30 when 7, l31 when others; with u2 select out2 <= l32 when -7, l33 when -6, l34 when -5, l35 when -4, l36 when -3, l37 when -2, l38 when -1, l39 when 0, l40 when 1, l41 when 2, l42 when 3, l43 when 4, l44 when 5, l45 when 6, l46 when 7, l47 when others;
Code 0-9: Ergebnis des Code-Generators.
|
Kurzfassung zur Implementierung eines modifizierten Gradientenverfahrens:
|
Kurzfassung zur Implementierung eines genetischen Algorithmus':
|



#5 Mo 28.04.2025
Themen
|
1. ÜBUNG: Implementierung des Neuronale-Netz-basierten Äquivalenzgatters
Es soll die Übung von letzter Woche fortgesetzt werden, bei der das zunächst mit Java realisierte digitale Neuronale Netz in VHDL realisiert werden soll.
Hinweise zur Umsetzung:
|

2. Diskussion der studentischen Lösungen und einer Musterlösung
3. Überlegungen zu Kapazität und Potential des Konzepts und Möglichkeiten zur Reduktion
Laut der aufgegebenen Statistik wurden 2% der Ressourcen verbraucht, somit bietet der verwendete FPGA das Potential ein Neuronales Netz diesen Typs mit maximal 150 Neuronen aufzubauen.
Welche Möglichkeiten gäbe es, die Anzahl der implementierbaren Neuronen zu erhöhen?
MUSTERLÖSUNG NXOR mittels Neuronalem Netz-Derivat auf FPGA

Hinweis:
Statt direkt u0 <= (((w0*in0)/2)+((w1*in1)/2))/8; ...wurde xu0 <= w0*in0; yu0 <= w1*in1; u0 <= ((xu0/2)+(yu0/2))/8; implementiert, da sonst beim Kompilieren eine Warnung zu einem möglichen Datenverlust angezeigt wurde.
Code 0-10: Hinweis.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity NeuroNetzNXOR is Port ( inputA : in STD_LOGIC; inputB : in STD_LOGIC; outputC : out STD_LOGIC); end NeuroNetzNXOR; architecture Behavioral of NeuroNetzNXOR is -- Konstanten einfügen: constant w0: integer := -6; constant w1: integer := -2; constant w2: integer := 2; constant w3: integer := 2; constant w4: integer := -1; constant w5: integer := -4; constant l0: integer := -8; constant l1: integer := 6; constant l2: integer := -4; constant l3: integer := -5; constant l4: integer := 1; constant l5: integer := 2; constant l6: integer := -7; constant l7: integer := -7; constant l8: integer := 1; constant l9: integer := -3; constant l10: integer := -1; constant l11: integer := -1; constant l12: integer := -4; constant l13: integer := 2; constant l14: integer := 3; constant l15: integer := 3; constant l16: integer := 0; constant l17: integer := 2; constant l18: integer := 4; constant l19: integer := -6; constant l20: integer := -6; constant l21: integer := 4; constant l22: integer := -6; constant l23: integer := -4; constant l24: integer := -1; constant l25: integer := -4; constant l26: integer := 3; constant l27: integer := -8; constant l28: integer := 4; constant l29: integer := -5; constant l30: integer := -1; constant l31: integer := -6; constant l32: integer := -1; constant l33: integer := 3; constant l34: integer := -1; constant l35: integer := 0; constant l36: integer := -7; constant l37: integer := 6; constant l38: integer := 7; constant l39: integer := 7; constant l40: integer := -8; constant l41: integer := -6; constant l42: integer := 4; constant l43: integer := -8; constant l44: integer := -2; constant l45: integer := -4; constant l46: integer := 7; constant l47: integer := 2; -- Eingangssignale definieren: signal in0 : integer range -8 to 7 := 0; -- 4Bit Variable signal in1 : integer range -8 to 7 := 0; -- 4Bit Variable -- Ergebnisse der gewichteten Summen definieren: -- wegen int u0 = ( ((w0*in0)/2) + ((w1*in1)/2) )/8; // [-7,8] -- kann u0 theoretisch als Zwischenergebnis maximal 16*7=112, bzw. minimal -16*8=128 annehmen. -- Darum wird als Bereich der einer vorzeichenbehafteten 8-Bit-Integerzahl gewählt: signal u0 : integer range -127 to 128 := 0; -- 8Bit Variable signal u1 : integer range -127 to 128 := 0; -- 8Bit Variable signal u2 : integer range -127 to 128 := 0; -- 8Bit Variable -- Ausgänge der Neuronen definieren: signal out0 : integer range -8 to 7 := 0; -- 4Bit Variable signal out1 : integer range -8 to 7 := 0; -- 4Bit Variable signal out2 : integer range -8 to 7 := 0; -- 4Bit Variable -- Testweise Zwischenergebnisse berechnen und in Hilfsvariablen speichern: -- Hilfsvariablen wegen warning, s.u.: signal xu0 : integer range -127 to 128 := 0; -- 8Bit Variable signal yu0 : integer range -127 to 128 := 0; -- 8Bit Variable signal xu1 : integer range -127 to 128 := 0; -- 8Bit Variable signal yu1 : integer range -127 to 128 := 0; -- 8Bit Variable signal xu2 : integer range -127 to 128 := 0; -- 8Bit Variable signal yu2 : integer range -127 to 128 := 0; -- 8Bit Variable begin -- Aus den logischen Eingängen die Neuronen-Inputs gewinnen: -- Eingänge invertieren, wg. Pullup in0 <= 7 when (inputA = '0') else -8; in1 <= 7 when (inputB = '0') else -8; -- Berechnung der gewichteten Summen xu0 <= w0*in0; yu0 <= w1*in1; u0 <= ((xu0/2)+(yu0/2))/8; -- WARNING ohne Hilfsvariablen: -- line 114: The result of a 4x4-bit multiplication is partially used. -- Only the 7 least significant bits are used. If you are doing this on purpose, -- you may safely ignore this warning. Otherwise, -- make sure you are not losing information, leading to unexpected circuit behavior. xu1 <= w2*in0; yu1 <= w3*in1; u1 <= ( (xu1/2) + (yu1/2) )/8; -- Lookup-Tabellen um aus u0 out0, bzw. aus u1 out1 zu bestimmen: with u0 select out0 <= l0 when -7, l1 when -6, l2 when -5, l3 when -4, l4 when -3, l5 when -2, l6 when -1, l7 when 0, l8 when 1, l9 when 2, l10 when 3, l11 when 4, l12 when 5, l13 when 6, l14 when 7, l15 when others; with u1 select out1 <= l16 when -7, l17 when -6, l18 when -5, l19 when -4, l20 when -3, l21 when -2, l22 when -1, l23 when 0, l24 when 1, l25 when 2, l26 when 3, l27 when 4, l28 when 5, l29 when 6, l30 when 7, l31 when others; -- Behandlung der zweiten Neuronenschicht (nur ein Neuron): xu2 <= w4*out0; yu2 <= w5*out1; u2 <= ( (xu2/2) + (yu2/2) )/8; -- Lookup-Tabelle, um aus u2 out2 zu bestimmen: with u2 select out2 <= l32 when -7, l33 when -6, l34 when -5, l35 when -4, l36 when -3, l37 when -2, l38 when -1, l39 when 0, l40 when 1, l41 when 2, l42 when 3, l43 when 4, l44 when 5, l45 when 6, l46 when 7, l47 when others; -- Umwandlung des Integer-Ausgangssignals von out2 in den logischen Ausgang outputC: with out2 select outputC <= '0' when -8 to 0, '1' when others; end Behavioral;
Code 0-11: VHDL-Datei.
NET "inputA" LOC = "P126" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "inputB" LOC = "P130" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "outputC" LOC = "P125" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ;
Code 0-12: Constraints-Datei.
Der entsprechende Testaufbau konnte erfolgreich getestet werden.
Laut der aufgegebenen Statistik wurden 2% der Ressourcen verbraucht, somit bietet der verwendete FPGA das Potential ein Neuronales Netz diesen Typs mit maximal 150 Neuronen aufzubauen.
MUSTERLÖSUNG zur Generierung eines Netzes mit nur 2 Bit Ausgangswertebereich pro Neuron

//004: Output nur 2 statt 4 Bit import java.util.Random; Random zzz = new Random(0); public int zufall() { return zzz.nextInt(16)-8; // [-8,7] } public double fehler(int[] gen) { int out0 = netz(-8,-8,gen); int out1 = netz(-8,7,gen); int out2 = netz(7,-8,gen); int out3 = netz(7,7,gen); int err = (out0-7)*(out0-7) + (out1+8)*(out1+8) + (out2+8)*(out2+8) + (out3-7)*(out3-7); return Math.sqrt((double)err); } public int netz(int in0, int in1, int[] gen) { int w0=gen[0]; int w1=gen[1]; int w2=gen[2]; int w3=gen[3]; int w4=gen[4]; int w5=gen[5]; // -8,7 => min -8*7=-56, max -8*-8=64 , /64=-1..2 == 2Bit!! int u0 = ( (w0*in0) + (w1*in1) )/64; // [-1,2] int u1 = ( (w2*in0) + (w3*in1) )/64; u0+=1; // [0..3] int out0 = gen[6+u0]; u1+=1; // [0..3] int out1 = gen[6+4+u1]; int u2 = ( (w4*out0) + (w5*out1) )/64; u2+=1; // [0..3] int out2 = gen[6+4+4+u2]; return out2; } public void setup() { int[] gen = new int[18]; //6+16+16+16=54, 6+4+4+4=18 int[] genN = new int[18]; for(int i=0;i<gen.length;i++) gen[i]=zufall(); for(int DURCHLAUF=0;DURCHLAUF<900;DURCHLAUF++) { int a = zzz.nextInt(gen.length); int b = gen[a]; double bb=fehler(gen); gen[a]=zufall(); double cc = fehler(gen); if(bb<cc) { gen[a]=b; } else { if(cc<bb) println("err="+cc); } } double aktueller_fehler = fehler(gen); println("err="+aktueller_fehler); println(); // Codegenerator als Unterstützung für die Erstellung des FPGA-Programms String EINRUECKUNG = " "; // constant w0: integer := -77; for(int i=0;i<6;i++) println(EINRUECKUNG+"constant w"+i+": integer := "+gen[i]+";"); for(int i=0;i<12;i++) println(EINRUECKUNG+"constant l"+i+": integer := "+gen[6+i]+";"); println(); println(EINRUECKUNG+"with u0 select out0 <="); for(int i=0;i<3;i++) println(EINRUECKUNG+"l"+i+" when "+(i-1)+", "); println(EINRUECKUNG+"l3 when others;"); println(); println(EINRUECKUNG+"with u1 select out1 <="); for(int i=0;i<3;i++) println(EINRUECKUNG+"l"+(4+i)+" when "+(i-1)+", "); println(EINRUECKUNG+"l7 when others;"); println(); println(EINRUECKUNG+"with u2 select out2 <="); for(int i=0;i<3;i++) println(EINRUECKUNG+"l"+(8+i)+" when "+(i-1)+", "); println(EINRUECKUNG+"l11 when others;"); } public void draw() { }
Code 0-13: MUSTERLÖSUNG zur Generierung eines Netzes mit nur 2 Bit Ausgangswertebereich pro Neuron
err=15.297058540778355 err=15.033296378372908 err=14.594519519326424 err=13.892443989449804 err=12.884098726725126 err=9.055385138137417 err=6.324555320336759 err=2.8284271247461903 err=0.0 err=0.0 constant w0: integer := 1; constant w1: integer := 5; constant w2: integer := 7; constant w3: integer := 5; constant w4: integer := -8; constant w5: integer := 6; constant l0: integer := 7; constant l1: integer := 6; constant l2: integer := -3; constant l3: integer := -6; constant l4: integer := -4; constant l5: integer := -1; constant l6: integer := -3; constant l7: integer := -8; constant l8: integer := 7; constant l9: integer := -8; constant l10: integer := 5; constant l11: integer := -4; with u0 select out0 <= l0 when -1, l1 when 0, l2 when 1, l3 when others; with u1 select out1 <= l4 when -1, l5 when 0, l6 when 1, l7 when others; with u2 select out2 <= l8 when -1, l9 when 0, l10 when 1, l11 when others;
Code 0-14: Ausgabe des Optimierers und Code-Generators.
#6 Mo 05.04.2025
Vorab, Rolle von FPGAs von Xilinx im Ukraine-Krieg:

Themen
|





#7 Mo 13.05.2025
Themen
|
1. Präsentation zu Projekt #1: D-Flip-Flop (?)

2. Erstellen eigener Module und deren Einbindung am Beispiel D-Flip-Flop und Schieberegister

3. Verwendung der vorgefertigten Module der UNISIM Bibliothek


4. Fortsetzung der Projektarbeiten
#8 Mo 19.05.2025
|
Themen
|
4. ÜBUNG: Schieberegister bestehend aus vier D-Flip-Flops, die aus einem Modul instanziiert werden

1. Projektpräsentation zur Emulation einer seriellen Schnittstelle

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY Transfert IS PORT ( MEINECLOCK : IN STD_LOGIC; TXD : OUT STD_LOGIC ); END Transfert; ARCHITECTURE BEHAVIORAL OF Transfert IS TYPE char_array IS ARRAY (0 TO 4) OF STD_LOGIC_VECTOR(7 DOWNTO 0); CONSTANT LETTRES : char_array := ( 0 => "01001000", -- H 1 => "01000101", -- E 2 => "01001100", -- L 3 => "01001100", -- L 4 => "01001111" -- O ); SIGNAL zaehler : INTEGER RANGE 0 TO 624 := 0; SIGNAL bit_counter : INTEGER RANGE 0 TO 15 := 0; SIGNAL char_index : INTEGER RANGE 0 TO 4 := 0; SIGNAL logikpegel : STD_LOGIC := '1'; SIGNAL current_word : STD_LOGIC_VECTOR(15 DOWNTO 0); CONSTANT PREFIX : STD_LOGIC_VECTOR(3 DOWNTO 0) := "1110"; CONSTANT POSTFIX : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0111"; BEGIN current_word <= PREFIX & LETTRES(char_index) & POSTFIX; PROCESS (MEINECLOCK) BEGIN IF rising_edge(MEINECLOCK) THEN IF zaehler = 624 THEN zaehler <= 0; -- Réinitialisation du compteur de timing logikpegel <= current_word(15 - bit_counter);--MSB senden TXD <= logikpegel; IF bit_counter = 15 THEN bit_counter <= 0; IF char_index = 4 THEN char_index <= 0; ELSE char_index <= char_index + 1; END IF; ELSE bit_counter <= bit_counter + 1; END IF; ELSE zaehler <= zaehler + 1; END IF; END IF; END PROCESS; END BEHAVIORAL;
Code 0-15: VHDL-Quelltext, studentische Lösung.
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; ## IO_L05P_0 ist auf FPGA-Chip Pin 125 NET "TXD" LOC = "P125"; NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "TXD" IOSTANDARD = LVCMOS33;
Code 0-16: Constraints-Datei.
#9 Mo 26.05.2025
Themen
|
1. Quiz
|
2. Übersicht zu den bereits behandelten Themen
|
3. Beispiel: Erzeugung eines Sinustones unter Verwendung eines R-2R-Netzes
Testumsetzung: Tonausgabe über DA-Wandler R/2R-Netzwerk, nur Rechtecksignal
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- WICHTIG, DAMIT CONCURRENT WHEN einen Effekt hat! -- Umsetzung eines DAC am Beispiel eines Rechteckgenerators -- 20Khz Samplerate -- 200Hz Ausgang -- 100 Schritte für 200Hz entity sinus is Port ( MEINECLOCK : in STD_LOGIC; ANALOG : out STD_LOGIC_VECTOR (7 downto 0)); end sinus; architecture Behavioral of sinus is signal zaehler : integer range 0 to 299 := 0; --20kHz signal zaehler2 : integer range 0 to 99 := 0; --200Hz signal wort : std_logic_vector(7 downto 0); begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<299) then zaehler <= zaehler+1; else zaehler <= 0; ---- Beginn zähler 2 if (zaehler2<99) then zaehler2 <= zaehler2+1; else zaehler2 <= 0; end if; end if; end process; --- Zuordnungen zum Ausgang, Test Rechteckschwingung von 200Hz with zaehler2 select wort <= "11111111" when 0 to 50, "00000000" when others; ANALOG <= wort; end Behavioral;
Code 0-17: 1. Testumsetzung: Tonausgabe über DA-Wandler R/2R-Netzwerk, nur Rechtecksignal
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; ## IO_L05P_0 ist auf FPGA-Chip Pin 125 NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "ANALOG<0>" LOC = "P58" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<1>" LOC = "P59" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<2>" LOC = "P93" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<3>" LOC = "P94" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<4>" LOC = "P96" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<5>" LOC = "P97" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<6>" LOC = "P103" | IOSTANDARD = LVCMOS33 ; NET "ANALOG<7>" LOC = "P104" | IOSTANDARD = LVCMOS33 ;
Code 0-18: Constraints zu 1. Testumsetzung.
|

Bild 0-2: Schaltung zum Tongebeber.

Bild 0-3: Schaltungsaufbau zum Tongebeber (sehr leise).
2. Testumsetzung: Sinuston über DA-Wandler R/2R-Netzwerk
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- Umsetzung eines DAC am Beispiel eines Sinusgenerators -- 20Khz Samplerate -- 200Hz Ausgang -- 100 Schritte für 200Hz entity sinus is Port ( MEINECLOCK : in STD_LOGIC; ANALOG : out STD_LOGIC_VECTOR (7 downto 0)); end sinus; architecture Behavioral of sinus is signal zaehler : integer range 0 to 299 := 0; --20kHz signal zaehler2 : integer range 0 to 99 := 0; --200Hz signal wort : std_logic_vector(7 downto 0); begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<299) then zaehler <= zaehler+1; else zaehler <= 0; ---- Beginn zähler 2 if (zaehler2<99) then zaehler2 <= zaehler2+1; else zaehler2 <= 0; end if; end if; end process; --- Zuordnungen zum Ausgang, Test Rechteckschwingung von 200Hz with zaehler2 select wort <= "00000000" when 0, "00000000" when 1, "00000001" when 2, "00000010" when 3, "00000100" when 4, "00000110" when 5, "00001000" when 6, "00001100" when 7, "00001111" when 8, "00010011" when 9, "00011000" when 10, "00011101" when 11, "00100010" when 12, "00101000" when 13, "00101110" when 14, "00110100" when 15, "00111011" when 16, "01000010" when 17, "01001001" when 18, "01010000" when 19, "01011000" when 20, "01011111" when 21, "01100111" when 22, "01101111" when 23, "01110111" when 24, "01111111" when 25, "10000111" when 26, "10001111" when 27, "10010111" when 28, "10011111" when 29, "10100110" when 30, "10101110" when 31, "10110101" when 32, "10111100" when 33, "11000011" when 34, "11001010" when 35, "11010000" when 36, "11010110" when 37, "11011100" when 38, "11100001" when 39, "11100110" when 40, "11101011" when 41, "11101111" when 42, "11110010" when 43, "11110110" when 44, "11111000" when 45, "11111010" when 46, "11111100" when 47, "11111101" when 48, "11111110" when 49, "11111110" when 50, "11111110" when 51, "11111101" when 52, "11111100" when 53, "11111010" when 54, "11111000" when 55, "11110110" when 56, "11110010" when 57, "11101111" when 58, "11101011" when 59, "11100110" when 60, "11100001" when 61, "11011100" when 62, "11010110" when 63, "11010000" when 64, "11001010" when 65, "11000011" when 66, "10111100" when 67, "10110101" when 68, "10101110" when 69, "10100110" when 70, "10011111" when 71, "10010111" when 72, "10001111" when 73, "10000111" when 74, "01111111" when 75, "01110111" when 76, "01101111" when 77, "01100111" when 78, "01011111" when 79, "01011000" when 80, "01010000" when 81, "01001001" when 82, "01000010" when 83, "00111011" when 84, "00110100" when 85, "00101110" when 86, "00101000" when 87, "00100010" when 88, "00011101" when 89, "00011000" when 90, "00010011" when 91, "00001111" when 92, "00001100" when 93, "00001000" when 94, "00000110" when 95, "00000100" when 96, "00000010" when 97, "00000001" when 98, "00000000" when 99, "00000000" when others; ANALOG <= wort; end Behavioral;
Code 0-19: 2. Testumsetzung: Sinuston über DA-Wandler R/2R-Netzwerk
Contraints wie zuvor.

public void setup() { for(int i=0;i<100;i++) { double dt = 1.0/20000.0; double t = (double)i*dt; double x = -Math.cos(2.0*Math.PI*200.0*t); double y = 255.0*((x+1.0)*0.5); int iy = (int)y; int a0 = iy%2; iy/=2; int a1 = iy%2; iy/=2; int a2 = iy%2; iy/=2; int a3 = iy%2; iy/=2; int a4 = iy%2; iy/=2; int a5 = iy%2; iy/=2; int a6 = iy%2; iy/=2; int a7 = iy%2; println(" \""+a7+""+a6+""+a5+""+a4+""+a3+""+a2+""+a1+""+a0+"\" when "+i+","); } }
Code 0-20: Codegenerator mit Processing für when-statement.
Testen Sie das Projekt sinus.
4. Beispiel: Erzeugung einer "Obertonmusik" (ursprünglich Übung)
|
Um das Geschehen akustisch wahrnehmbar zu machen, soll folgende Schaltung aufgebaut werden:

Bild 0-4: Schaltung für "Obertonspiel".
Hinweise:
|
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.std_logic_arith.all; use IEEE.NUMERIC_STD.ALL; library UNISIM; use UNISIM.VComponents.all; entity ober is Port (MEINECLOCK : STD_Logic; aus : out STD_LOGIC_VECTOR (7 downto 0)); end ober; architecture Behavioral of ober is constant f0: integer := 29999; constant f1: integer := 14999; constant f2: integer := 9999; constant f3: integer := 7499; constant f4: integer := 5999; constant f5: integer := 4999; constant f6: integer := 4285; constant f7: integer := 3749; signal zaehler0 : integer range 0 to 29999 := 0; signal zaehler1 : integer range 0 to 14999 := 0; signal zaehler2 : integer range 0 to 9999 := 0; signal zaehler3 : integer range 0 to 7499 := 0; signal zaehler4 : integer range 0 to 5999 := 0; signal zaehler5 : integer range 0 to 4999 := 0; signal zaehler6 : integer range 0 to 4285 := 0; signal zaehler7 : integer range 0 to 3749 := 0; signal frequenz : integer range 0 to 2999999 := 0; signal wort : integer range 0 to 256 := 0; signal Ausgang: STD_LOGIC_VECTOR (7 downto 0) := "00000000"; signal takt0 : STD_LOGIC := '0'; signal takt1 : STD_LOGIC := '0'; signal takt2 : STD_LOGIC := '0'; signal takt3 : STD_LOGIC := '0'; signal takt4 : STD_LOGIC := '0'; signal takt5 : STD_LOGIC := '0'; signal takt6 : STD_LOGIC := '0'; signal takt7 : STD_LOGIC := '0'; begin process begin wait until rising_edge(MEINECLOCK); if(zaehler0<f0)then zaehler0 <= zaehler0 + 1; else zaehler0 <= 0; takt0 <= not takt0; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler1<f1)then zaehler1 <= zaehler1 + 1; else zaehler1 <= 0; takt1 <= not takt1; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler2<f2)then zaehler2 <= zaehler2 + 1; else zaehler2 <= 0; takt2 <= not takt2; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler3<f3)then zaehler3 <= zaehler3 + 1; else zaehler3 <= 0; takt3 <= not takt3; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler4<f4)then zaehler4 <= zaehler4 + 1; else zaehler4 <= 0; takt4 <= not takt4; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler5<f5)then zaehler5 <= zaehler5 + 1; else zaehler5 <= 0; takt5 <= not takt5; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler6<f6)then zaehler6 <= zaehler6 + 1; else zaehler6 <= 0; takt6 <= not takt6; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(zaehler7<f7)then zaehler7 <= zaehler7 + 1; else zaehler7 <= 0; takt7 <= not takt7; end if; end process; process begin wait until rising_edge(MEINECLOCK); if(frequenz<2999999)then frequenz <= frequenz + 1; else frequenz <= 0; if(wort>255)then wort <= 0; else wort <= wort +1; end if; end if; end process; Ausgang <= conv_std_logic_vector(wort,Ausgang'length); aus(0) <= takt0 and Ausgang(0); aus(1) <= takt1 and Ausgang(1); aus(2) <= takt2 and Ausgang(2); aus(3) <= takt3 and Ausgang(3); aus(4) <= takt4 and Ausgang(4); aus(5) <= takt5 and Ausgang(5); aus(6) <= takt6 and Ausgang(6); aus(7) <= takt7 and Ausgang(7); end Behavioral;
Code 0-21: Studentische Lösung zu "Obertonmusik".
NET "aus<0>" LOC = "P126" | IOSTANDARD = LVCMOS33 ; NET "aus<1>" LOC = "P130" | IOSTANDARD = LVCMOS33 ; NET "aus<2>" LOC = "P131" | IOSTANDARD = LVCMOS33 ; NET "aus<3>" LOC = "P132" | IOSTANDARD = LVCMOS33 ; NET "aus<4>" LOC = "P134" | IOSTANDARD = LVCMOS33 ; NET "aus<5>" LOC = "P135" | IOSTANDARD = LVCMOS33 ; NET "aus<6>" LOC = "P139" | IOSTANDARD = LVCMOS33 ; NET "aus<7>" LOC = "P140" | IOSTANDARD = LVCMOS33 ; NET "MEINECLOCK" LOC = "P56" | IOSTANDARD = LVCMOS25;
Code 0-22: Zugehörige Constraint-Datei zu "Obertonmusik".

Bild 0-5: Aufbau zu "Obertonmusik"

5. Projektübung: Entwicklung eines elektronischen Musikinstruments
|
#10 Mo 02.05.2025
Ankündigung, nächster Termin: Probe-E-Test Montag, 16.06.
Themen
|
1. Rückblick auf die praktische Verwendung der Xilinx IDE:
|
2. Rückblick auf den DSPFPGA und die FPGA-Familie Spartan 3E

3. Vertiefung: Struktur von FPGA-Programmen, synchrone und asynchrone Schaltungen

4. Vertiefung: Analyse von Programmen mit und ohne Prozess-Bereich


5. Sprachelemente von VHDL -- Vorstellung einiger häufig verwendeter Datentypen und Programmstrukturen

#11 Mo 16.06.2025
Themen
|
1. Probe-E-Test
|
|
Praktische Aufgabe
|
|
Zustand Nr. | Zeit/s | P59 | P93 | P94 | P96 |
---|---|---|---|---|---|
0 | 0,0 | HIGH | LOW | LOW | LOW |
1 | 0,2 | LOW | HIGH | LOW | LOW |
2 | 0,4 | LOW | LOW | HIGH | LOW |
3 | 0,6 | LOW | LOW | LOW | HIGH |
Tabelle 0-2: Zeitliche Abfolge der Zustände auf den angegebenen Port-Ausgängen.
HINWEISE:
|
2. Besprechung
#12 Mo 23.06.2025
ACHTUNG: Wegen eines Zugausfalls verspäte ich mich heute um 10 Minuten. Bitte arbeiten Sie schon an der praktischen Aufgabe aus der Probeklausur weiter.
Themen
|

Processing Beispiel
import java.util.Random; Random zufall = new Random(); Ball[] ball = new Ball[1000]; public void setup() { size(500,500); frameRate(30); for(int i=0;i<ball.length;i++) ball[i] = new Ball(); } public void draw() { background(255); for(int i=0;i<ball.length;i++) ball[i].draw(); }
Code 0-23: Randomart003
public class Ball { int x,y,d,t,r,g,b; public Ball() { x = zufall.nextInt(width); y = zufall.nextInt(height); d = zufall.nextInt(height/5); t = zufall.nextInt(256); r = zufall.nextInt(256); g = zufall.nextInt(256); b = zufall.nextInt(256); } public void draw() { fill(r,g,b,t); ellipse(x,y,d,d); } }
Code 0-24: Tab Ball