DAY BY DAY zu HDL -- Echtzeitanwendungen auf Basis von HDL
(EN google-translate)
(PL google-translate)
Übersicht
|
Die Lehrveranstaltung Echtzeitanwendungen auf Basis von HDL richtet sich an Studierende der Ingenieurwissenschaften im sechsten Semester. Die Lehrveranstaltung konzentriert sich auf die Vermittlung der Programmiersprache VHDL (VHSIC (Very High Speed Integrated Circuits) Hardware Description Language). Es wird vorausgesetzt, dass die Vermittlung der verschiedenen Archtekturen für FPGAs (Field Programmable Gate Arrays), sowie der Schaltungsentwurf mit FPGA-ICs in anderen LVs erfolgt. Jedoch unterscheidet sich konzeptuell HDL so grundlegend von Prozeß- oder Objektorientierten Programmiersprachen, wie sie in vorangehenden LVs vermittelt wurden, dass dessen Vermittlung auch den hier verfügbaren zeitlichen Rahmen erfordert.
Chronologisches Verzeichnis der im Verlauf des Semesters behandelten Themen
#1 Do 17.03.2022
Motivation / Diskussion ... Grey Walter's tortoises 1949Teil 1: Behandlung grundlegender Fragestellung zu FPGAs und HDL
|
Was ist ein FPGA? -- 69_FPGA/01_Einfuehrung
Teil 2: Vorberetung der ersten Übung mit einem FPGA-Board
|
Getting started alte Version mit ISE9 -- 69_FPGA/04_Getting_Started
AKTUELL: Verwendung von XSE14 -- 69_FPGA/21_XSE14
Upload des kompilierten Images -- 69_FPGA/02_Einrichtung/02_BitLoadApp
69_FPGA/11_VHDL -- Kleine Referenz zu VHDL
#2 Do 24.03.2022
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
|
(Hier geht es erst einmal nur darum, mit der Entwicklungsumgebung XSE und der Bitloadapp und Xubuntu klar zu kommen.)
Ü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-1: 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-2: Constraints (.ucf-Datei) zum UND-Gatter.
Variieren Sie dieses Projekt so, dass es dann drei Eingänge hat. Der Ausgang soll dabei dann logisch 1 annehmen, wenn der erste und zweite Eingang im gleichen Zustand sind und der Zustand des dritten Eingangs dazu invers ist.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity UND_GATTER_3IN_1OUT is Port ( a : in STD_LOGIC; b : in STD_LOGIC; c : in STD_LOGIC; d : out STD_LOGIC); end UND_GATTER_3IN_1OUT; architecture Behavioral of UND_GATTER_3IN_1OUT is begin d<=(a and b and (not c)) or ((not a) and (not b) and c); end Behavioral;
Code 0-3: Studentische Lösung VHD
NET "a" LOC = "P140" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "b" LOC = "P139" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "c" LOC = "P135" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "d" LOC = "P131" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ;
Code 0-4: Studentische Lösung UCF
ÜBUNG 3
Variieren Sie das Beispiel mit der blinkenden LED so, dass diese nun mit 4 Hertz blinkt.
einfach ändern: if (zaehler<2999999) then zu if (zaehler<749999) then
Code 0-5: Lösung
Ü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:
|
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-6: 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-7: 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-8: VHD-Datei
#3 Do 31.03.2022
Themen
|
-- Umwandlung einer Integerzahl in ein Vierbit-Wort: wort <= conv_std_logic_vector(kleinerzaehler,VIERBIT'length); -- Code 0-5: Beispiele zur Verknüpfung logischer Wörter, um bestimmte Operationen zu realisieren. signal wort1 : std_logic_vector(3 downto 0) := "1010"; signal wort2 : std_logic_vector(3 downto 0) := "1110"; signal wort3 : std_logic_vector(7 downto 0) := "10101111"; -- .... -- .... --Verknüpfung zweier Vierbit-Worte zu einem 8-Bit-Wort wort3 <= wort1 & wort2; --Wiederholung eines Vierbit-Wortes wort3 <= wort1 & wort1; --Bitshift um eine Stelle nach links wort3 <= wort3(6 downto 0) & '0'; --Bitshift um zwei Stelle nach rechts wort3 <= "00" & wort3(7 downto 2); --Rotation nach links wort3 <= wort3(6 downto 0) & wort3(7);
Code 0-9: Aus 11_VHDL
|
ÜBUNG 1
|
ÜBUNG 2
|
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity lauflicht is Port ( ledOut : out STD_LOGIC_VECTOR(3 downto 0); clock : in STD_LOGIC); end lauflicht; architecture Behavioral of lauflicht is signal i : integer range 0 to 2999999 := 0; signal wordOne : std_logic_vector(3 downto 0) := "0001"; signal logicLevel : std_logic := '0'; begin process begin wait until rising_edge(clock); if (i<2999999) then i <= i+1; else i <= 0; logicLevel <= not logicLevel; wordOne <= wordOne(2 downto 0) & wordOne(3); end if; end process; ledOut <= wordOne; end Behavioral;
Code 0-10: Studentische Lösung VHDL
NET "clock" LOC = "P56" | IOSTANDARD = LVCMOS33; NET "ledOut<0>" LOC = "P126" | IOSTANDARD = LVCMOS33; NET "ledOut<1>" LOC = "P130" | IOSTANDARD = LVCMOS33; NET "ledOut<2>" LOC = "P131" | IOSTANDARD = LVCMOS33; NET "ledOut<3>" LOC = "P132" | IOSTANDARD = LVCMOS33;
Code 0-11: Studentische Lösung UCF
#4 Do 07.04.2022
Themen
|
69_FPGA/09_Uebung -- Schieberegister
69_FPGA/10_Servo -- Modellbauservo
Siehe auch: 40_Mikrocontroller/04_PWM
#5 Do 21.04.2022
Heute soll die Möglichkeit behandelt werden, vordefinierte Module einzusetzen. Diese werden von der Xilinx-IDE über die UNISIM-Library bereitgestellt.
Folgende Beispiele werden gemeinsam im Unterricht analysiert:
69_FPGA/13_LUT -- Verwendung eines Lookup-Tables (hier UNISIM LUT4) statt logischer Operationen, um ein bestimmtes logisches Verhalten zu realisieren.
Ü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.
|
Musterlösung
Ausgangspunkt war der Binärzähler hier:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; -- Ausgangspunkt: -- http://www.kramann.info/69_FPGA/05_Beispiele/02_Binaerzaehler/index.php entity lauflicht is Port ( MEINECLOCK : in STD_LOGIC; VIERBIT : out STD_LOGIC_VECTOR (3 downto 0)); end lauflicht; architecture Behavioral of lauflicht is signal zaehler : integer range 0 to 2999999 := 0; signal VIERBITZAEHLER : integer range 0 to 15 := 0; signal wort : std_logic_vector(3 downto 0); begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<2999999) then zaehler <= zaehler+1; else zaehler <= 0; if(VIERBITZAEHLER<15) then VIERBITZAEHLER <= VIERBITZAEHLER+1; else VIERBITZAEHLER <= 0; end if; end if; end process; -- Typumwandlung erforderlich, da Mapping zwischen unterschiedlichen Datentypen: LUT4_instanz1 : LUT4 generic map ( INIT => "0000000000001111" ) port map (O => VIERBIT(0),I0 => wort(0),I1 => wort(1),I2 => wort(2),I3 => wort(3)); LUT4_instanz2 : LUT4 generic map ( INIT => "0000000011110000" ) port map (O => VIERBIT(1),I0 => wort(0),I1 => wort(1),I2 => wort(2),I3 => wort(3)); LUT4_instanz3 : LUT4 generic map ( INIT => "0000111100000000" ) port map (O => VIERBIT(2),I0 => wort(0),I1 => wort(1),I2 => wort(2),I3 => wort(3)); LUT4_instanz4 : LUT4 generic map ( INIT => "1111000000000000" ) port map (O => VIERBIT(3),I0 => wort(0),I1 => wort(1),I2 => wort(2),I3 => wort(3)); wort <= conv_std_logic_vector(VIERBITZAEHLER,VIERBIT'length); end Behavioral;
Code 0-12: lauflicht7 -- VHDL
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; ## Mapping muss bitweise erfolgen: NET "VIERBIT<3>" LOC = "P126"; NET "VIERBIT<2>" LOC = "P130"; NET "VIERBIT<1>" LOC = "P131"; NET "VIERBIT<0>" LOC = "P132"; NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "VIERBIT<3>" IOSTANDARD = LVCMOS33; NET "VIERBIT<2>" IOSTANDARD = LVCMOS33; NET "VIERBIT<1>" IOSTANDARD = LVCMOS33; NET "VIERBIT<0>" IOSTANDARD = LVCMOS33;
Code 0-13: lauflicht7 --constraints
LUT4_Lauflicht.zip -- studentische Lösung.
Wenn es nur darum geht ein Lauflicht zu erzeugen und keine anderen Muster, kann natürlich eine wesentlich einfachere Lösung durch Rotation eines Bitmusters gefunden werden. Nachfolgend findet sich wieder eine studentische Lösung:
#6 Do 28.04.2022 wie Do 21.04.2022
#7 Do 05.05.2022
Themen:
|
Übung 1
Bauen und testen Sie das serielle Übertragungssystem.
ACHTUNG: Das Beispiel wurde für ein anderes FPGA-Board entwickelt. Nehmen Sie alle notwendigen Anpassungen selber vor.
Lösen Sie auch die Übungsaufgaben, die unter dem Beispiel stehen.
Problematiken und mögliche Umsetzungen für das Auswählen der zu sendenden Buchstaben über DIP-Schalter (vergl. Aufgaben unter dem Beispiel), soll nach einiger Zeit im Plenum diskutiert werden.
Übung 2
Über einen vierfachen DIP-Schalter sollen bei einem FPGA die ersten 16 Buchstaben im Alphabet ausgewählt werden können.
Per Konpfdruck soll dann die Wahl als Morsecode mit einer LED dargestellt werden.
Diskutieren Sie in Zweiergruppen, eine sinnvolle Implementierungsmöglichkeit und setzen das Projekt dann um.
Wählen Sie die verwendeten Ein- und Ausgänge selber frei aus.
Nicht festgelegte Randbedingungen zur Lösung dieser Aufgabe könne frei, aber in sinnvoller Weise festgelegt werden. Stets ist eine kurze effiziente Implementierung einer aufwändigen vorzuziehen.
#8 Do 12.05.2022
Prüfung (Projekt mit Hardware): Donnerstag 23.06. ab 12:30Uhr.
|
Thema: Komplex-Projekt, Software-Entwurf und Bau einer Stoppuhr
|
https://www.farnell.com/datasheets/2095874.pdf -- Anzeigeelement 2.
Beispiellösung für einen FPGA
69_FPGA/22_UebungBeispielumsetzung mit einem Arduino-Micro zur Orientierung
45_Mikro17/09_Uebung2017Teillösungen
stoptest002.zip -- Testweise nur eine 8 anzeigen auf dem ersten Digitstoppuhr.zip -- Testweise nur auf erstem Digit von 0 bis 9 zyklisch im Halb-Sekundentakt zählen.
#9 Do 19.05.2022
Fortsetzung Stoppuhr
Nach ein paar Anlaufschwierigkeiten letzte Woche, sollte es uns heute gelingen im Rahmen einer fortgesetzten Übung die FPGA-basierte Stoppuhr fertigzustellen.
Schwierigkeiten gab es unter anderem folgende:
|
Bild 0-1: Datenblatt Seite 5: das von uns verwendete Element HDSP-B08G hat GEMEINSAME ANODEN (und nicht Kathoden).
Muster-Teillösung: eines der Segmente zählt zyklisch von 0 bis 9
stoppuhr.zip -- Testweise nur auf erstem Digit von 0 bis 9 zyklisch im Halb-Sekundentakt zählen.library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity stoppuhr is Port ( MEINECLOCK : in STD_LOGIC; TASTE : in STD_LOGIC; ANZEIGE : out STD_LOGIC_VECTOR (11 downto 0) := "000000000000"); end stoppuhr; architecture Behavioral of stoppuhr is -- PIN: 12 11 10 9 8 7 6 5 4 3 2 1 -- BIT: 11 10 9 8 7 6 5 4 3 2 1 0 -- D1 A F D2 D3 B D4 G C DP D E -- 1AF23B4GCPDE constant ZIFFER0: STD_LOGIC_VECTOR := "100110110100"; constant ZIFFER1: STD_LOGIC_VECTOR := "111110110111"; constant ZIFFER2: STD_LOGIC_VECTOR := "101110101100"; constant ZIFFER3: STD_LOGIC_VECTOR := "101110100101"; constant ZIFFER4: STD_LOGIC_VECTOR := "110110100111"; constant ZIFFER5: STD_LOGIC_VECTOR := "100111100101"; constant ZIFFER6: STD_LOGIC_VECTOR := "100111100100"; constant ZIFFER7: STD_LOGIC_VECTOR := "101110110111"; constant ZIFFER8: STD_LOGIC_VECTOR := "100110100100"; constant ZIFFER9: STD_LOGIC_VECTOR := "100110100101"; -- 1AF23B4GCPDE -- 1AF23B4GCPDE constant DIGIT1: STD_LOGIC_VECTOR := "111001011111"; constant DIGIT2: STD_LOGIC_VECTOR := "011101011111"; constant DIGIT3: STD_LOGIC_VECTOR := "011011011111"; constant DIGIT4: STD_LOGIC_VECTOR := "011001111111"; signal zaehler : integer range 0 to 2999999 := 0; signal ziffer : integer range 0 to 9 := 0; signal anz : std_logic_vector (11 downto 0) := "000000000000"; begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<2999999) then zaehler <= zaehler+1; else zaehler <= 0; -- ziffer hochzaehlen if (ziffer<9) then ziffer <= ziffer+1; else ziffer <= 0; end if; -- end ziffer hochzaehlen end if; -- case muss in einen Prozess! case ziffer is when 0 => anz <= ZIFFER0 and DIGIT1; when 1 => anz <= ZIFFER1 and DIGIT1; when 2 => anz <= ZIFFER2 and DIGIT1; when 3 => anz <= ZIFFER3 and DIGIT1; when 4 => anz <= ZIFFER4 and DIGIT1; when 5 => anz <= ZIFFER5 and DIGIT1; when 6 => anz <= ZIFFER6 and DIGIT1; when 7 => anz <= ZIFFER7 and DIGIT1; when 8 => anz <= ZIFFER8 and DIGIT1; when 9 => anz <= ZIFFER9 and DIGIT1; when others => anz <= "000000000000"; end case; end process; ANZEIGE <= anz; end Behavioral;
Code 0-14: stoppuhr.zip -- Muster-Teillösung: eines der Segmente zählt zyklisch von 0 bis 9.
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; NET "TASTE" LOC = "P58" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "ANZEIGE<11>" LOC = "P116"; NET "ANZEIGE<10>" LOC = "P113"; NET "ANZEIGE<9>" LOC = "P112"; NET "ANZEIGE<8>" LOC = "P106"; NET "ANZEIGE<7>" LOC = "P105"; NET "ANZEIGE<6>" LOC = "P104"; NET "ANZEIGE<5>" LOC = "P103"; NET "ANZEIGE<4>" LOC = "P97"; NET "ANZEIGE<3>" LOC = "P96"; NET "ANZEIGE<2>" LOC = "P94"; NET "ANZEIGE<1>" LOC = "P93"; NET "ANZEIGE<0>" LOC = "P59"; NET "ANZEIGE<11>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<10>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<9>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<8>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<7>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<6>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<5>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<4>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<3>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<2>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<1>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<0>" IOSTANDARD = LVCMOS33;
Code 0-15: Constraints zu obigem VHDL-Beispiel.
ÜBUNG
|
#10 Do 02.06.2022
Bisher behandelte und prüfungsrelevante Themen ohne Anspruch auf Vollständigkeit:
|
Ausblick auf nicht behandelte Themen
69_FPGA/07_Testbench -- Simulation von Programmen.68_nexys -- Verwenden einer moderneren aufwändigeren FPGA-Plattform
Projekt Stoppuhr abschließen
|
stoppuhrMusterloesungVIERSEG2.zip -- vollständige Lösung
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values -- use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity stoppuhr is Port ( MEINECLOCK : in STD_LOGIC; TASTE : in STD_LOGIC; ANZEIGE : out STD_LOGIC_VECTOR (11 downto 0) := "000000000000"); end stoppuhr; architecture Behavioral of stoppuhr is -- PIN: 12 11 10 9 8 7 6 5 4 3 2 1 -- BIT: 11 10 9 8 7 6 5 4 3 2 1 0 -- D1 A F D2 D3 B D4 G C DP D E -- 1AF23B4GCPDE constant ZIFFER0: STD_LOGIC_VECTOR := "100110110100"; constant ZIFFER1: STD_LOGIC_VECTOR := "111110110111"; constant ZIFFER2: STD_LOGIC_VECTOR := "101110101100"; constant ZIFFER3: STD_LOGIC_VECTOR := "101110100101"; constant ZIFFER4: STD_LOGIC_VECTOR := "110110100111"; constant ZIFFER5: STD_LOGIC_VECTOR := "100111100101"; constant ZIFFER6: STD_LOGIC_VECTOR := "100111100100"; constant ZIFFER7: STD_LOGIC_VECTOR := "101110110111"; constant ZIFFER8: STD_LOGIC_VECTOR := "100110100100"; constant ZIFFER9: STD_LOGIC_VECTOR := "100110100101"; -- 1AF23B4GCPDE -- 1AF23B4GCPDE constant DIGIT1: STD_LOGIC_VECTOR := "111001011111"; constant DIGIT2: STD_LOGIC_VECTOR := "011101011111"; constant DIGIT3: STD_LOGIC_VECTOR := "011011011111"; constant DIGIT4: STD_LOGIC_VECTOR := "011001111111"; signal welchesdigit : integer range 0 to 3 := 0; signal zaehler : integer range 0 to 2999999 := 0; signal zzzaehler : integer range 0 to 2999 := 0; signal zziffer1 : integer range 0 to 9 := 0; signal zziffer2 : integer range 0 to 9 := 0; signal zziffer3 : integer range 0 to 9 := 0; signal zziffer4 : integer range 0 to 9 := 0; signal anz : std_logic_vector (11 downto 0) := "000000000000"; -- Zählerstand der Stoppuhr: signal COUNT : integer range 0 to 9999 := 0; signal FLAGGE : std_logic := '0'; begin -- PROCESS 0 process begin wait until rising_edge(MEINECLOCK); if (zzzaehler<2999) then zzzaehler <= zzzaehler+1; else zzzaehler <= 0; welchesdigit <= welchesdigit + 1; end if; --------------------------------------------- --DIGIT 1 (ganz links) if ( welchesdigit = 0 ) then case zziffer4 is when 0 => anz <= ZIFFER0 and DIGIT1; when 1 => anz <= ZIFFER1 and DIGIT1; when 2 => anz <= ZIFFER2 and DIGIT1; when 3 => anz <= ZIFFER3 and DIGIT1; when 4 => anz <= ZIFFER4 and DIGIT1; when 5 => anz <= ZIFFER5 and DIGIT1; when 6 => anz <= ZIFFER6 and DIGIT1; when 7 => anz <= ZIFFER7 and DIGIT1; when 8 => anz <= ZIFFER8 and DIGIT1; when 9 => anz <= ZIFFER9 and DIGIT1; when others => anz <= "000000000000"; end case; end if; --DIGIT 2 if ( welchesdigit = 1 ) then case zziffer3 is when 0 => anz <= ZIFFER0 and DIGIT2; when 1 => anz <= ZIFFER1 and DIGIT2; when 2 => anz <= ZIFFER2 and DIGIT2; when 3 => anz <= ZIFFER3 and DIGIT2; when 4 => anz <= ZIFFER4 and DIGIT2; when 5 => anz <= ZIFFER5 and DIGIT2; when 6 => anz <= ZIFFER6 and DIGIT2; when 7 => anz <= ZIFFER7 and DIGIT2; when 8 => anz <= ZIFFER8 and DIGIT2; when 9 => anz <= ZIFFER9 and DIGIT2; when others => anz <= "000000000000"; end case; end if; --DIGIT 3 if ( welchesdigit = 2 ) then case zziffer2 is when 0 => anz <= ZIFFER0 and DIGIT3; when 1 => anz <= ZIFFER1 and DIGIT3; when 2 => anz <= ZIFFER2 and DIGIT3; when 3 => anz <= ZIFFER3 and DIGIT3; when 4 => anz <= ZIFFER4 and DIGIT3; when 5 => anz <= ZIFFER5 and DIGIT3; when 6 => anz <= ZIFFER6 and DIGIT3; when 7 => anz <= ZIFFER7 and DIGIT3; when 8 => anz <= ZIFFER8 and DIGIT3; when 9 => anz <= ZIFFER9 and DIGIT3; when others => anz <= "000000000000"; end case; end if; --DIGIT 4 if ( welchesdigit = 3 ) then case zziffer1 is when 0 => anz <= ZIFFER0 and DIGIT4; when 1 => anz <= ZIFFER1 and DIGIT4; when 2 => anz <= ZIFFER2 and DIGIT4; when 3 => anz <= ZIFFER3 and DIGIT4; when 4 => anz <= ZIFFER4 and DIGIT4; when 5 => anz <= ZIFFER5 and DIGIT4; when 6 => anz <= ZIFFER6 and DIGIT4; when 7 => anz <= ZIFFER7 and DIGIT4; when 8 => anz <= ZIFFER8 and DIGIT4; when 9 => anz <= ZIFFER9 and DIGIT4; when others => anz <= "000000000000"; end case; end if; --------------------------------------------- end process; -- PROZESS 1 process begin if ( falling_edge(TASTE) ) then FLAGGE <= '1'; end if; if ( COUNT = 0 ) then -- Lesen von COUNT geht hier. FLAGGE <= '0'; end if; end process; -- PROZESS 2 process begin wait until rising_edge(MEINECLOCK); --Stoppuhr-Bereich if (zaehler<29999) then zaehler <= zaehler+1; elsif (COUNT<9999 and TASTE='0') then if( FLAGGE = '1' ) then COUNT <= 0; -- FLAGGE <= '0'; -- Lesen geht in ZWEI Prozessen, aber Schreiben nur in einem !! zziffer1 <= 0; zziffer2 <= 0; zziffer3 <= 0; zziffer4 <= 0; else COUNT <= COUNT + 1; ------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------ if (zziffer1<9) then zziffer1 <= zziffer1 + 1; else zziffer1 <= 0; if(zziffer2<9) then zziffer2 <= zziffer2 + 1; else zziffer2 <= 0; if(zziffer3<9) then zziffer3 <= zziffer3 + 1; else zziffer3 <= 0; zziffer4 <= zziffer4 + 1; end if; end if; end if; ------------------------------------------------------ ------------------------------------------------------ ------------------------------------------------------ end if; zaehler <= 0; -- auf Ziffer übertragen: --ziffer <= COUNT; -- mod muss "power of two" sein, aber da range 0..9 nicht nötig!! end if; end process; ANZEIGE <= anz; end Behavioral;
Code 0-16: VHDL der Musterlösung zur Stoppuhr
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56"; NET "TASTE" LOC = "P58" | PULLUP | IOSTANDARD = LVCMOS33 ; NET "ANZEIGE<11>" LOC = "P116"; NET "ANZEIGE<10>" LOC = "P113"; NET "ANZEIGE<9>" LOC = "P112"; NET "ANZEIGE<8>" LOC = "P106"; NET "ANZEIGE<7>" LOC = "P105"; NET "ANZEIGE<6>" LOC = "P104"; NET "ANZEIGE<5>" LOC = "P103"; NET "ANZEIGE<4>" LOC = "P97"; NET "ANZEIGE<3>" LOC = "P96"; NET "ANZEIGE<2>" LOC = "P94"; NET "ANZEIGE<1>" LOC = "P93"; NET "ANZEIGE<0>" LOC = "P59"; NET "ANZEIGE<11>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<10>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<9>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<8>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<7>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<6>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<5>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<4>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<3>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<2>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<1>" IOSTANDARD = LVCMOS33; NET "ANZEIGE<0>" IOSTANDARD = LVCMOS33;
Code 0-17: Constraints zur Stoppuhr
Kleine Aufgaben, die den Umgang mit der IDE trainieren und die Prüfung vorbereiten
Aufgabe 1
Eine LED auf P125 soll fortwährend den Morsecode SOS aussenden:
...---... Pause ...---... Pause ...---... Pause usw.
Nähere Spezifikation: Um die Signalfolge zu realisieren wird eine Zeiteinheit von 0,25 Sekunden als Einheit festgelegt. Wenn 1 bedeutet, dass die LED für 0,25 Sekunden leuchtet und 0, dass sie für 0,25 Sekunden aus ist, dann kann ein Zyklus der gewünschten Signalfolge folgendermaßen beschrieben werden:
10101011001100110010101000000000
Setzen Sie das Projekt mit VHDL und, bauen die Hardware auf und demonstrieren das Funktionieren Ihrer Lösung.
Aufgabe 2
Eine LED bei P125 soll nur leuchten, wenn die über vier DIP-Schalter bei P126 (MSB), P130, P131, P132 (LSB) eingestellte Zahl ungerade ist.
Setzen Sie das Projekt mit VHDL und, bauen die Hardware auf und demonstrieren das Funktionieren Ihrer Lösung.
Aufgabe 3
Wie Aufgabe 2, aber zur Lösung muß ein LUT4-Element verwendet werden.
Aufgabe 4
Eine LED bei P125 soll mittels eines PWM-Signals 16 Helligkeitsstufen annehmen können, die über vier DIP-Schalter bei P126 (MSB), P130, P131, P132 (LSB) angeschlossen sind.
Setzen Sie das Projekt mit VHDL und, bauen die Hardware auf und demonstrieren das Funktionieren Ihrer Lösung.
#11 Do 09.06.2022 Probe-E-Test
Regeln für den Probe-E-Test und für den E-Test
Schauen Sie sich die Angaben zum Ablauf eines E-Tests bitte an:
|
Vorbereitungen für den Probe-E-Test und den richtigen E-Test
Packen Sie eine Box mit folgenden Inhalten:
|
Bauen Sie die Blinkschaltung mit 1Hz auf und testen diese
Wenn an jedem Platz die LED blinkt, kann die eigentliche Prüfung beginnen.
Verbleibt noch Zeit, so können die Aufgaben von letzter Woche weiter bearbeitet werden.
#12 Do 16.06.2022
Themen
|
Musterlösung Aufgabe 1 (morsen)
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity morsen is Port ( MEINECLOCK : in STD_LOGIC; MEINELED : out STD_LOGIC); end morsen; architecture Behavioral of morsen is signal zaehler : integer range 0 to 1499999 := 0; signal logikpegel : std_logic := '0'; signal wort : std_logic_vector(31 downto 0) := "10101011001100110010101000000000"; begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<1499999) then zaehler <= zaehler+1; else zaehler <= 0; logikpegel <= wort(31); wort <= wort(30 downto 0) & wort(31); end if; end process; MEINELED <= logikpegel; end Behavioral;
Code 0-18: Musterlösung Aufgabe 1 (morsen)
## 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;
Code 0-19: Constraints
Musterlösung Aufgabe 4 (PWM-LED)
library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity pwmled is Port ( VIERBIT : in STD_LOGIC_VECTOR (3 downto 0); MEINELED : out STD_LOGIC; MEINECLOCK : in STD_LOGIC); end pwmled; architecture Behavioral of pwmled is signal grenze : integer range 0 to 15 := 0; signal langsamerzaehler : integer range 0 to 15 := 0; signal zaehler : integer range 0 to 2999999 := 0; signal logikpegel : std_logic := '0'; begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<2999) then zaehler <= zaehler+1; else -- grenze <= conv_integer(unsigned(VIERBIT)); grenze <= to_integer(unsigned(VIERBIT)); zaehler <= 0; langsamerzaehler <= langsamerzaehler + 1; if ( langsamerzaehler < grenze ) then logikpegel <= '1'; else logikpegel <= '0'; end if; end if; end process; MEINELED <= logikpegel; end Behavioral;
Code 0-20: Musterlösung Aufgabe 4 (PWM-LED)
## 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 "VIERBIT<3>" LOC = "P126" | PULLUP; NET "VIERBIT<2>" LOC = "P130" | PULLUP; NET "VIERBIT<1>" LOC = "P131" | PULLUP; NET "VIERBIT<0>" LOC = "P132" | PULLUP; NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "MEINELED" IOSTANDARD = LVCMOS33; NET "VIERBIT<3>" IOSTANDARD = LVCMOS33; NET "VIERBIT<2>" IOSTANDARD = LVCMOS33; NET "VIERBIT<1>" IOSTANDARD = LVCMOS33; NET "VIERBIT<0>" IOSTANDARD = LVCMOS33;
Code 0-21: Constraints.