Ich habe die Aufgabe gekriegt (im Studium) ein Lauflicht mit VHDL
umzusetzen, um 8 LED's nach einem bestimmten Muster laufen zu lassen.
Dabei sollen die Lauflichter nach folgender Reihenfolge aufleuchten:
von links nach rechts: 1->3->5->7 und dann von rechts nach links:
8->6->4->2
und dann wieder von vorn.
Ich verwende hierfür CPLD XC9572XL und Modelsim als Simulator.
Mir hat als ersten Ansatz diese Seite:
http://chip.uni-rostock.de/designs/lauflicht.html gut gefallen. Jedoch
will ich kein Makro verwenden und daher soll alles in eine Datei und
auch das ersetzen der Nullen und Einsen durch Rauten und Leerzeichen
gefällt mir nicht.
Da ich mit VHDL noch nie gearbeitet habe, wollte ich euch um Hilfe
bitten.
Vielleicht gibt es auch andere Möglichkeiten.
Och, immer so verschwenderisch.
Ich bevorzuge hier(cpld) die minimalistische Variante. 8 leds macht 8
mögliche Positionen, also brauchen wir auch nur 3 bit.
> Och, immer so verschwenderisch.
Das sieht nur so aus: meine Lösung braucht nur 3 FFs ;-)
Die Synthese macht das schon richtig, und der Fitter optimiert sich das
zurecht. Von Vorteil ist, dass das Muster ohne Probleme erkannt und
geändert werden kann.
Und wenns zum Schluss (noch) nicht hineinpasst, dann kann/muss man ja
nochmal Hand anlegen...
Nur 3 FF ?
Ich hätte auf den ersten Blick jetzt vermutet das es gar 64 benötigt,
wenigstens aber 8.
Manchmal unterschätzt man die Tools wirklich. In dem Fall ist die Lösung
natürlich sinnvoller.
Das versteh ich nun garnicht...sicher das dies bei "optimized density"
raus kommt ?
Denn es sind nur 10 Produkterme, also müsste es doch selbst im
Extremfall höchstens auf 10 Makrozellen kommen ?
9 sinds ja eh mindestens wegen den 9 nötigen Pins.
Aber gut, das ist nun wirklich nebensächlich, ob 2 Makrozellen mehr oder
weniger, wegen der Übersichtlichkeit sollte er wohl trotzdem eher die
Array Methode nutzen.
Ich entwerf für solche Dinge wo sich das anbietet einfach die Funktion
gerne selbst, das gibt einem irgentwie das Gefühl der Kontrolle, die man
trotzdem oft nicht hat :)
> sicher das dies bei "optimized density" raus kommt ?
Jawoll.
> Ich entwerf für solche Dinge wo sich das anbietet einfach die Funktion> gerne selbst, das gibt einem irgentwie das Gefühl der Kontrolle...
Ich bin eher aus der FPGA-Ecke, dort kann ich mir manuelles Tuning nur
in Spezialfällen leisten... ;-)
>>> Nur 3 FF ?>>> Ich hätte auf den ersten Blick jetzt vermutet das es gar 64 benötigt,> ...Gefühl der Kontrolle, die man trotzdem oft nicht hat :)
ACK
> Wie kann ich den Takt von 1MHz runtertakten auf 1 Sekunde, damit man das> Signal auch sieht?
Du programmierst einen Taktteiler, der dir im Takt von 1 Sekunde ein
Clock-Enable generiert: Taktung FPGA/CPLD
Mit diesem Clock-Enable wird dann der Takt für dein Lauflicht
freigegeben.
Allerdings brauchst du in einem CPLD einiges an wertvollen Makrozellen:
für einen Teiler durch 1 Mio sind 20 FFs nötig :-o
Tetramam schrieb:
> Wie kann ich den Takt von 1MHz runtertakten auf 1 Sekunde, damit man das> Signal auch sieht?
In der Testbench oder im realen Leben?
In der Testbench musst du ja nur die passenden wait-Anweisungen
spendieren im Takt-Prozess.
Im realen Leben musst du noch ein paar Flipflops spendieren und
einen Zähler aufbauen.
Edith: Lothar war schneller...
> constant cnt_div: integer:=20;
Der zählt jetzt von 0 bis 19. Reicht dir das?
Du wollstest doch 1000000 :-o
> signal cnt : integer range 0 to 7 := 0;> :> signal cnt: integer range 0 to cnt_div-1; -- Zähler für Teiler
Du kannst nicht einfach den Namen cnt zweimal verwenden (einmal für
den Enable und einmal für den Index).
Und wenn du dann einen geteilten Takt hast, dann solltest du den auch
weiterverwenden:
1
processbegin
2
waituntilrising_edge(clk);
3
if(ce='1')then--------------- hier z.B.
4
if(cnt<7)then
5
cnt<=cnt+1;
6
else
7
cnt<=0;
8
endif;
9
endif;
10
endprocess;
BTW
Hin- und herkopieren reicht nicht aus:
ein wenig solltest du schon mitdenken :-/
Es waren noch viele Fehler drin daher habe ich den Quellcode noch einmal
umgeschrieben. Es erscheint nur noch eine Fehlermeldung:
** Warning: [2] LauflichtTest.vhd(79): (vcom-1090) Possible infinite
loop: Process contains no WAIT statement.
--> kann ich diese Fehlermeldung ignorieren?
Jetzt sieht der Quellcode folgendermaßen aus:
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
ENTITYLauflichtis
6
Port(clk:inSTD_LOGIC;
7
leds:outSTD_LOGIC_VECTOR(7downto0));
8
9
ARCHITECTUREBehavioralOFLauflichtIS
10
typeRomisarray(0to7)
11
ofstd_logic_vector(7downto0);
12
13
constantledarray:Rom:=
14
("10000000",
15
"00100000",
16
"00001000",
17
"00000010",
18
"10000001",
19
"00000100",
20
"00010000",
21
"01000000");
22
signalcntled:integerrange0to7:=0;
23
constantcnt_div:integer:=21;
24
signalcnt:integerrange0tocnt_div-1;
25
signalce:std_logic;
26
27
BEGIN
28
29
30
PROCESS
31
BEGIN
32
IFclk='1'andclk'eventTHEN
33
IFce='1'THEN
34
waituntilclk='1'andclk'event;
35
IF(ce='1')THEN
36
IF(cntled<7)THEN
37
cntled<=cntled+1;
38
ELSE
39
cntled<=0;
40
ENDIF;
41
leds<=ledarray(cntled);
42
ENDIF;
43
ENDIF;
44
ENDIF;
45
ENDPROCESS;
46
47
48
PROCESS
49
BEGIN
50
IFclk='1'andclk'eventTHEN
51
IFcnt=cnt_div-1THEN
52
ce<='1';
53
cnt<=0;
54
ELSE
55
ce<='0';
56
cnt<=cnt+1;
57
ENDIF;
58
ENDIF;
59
ENDPROCESS;
60
ENDBehavioral;
Ist das so korrekt oder habe ich dort vielleicht noch etwas falsch
verstanden?