Hallo.
Gegeben: VHDL Afänger,
Altera DE1 board mit Cyclon II
Gesucht: Ein 4-Bit Addierer mit LED-Anzeige für die Ausgabe der Lösung
in Binär , und 7-Segment Display für die Ausgabe der Lösung in Dezimal.
Stand der Sache:
-Ein 4-Bit Addierer funktioniert einwandfrei, das Ergebnis der Addition
wird mit LED'S richtig angezeigt!
-EIN 7-Segment element zeigt die erste Zahl des Ergebnises richtig.
Die Kode sieht man unten (Ich habe ein paar bücher über VHDL, und
verarbeite die Kapiteln in ihre Reiehenfolge durch, deswegen bitte nicht
fragen wieso ich irgendeine Methode nicht benutze. Ich bin einfach noch
nicht soweit:)
1
libraryieee;
2
useieee.std_logic_1164.all;
3
useieee.numeric_std.all;
4
useieee.std_logic_signed.all;
5
6
ENTITYadderIS
7
PORT(
8
SW0,SW1,SW2,SW3:INSTD_LOGIC;
9
H0,H1,H2,H3,H4,H5,H6:OUTSTD_LOGIC;
10
HEX1:OUTSTD_LOGIC_VECTOR(7downto0);
11
LED0,LED1,LED2,LED3,LED4:OUTSTD_LOGIC;
12
ENTER:INSTD_LOGIC
13
);
14
ENDadder;
15
16
ARCHITECTUREFOFadderIS
17
SIGNALHEXD1:STD_LOGIC_VECTOR(6downto0);
18
SIGNALRESULT:STD_LOGIC_VECTOR(4downto0);
19
20
21
BEGIN
22
PROCESS(ENTER)
23
VARIABLERE:STD_LOGIC_VECTOR(4downto0);
24
VARIABLEN1:STD_LOGIC_VECTOR(4downto0):="00000";
25
VARIABLEN2:STD_LOGIC_VECTOR(4downto0):="00000";
26
VARIABLES:STD_LOGIC:='0';
27
BEGIN
28
IF(ENTER'EVENTANDENTER='0')THEN
29
IF(S='0')THEN
30
------Zahl 1------
31
N1(0):=SW0;
32
N1(1):=SW1;
33
N1(2):=SW2;
34
N1(3):=SW3;
35
S:='1';
36
37
ELSIF(S='1')THEN
38
-----Zahl 2------
39
N2(0):=SW0;
40
N2(1):=SW1;
41
N2(2):=SW2;
42
N2(3):=SW3;
43
RESULT<=N1+N2;
44
RE:=N1+N2;
45
LED0<=RE(0);
46
LED1<=RE(1);
47
LED2<=RE(2);
48
LED3<=RE(3);
49
LED4<=RE(4);
50
S:='0';
51
ENDIF;
52
53
ENDIF;
54
ENDPROCESS;
55
---------HEX DISPLAY AB HIER-----
56
---------HEX1--------------------
57
58
WITHRESULTSELECT
59
HEXD1<="0111111"WHEN"00000",---0
60
"0000110"WHEN"00001",---1
61
"1011011"WHEN"00010",---2
62
"1001111"WHEN"00011",---3
63
"1100110"WHEN"00100",---4
64
"1101101"WHEN"00101",---5
65
"1111101"WHEN"00110",---6
66
"0000111"WHEN"00111",---7
67
"1111111"WHEN"01000",---8
68
"1101111"WHEN"01001",---9
69
"0111111"WHEN"01010",---10
70
"1111001"WHENOTHERS;--- Error
71
72
73
H0<=NOTHEXD1(0);
74
H1<=NOTHEXD1(1);
75
H2<=NOTHEXD1(2);
76
H3<=NOTHEXD1(3);
77
H4<=NOTHEXD1(4);
78
H5<=NOTHEXD1(5);
79
H6<=NOTHEXD1(6);
80
ENDF;
FRAGEN meinerseits:
-Soll ich jetzt wirklich alle 32 Fälle für das Ergebniss durchgehen, um
die zweistellige Zahl auf zwei HEX-Displays anzuzeigen? Oder mache ich
es komplett falsch, und es gibt ein deutlich einfacherer Weg?
- Für die LED Steuerung habe ich zuerst das hier geschrieben:
1
RESULT<=N1+N2;
2
LED0<=RESULT(0);
3
LED1<=RESULT(1);
4
LED2<=RESULT(2);
5
LED3<=RESULT(3);
6
LED4<=RESULT(4);
Also OHNE zusätzlicher Variable "RE" für die LED's. Doch so eine Lösung
funktionierte nicht richtig. Das Ergebnis auf HEX-Display wurde zwar
immer richtig angezeigt, doch die Lösung in binär wurde nur noch jeden
zweiten mal ausgeleuchtet, manchmal sogar verspätet(also die Zahl von
vorher...)
Liegt es daran, das ich den Signal RESULT nach "außen" führe? Also
auserhalb des PROCESSES, so dass die LED Zuweisung keine Zeit hat,
diesen Signal abzugreifen? Sind die Signale nur einmal "verwendbar"?
UND die Dritte Frage:
Ist es möglich alle Ports in einen ARRAY oder TYP zu schreiben, so was
wie:
LEDS:= (LED1,LED2,LED3,LED4)
Damit ich dann später schreiben kann
LEDS <="0101"; und damit direkt die gewünschte LED auf HIGH setze?
Danke für die Aufmerksamkheit und Zeit.
> FRAGEN meinerseits:> -Soll ich jetzt wirklich alle 32 Fälle für das Ergebniss durchgehen, um> die zweistellige Zahl auf zwei HEX-Displays anzuzeigen?
Nein, das ist nicht nötig.
> Oder mache ich es komplett falsch,
Das nicht unbedingt.
> und es gibt ein deutlich einfacherer Weg?
Das schon. Du machst zu viele Umwege, aber das liegt daran, dass du
wegen fehlender Erfahrung die einfachen Wege (noch) nicht siehst. Übung
macht hier den Meister.
> Das Ergebnis auf HEX-Display wurde zwar immer richtig angezeigt,> doch die Lösung in binär wurde nur noch jeden zweiten mal> ausgeleuchtet, manchmal sogar verspätet(also die Zahl von vorher...)
Ich schlage hier mal eine Simulation vor. Der Fehler ist
höchstwahrscheinlich ein prellender Taster, der als Enter-Taste
verwendet wird:
1
IF(ENTER'EVENTANDENTER='0')THEN
2
IF(S='0')THEN
3
...
4
S:='1';
5
ELSIF(S='1')THEN
6
...
7
S:='0';
8
ENDIF;
Diese beiden Zustände von S werden pro Tasterbetätigung gleich ein paar
Mal durchlaufen...
Ich schlage dir vor, ein synchrones Design mit einem Quarztakt
(20-100MHz) aufzubauen, den Taster einzusynchronisieren und erst dann
die auswertung zu machen.
> Liegt es daran, das ich den Signal RESULT nach "außen" führe? Also> auserhalb des PROCESSES, so dass die LED Zuweisung keine Zeit hat,> diesen Signal abzugreifen?
Nein, es liegt am prellenden Taster. Die Zuweisung braucht keine Zeit,
weil sie gleichzeitig existiert. Die Zuweisungen sind nur Verbindungen
im FPGA, da muss nichts ausgeführt werden, die sind einfach immer da.
> Sind die Signale nur einmal "verwendbar"?
Signale sind beliebig oft lesbar. Beim Schreiben kann es aber mal zu
Problemen mit einer "Multi Source" kommen (da wirst du dann bei
Gelegenheit drüber stolpern). Nur Ausgangs-Ports können nicht gelesen
werden.
> UND die Dritte Frage:> Ist es möglich alle Ports in einen ARRAY oder TYP zu schreiben, so was> wie:> LEDS:= (LED1,LED2,LED3,LED4)
Ja. Sieh dir mal da die LEDs vom Lauflicht an:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
BTW1:
Man kann in VHDL mit Texteinrückungen der Beschreibung mehr Übersicht
verleihen.
BTW2:
Wozu unnötigerweise die vielen Variablen?
Siehe den Beitrag "Variable vs Signal"
BTW3:
Entweder die alten Synopsys Libs:
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
Oder die genormte Numeric_std:
use ieee.numeric_std.all;
Aber niemals beide zusammen!
Siehe auch den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
WOW!
Vielen dank für die ausführliche Antwort. Respekt für die Zeit und
Mühe:)
Ich werde mich weiterbilden, und höchstwahrscheinlich hier im forum bald
wiedermelden.
Bis dann.