Hallo Leute!
Ich bin noch recht neu in VHDL und probiere mich gerade an ein paar
Aufgaben und wollte euch diesbezüglich etwas fragen.
Zunächst einmal die Aufgabenstellung:
Insgesamt geht es darum, eine Figur zu bauen. Diese hat einen
Bewegungsmelder, eine Lampe für Augen und einen Lautsprecher, der Laute
abgeben kann. Weiterhin hat diese Figur einen Taktgeber, d. h. es gilt
1
entityfiguris
2
port(clock:inSTD_LOGIC;-- the clock has every second a rising edge
3
melder:inSTD_LOGIC;-- motion sensor
4
lichter:outSTD_LOGIC;-- the lamps for the eyes
5
lautsprecher:outSTD_LOGIC-- the speaker for chain rattling
6
);
7
endfigur;
Wenn eine steigende Flanke kommt, werden Eingaben überprüft. Die Figur
soll sich aktivieren, wenn der Bewegungsmelder ein Signal bekommt, wobei
der Lautsprecher dann ebenfalls sofort starten soll. 5 Sekunden später
wiederum sollen die Augen dann beginnen, zu leuchten. Wenn der Melder
kein Signal mehr meldet, so soll zuerst das Leuchten und die Laute des
Sprechers noch 20 Sekunden fortgesetzt werden, anschließend wird der
Lautsprecher ausgeschaltet und 15 Sekunden später wird dann das Leuchten
der Augen ausgeschaltet.
Aktuell habe ich gemäß der Beschreibung nach eigener Interpretation es
folgendermaßen implementiert:
1
architectureBehavioraloffiguris
2
begin
3
activate:process(clock)
4
variablecounter:integerrange0to40:=0;
5
begin
6
ifrising_edge(clock)then
7
if(melder=1)then
8
lautsprecher<='1';
9
if(counter=5)then
10
lichter<='1';
11
endif;
12
else
13
if(counter=25)then
14
lautsprecher<='0';
15
endif;
16
if(counter=40)then
17
lichter<='0';
18
endif;
19
endif;
20
endif;
21
counter:=counter+1;
22
endprocess;
23
endBehavioral;
Meine Idee hierbei war, einen counter als Variable zu benutzen (für die
Sekunden). Mich würde nun einmal interessieren, ob der Ansatz so richtig
ist bzw. was man genau wo verbessern kann.
zakar95 schrieb:> entity figur is> port (clock : in STD_LOGIC; -- the clock has every second a rising edge
Das ist aber kein Design fürs echte Leben, oder? Denn dort hat ein FPGA
einen Takt im Bereich ab 50MHz aufwärts...
> Die Figur soll sich aktivieren, wenn der Bewegungsmelder ein Signal> bekommt, wobei der Lautsprecher dann ebenfalls sofort starten soll.
Und wenn sich der Bewegungsmelder für 0,9 Sekunden genau zwischen zwei
Taktimpulsen regt?
> Meine Idee hierbei war, einen counter als Variable zu benutzen
Warum unnötigerweise eine Variable?
Siehe den Beitrag "Variable vs Signal"> Wenn der Melder kein Signal mehr meldet, so soll zuerst das Leuchten und> die Laute des Sprechers noch 20 Sekunden fortgesetzt werden
Solltest du dann bei aktivem Melder nicht irgendwie den Counter
zurücksetzen?
Mein Tipp: simuliere dein Design einfach mal. Dort kannst du dann ganz
einfach kontrollieren ob es funktioniert und wenn nicht, was wo schief
läuft.
> was man genau wo verbessern kann.
Du kannst den Quelltext hier wie in der Bedieungsanleitung nach "Antwort
schreiben - Wichtige Regeln- erst lesen, dann posten!" beschrieben mit
den [vhdl]-Tags umrahmen...
ElKo schrieb:> Kurze Zwischenfrage: Wenn der Counter überläuft, geht es bei VHDL> automatisch bei 0 (bzw. beim Minimum) wieder los?
Nein.
1. Der Simulator gibt einem Fehler aus.
2. Die reale Hardware zählt bis 63 und läuft dann über auf 0.
Gustl B. schrieb:> Bei Integer zählt der Zähler in der Simulation einfach endlos weiter> nach oben.
Aber eben nicht bei einem eingeschränkten Integer wie hier. Da hält
der Simulator mit einem Fehler bei 41 an. Und genau deshalb sollte man
auch solche Bereiche (0 to 40) angeben, denn nur der Designer weiß, dass
für diesen Zähler eine Wert von 1234567 unsinnig ist.
Im realen FPGA brauchen 0..40 letztlich einen 6 Bit breiten Zähler. Und
weil kein Überlauf abgehandelt wird, zählt der Zähler auf diesen 6 Bits
laufend weiter. Und da kommt nach 63 dann eben die 0.
zakar95 schrieb:> Die Figur soll sich aktivieren...
Was soll denn passieren, wenn der Melder nach dem Abschalten schon nach
15 Sekunden wieder aktiviert wird? Oder nach 25?
Du musst übrigens bedenken, dass der Melder auch mal 60 Sekunden belegt
sein kann. Was soll dann passieren? Laut deiner Beschreibung muss
solange dann sowohl die Leuchte wie auch der Lautsprecher aktiviert
sein.
Ich würde hier jetzt erst mal die zusammengemantschte Aufgabe in 2
Teilaufgaben trennen: das Leuchten und den Lautsprecher.
1. Lautsprecher
Für den Lautsprecher wird es ganz einfach: der bekommt einen eigenen
Timer, der bei aktivem Melder laufend auf 20 gesetzt und bei inaktivem
Melder heruntergezählt wird. Solange der Timer ungleich 0 ist wird der
Lautsprecher aktiviert.
2. Leuchten
Diese Aufgabe packst du am einfachsten in einen Zustandsautomaten. In
dessen Ruhezustand wird der Leuchtenzähler auf 0 gesetzt und gewartet,
bis der Melder aktiviert wird. Im nächsten Zustand wird der Zähler
hochgezählt und bei Erreichen des Verzögerungswertes die LEDs
eingeschaltet. Dann wird im nächsten Zustand gewartet, bis das
Meldersignal wieder inaktiv wird und die Leuchte verzögert abgeschaltet.
Lothar M. schrieb:> Aber eben nicht bei einem eingeschränkten Integer wie hier. Da hält> der Simulator mit einem Fehler bei 41 an. Und genau deshalb sollte man> auch solche Bereiche (0 to 40) angeben, denn nur der Designer weiß, dass> für diesen Zähler eine Wert von 1234567 unsinnig ist.
Nein. Gerade getestet mit VIVADO und dem dortigen Simulator.
Mag sein, dass der nichts taugt, ist aber einfach zu bedienen und gerade
Anfänger die sich das VIVADO runterladen werden den verwenden, für die
ist es nicht offensichtlich, dass das nichts taugt. So wie ich ja auch.
Bei Integer finde ich das Verhalten sogar noch logisch, wieso sollte das
irgendwann wieder bei 0 anfangen? Das ist ja nicht auf eine bestimmte
Anzahl an Bits beschränkt. Wünschenswert wäre eine Warnung wenn ein
beschränkter Integer über die Schranke läuft, aber ... wenn es diese
Warnung gäbe, dann auch nur in der Simulation. In Hardware fängt der
Zähler an wenn alle Bits 1 sind aber nicht wenn eine Schranke
Beschränkung überschritten wird.
Wenn, dann will ich also, dass die Simulation genauso wie die Hardware
funktioniert, also der die das Integer erst dann überläuft wenn alle
Bits gesetzt sind. Und dafür gibt es die Post-Syntheses Functional
Simulation, die nutze ich dann auch relativ häufig wobei auch die
normale Simulation OK ist wenn man weiß was sie macht.
Gustl B. schrieb:> Mag sein, dass der nichts taugt, ist aber einfach zu bedienen und> gerade> Anfänger die sich das VIVADO runterladen werden den verwenden, für die> ist es nicht offensichtlich, dass das nichts taugt.
Ja, leider. Schade das der Vivadosimulator sich nicht an den
VHDL-Standard hält.
> Bei Integer finde ich das Verhalten sogar noch logisch, wieso sollte das> irgendwann wieder bei 0 anfangen?
Es sollte wieder bei -2^31 anfangen. Das sieht zumindest der Standard
vor.
> Wünschenswert wäre eine Warnung wenn ein> beschränkter Integer über die Schranke läuft, aber ... wenn es diese> Warnung gäbe, dann auch nur in der Simulation. In Hardware fängt der> Zähler an wenn alle Bits 1 sind aber nicht wenn eine Schranke> Beschränkung überschritten wird.
Richtig.
> Wenn, dann will ich also, dass die Simulation genauso wie die Hardware> funktioniert, also der die das Integer erst dann überläuft wenn alle> Bits gesetzt sind. Und dafür gibt es die Post-Syntheses Functional> Simulation, die nutze ich dann auch relativ häufig wobei
Ich nicht. Ich erwarte vom Simulator eine korrekte Funktionsweise.
Wenn ich Überläufe zulassen will, dann nehme ich entweder
signed/unsigned oder Modulo bei Integer.
Dann läuft die Verhaltenssimulation identisch zur Hardware. Ohne
Fehlermeldung und ohne die unnötige Post-Synthesis-Simulation.
Duke
Ich hätte lieber, dass das Synthesetool auch beschränkte Integer richtig
in Hardware umwandelt. Wieso sollte man sonst überhaupt Integers
beschränken? Weil das eben keinen Sinn ergibt und ungenutzte Bits
sowieso wegoptimiert werden könnte man die Beschränkung ganz weglassen.
Ich beschränke schon, aber nur auf 2^n-1.
Aber wo wir schon dabei sind:
Wenn ich jetzt einen ungerade beschränkten Integer für die Zustände
einer FSM verwende, also integer range 0 to 5.
Und dann verwende ich in der FSM auch alle 6 Zustände 0 bis 5, denke mir
jawohl, es gibt jetzt keine Zustände die nicht abgedeckt sind und liege
falsch, es werden nämlich 3 Bits für die Zustände verwendet, 8 Zustände
und nur 6 sind abgedeckt. Klar mit when others wird das gelöst, aber was
hat dann die Beschränkung gebracht?
Gustl B. schrieb:> Und dann verwende ich in der FSM auch alle 6 Zustände 0 bis 5, denke mir> jawohl, es gibt jetzt keine Zustände die nicht abgedeckt sind und liege> falsch, es werden nämlich 3 Bits für die Zustände verwendet, 8 Zustände> und nur 6 sind abgedeckt
Jupp und wenn der Synthesizer der Meinung ist auf one-hot zu kodieren
hast Du 6 Bits und 58 ungültige Zustände. Da hilft auch when others
nicht.
Meine Zustände haben übrigens Namen:
Duke Scarring schrieb:> -gb- schrieb:>> VIVADO und dem dortigen Simulator> Der taugt offensichtlich nix.
Die Defaultwerte sind da ganz offensichtlich völlig untauglich
eingestellt.
Das hatten wir schon mal im
Beitrag "Re: VGA Versuch - Problem beim Simulieren"
Ich habe das allerdings nicht weiter untersucht...
Gustl B. schrieb:> Wieso sollte man sonst überhaupt Integers beschränken?
Weil nur du als Entwickler wei0t, dass ein VGA-Zähler nur auf 639 oder
479 laufen muss. Sobald er größere Werte erreicht, ist das ein Fehler,
denn das war nicht so geplant.
> Weil das eben> keinen Sinn ergibt und ungenutzte Bits sowieso wegoptimiert werden
Aber erst weit hinten in der Toolchain mit vielen Meldungen zu "unused
signals". Wenn man den range mit angibt, dann kann schon der Synthesizer
die unnötigen Leitungen weglassen. Siehe
Beitrag "Re: VGA Versuch - Problem beim Simulieren"
Lothar M. schrieb:> Weil nur du als Entwickler wei0t, dass ein VGA-Zähler nur auf 639 oder> 479 laufen muss.
Ja, aber der Entwickler muss den Zähler dann auch im Code zurücksetzen.
Da mir das VIVADO da sowieso keinen Fehler ausspuckt habe ich sowas
immer händisch in der Testbench abgeprüft oder eben auf die Signale
geachtet und mal hingeguckt ob da Fehler passieren.
Also ja, wenn der Simulator da einen Fehler meldet sollte man das machen
weil es aus Debugginggründen sinnvoll ist, das verstehe ich.