Ich hab mal ne Verständnisfrage zum Prozess in VHDL. Ich lieg doch
richtig, dass die Anweisung nach dem "rising_edge" erst ausgeführt wird,
NACHDEM dieses Ereignis auch eingetreten ist !?
D.h. alle bis zum letzten "end if" stehenden Anweisungen werden ERST
NACH eintreffen des Ereignisses, also im Prozess, ausgeführt !?
Nun meine Frage, an welcher Stelle lade ich den Zähler ? Das muss in
jedem Fall auch ohne das ein Ereignis eintrifft gehen. Ich denk ich
müsste das außerhalb des Prozesses tun, oder?
Ralph H. schrieb:> Ich lieg doch richtig, dass die Anweisung nach dem "rising_edge"> erst ausgeführt wird, NACHDEM dieses Ereignis auch eingetreten ist !?
Nicht nachdem, sondern WEGEN des Ereignisses wird der Prozess neu
berechnet (nicht "ausgeführt").
Ralph H. schrieb:> Nun meine Frage, an welcher Stelle lade ich den Zähler ? Das muss in> jedem Fall auch ohne das ein Ereignis eintrifft gehen.
Tja, weil du da jetzt ein Ereignis verwendest, das schon das
Zählereignis selber ist, kannst du den Zähler da natürlich nicht laden.
Pech...
Deshalb mußt du das hier asynchron machen:
ABER....
warum machst du solche Konstrukte? Wofür soll der Code sein?
Wieviele Takte hast du in deinem Design (ein Takt ist das bei
rising_edge() oder falling_edge() oder bei 'event)?
Sieh dir den Beitrag "vhdl-richtlinien f. synthese?" mal an.
> Ich denk ich müsste das außerhalb des Prozesses tun, oder?
Das geht nicht. Probiers aus.
Grund: dann hast du 2 Treiber auf ein Signal.
Zunächst mal Danke Euch ! Ich hab mir die Beiträge angesehen, aber um
ehrlich zu sein keine ANTWORT auf meine Frage erhalten dabei. Entweder
bin ich zu blöd die da rauszulesen (sicher :D) oder wer weiß was auch
immer..
Werd aber dennoch versuchen das irgendwie zu kapieren.
Lothar Miller schrieb:> ABER....> warum machst du solche Konstrukte? Wofür soll der Code sein?
Ein einfacher 4Bit-Zähler, der geladen wird, um ihn später auszulesen :)
Dann versuch ich mich mal.
1) rising_edge - kennzeichnet grundsätzlich einen Takt. Flankenwechsel
können damit nicht abgefragt werden.
2)
>Ich lieg doch>richtig, dass die Anweisung nach dem "rising_edge" erst ausgeführt wird,>NACHDEM dieses Ereignis auch eingetreten ist !?
Im Prinzip ja, allerdings ist die Zeitspanne theoretisch = 0
Zu beachten ist hier noch, das Signalzuweisungen nicht sofort sondern
erst am ende des Prozesses ausgeführt werden.
3)
>alle bis zum letzten "end if" stehenden Anweisungen werden ERST>NACH eintreffen des Ereignisses, also im Prozess, ausgeführt !?
Ja das ist richtig, allerdings gilt auch hier Zeitspanne theoretisch = 0
4) an welcher Stelle lade ich den Zähler ?
Lothar schrieb:
>Tja, weil du da jetzt ein Ereignis verwendest, das schon das>Zählereignis selber ist, kannst du den Zähler da natürlich nicht laden.
Wieso geht es deiner Meinung nach nicht Synchron ?
Das Laden des Zählers entspricht einem Reset, auch wenn ein anderer wert
als 0 geladen wird.
im allgemeinen schreibt man das so:
1
process(clock)begin
2
ifrising_edge(clock)then
3
-- den Zähler laden
4
ifreset=1then
5
zaehler<=0;
6
endif;
7
zaehler<=zaehler+1;
8
endif;
9
endprocess;
5)
Das muss in jedem Fall auch ohne das ein Ereignis eintrifft gehen.
Dein "Ereignis" ist der Systemtakt, ohne den Takt geht gar nichts
Das hier sollte helfen:
http://www.mikrocontroller.net/articles/VHDL_Flankenerkennung
6)
>Ich denk ich müsste das außerhalb des Prozesses tun, oder?
Nein, der Reset gehört zum Prozess
Silvia A. schrieb:> Ist schon spät
Na ist doch OK.. ich soll ja mein Köpppl anstrengen ;-)
Danke Euch erstmal... nur zu meinem Verständnis, der Zähler wird immer
auf 0 gestellt wenn Reset 1 ist, oder ?? Ich denke nicht !!
Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die
nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist, oder
irre ich mich ? D.h. wenn kein CLOCK mehr kommt, wird auch der Zähler
durch Reset 1 NICHT rückgesetzt ?!
Wenn kein Clock mehr kommt schauts eh düster aus in der Schaltung.
Und nein Silvia das ist nicht ok, da dein Zähler nie zurückgesetzt
werden wird sondern immer hochzählen wird
Silvia A. schrieb:> ich hoffe jetzt ist es richtig
Nein, so wirkt der Reset nicht.
Es zählt nämlich die letzte Zuweisung, und die ist immer
zaehler <= zaehler + 1;
unabhängig davon, ob der Reset-Pfad ausgeführt wurde oder nicht.
Ralph H. schrieb:> Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die> nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist
So ist es.
> D.h. wenn kein CLOCK mehr kommt, wird auch der Zähler> durch Reset 1 NICHT rückgesetzt ?!
Auch richtig.
ABER.... (Obacht, jetzt kommts)
...in einem idealen (und auf jeden Fall in einem Anfänger-)Design gibt
es genau 1 Takt. Der kommt von einem Taktgenerator, der aussen an das
FPGA angeschlossen ist. Und der Takt kommt garantiert 1 mal, solange
dieses Signal Reset aktiv ist! Denn dieser Reset selber ist ja auch ein
Signal, das synchron (das ist das Schlüselwort) zum Takt gesetzt und
zurückgesetzt wird. Und daher muß der Reset mindestens für 1 Taktzyklus
lang aktiv sein.
>Aus meiner Sicht wird der Zähler doch erst rückgesetzt werden, wenn die>nächste steigende Flanke von clock kommt UND Reset dann noch 1 ist
Genau,
ach jetzt versteh ich erst warum Lothar das asynchron lösen wollte, denn
du schriebst ja:
> Das muss in jedem Fall auch ohne das ein Ereignis eintrifft gehen
na der reset ist ja schnell asynchron gemacht:
1
process(clock,reset)begin
2
-- den Zähler laden
3
ifreset='1'then
4
zaehler<=(others=>'0');
5
endif;
6
-- den Zähler erhöhen
7
ifrising_edge(clock)then
8
zaehler<=zaehler+1;
9
endif;
10
endprocess;
allerdings solltest du nach Möglichkeit bei der synchronen Methode
bleiben
Silvia A. schrieb:> warum Lothar das asynchron lösen wollte
Ich wollte das nicht! Ralph wollte das! ;-)
Für mich gelten erst mal meine Postulate (wobei ich mich mit der
Begründung von Ausnahmen etwas leichter tue...;-)
Wenn sich Signale nur wegen einer Taktflanke des selben Takts ändern
können, dann nennt man das ein synchrones (=zeitgleiches) Design. Und
nur so funktionieren FPGA Designs zuverlässig. Allerdings kämpft Ralph
mit CPLDs rum, da fallen mir gleich ein paar Ausreden ein, warum man
"lokale" Takte nehmen könnte.....
BTW:
So ein Bauteil gibt es (eigentlich) nicht:
1
process(clock,reset)begin
2
-- den Zähler laden
3
ifreset='1'then
4
zaehler<=(others=>'0');
5
endif;
6
-- den Zähler erhöhen
7
ifrising_edge(clock)then
8
zaehler<=zaehler+1;
9
endif;
10
endprocess;
Wenn hier der Reset aktiv ist, und keine Flanke kommt, dann wird der
Zähler zurückgesetzt (klar soweit). Wenn jetzt aber eine Flanke kommt,
dann hat die Vorrang vor dem Reset (weil die if rising_edge() Abfrage im
Prozess nach der Reset-Abfrage kommt) und der Zähler müsste um 1
hochzählen, um sofort danach wieder zurückgesetzt zu werden...
Silvia A. schrieb:> process (clock,reset) begin> -- den Zähler laden> if reset = '1' then> zaehler <= (others => '0');> end if;> -- den Zähler erhöhen> if rising_edge (clock) then> zaehler <= zaehler + 1;> end if;> end process;
Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal
schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist
falsch, es sollte mit asynchronem Reset folgendermaßen lauten
>Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal>schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist>falsch, es sollte mit asynchronem Reset folgendermaßen lauten
Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken
gar nix
Silvia A. schrieb:> Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken> gar nix
Hey nicht zanken !! und daran denken, ich will den Zähler mit nem
anderen Wert als 0 laden !! da geht := others nicht !
Wenn ich so seh was ihr scheit, bin ich froh gefragt zu haben, denn es
scheint ja doch nicht leicht zu sein.
Silvia A. schrieb:>>Ich will ja nix sagen, aber IMHO solltest du vielleicht auch erstmal>>schauen, was und wie ein Prozess funktioniert. Auch diese Lösung ist>>falsch, es sollte mit asynchronem Reset folgendermaßen lauten>> Da widerspreche ich dir jetzt einfach mal, denn deine Klammern bewirken> gar nix
Es geht nicht um die Klammern.
1
process(clock,reset)begin
2
-- den Zähler laden
3
ifreset='1'then
4
zaehler<=(others=>'0');
5
endif;
6
-- den Zähler erhöhen
7
ifrising_edge(clock)then
8
zaehler<=zaehler+1;
9
endif;
10
endprocess;
Diese Beschreibung entspricht nicht den üblicherweise vorhanden FFs, bei
denen der Reset Vorrang hat und bei dem der Reset wirkt unabhängig davon
on der Takt kommt.
Bei deiner Beschreibung oben wird der Zähler erhöht, auch wenn der Reset
aktiv ist.
Silvia A. schrieb:> denn deine Klammern bewirken gar nix
Aber das fehlende erste end if und das stattdessen verwendete elsif
alles... :-o
Dadurch erhält der (asynchrone) Reset genau die Priorität, die er im FF
tatsächlich auch hat.
>So ein Bauteil gibt es (eigentlich) nicht>Wenn hier der Reset aktiv ist, und keine Flanke kommt, dann wird der>Zähler zurückgesetzt (klar soweit). Wenn jetzt aber eine Flanke kommt,>dann hat die Vorrang vor dem Reset (weil die if rising_edge() Abfrage im>Prozess nach der Reset-Abfrage kommt) und der Zähler müsste um 1>hochzählen, um sofort danach wieder zurückgesetzt zu werden...
Komisch, Xilinx beschreibt einen Zähler mit asynchronen Reset genauso.
(Mal abgesehen vom Clock enable und der anderen schreibweise für
"rising_edge")
1
-- Usage of Asynchronous resets may negatively impact FPGA resources
2
-- and timing. In general faster and smaller FPGA designs will
3
-- result from not using Asynchronous Resets. Please refer to
4
-- the Synthesis and Simulation Design Guide for more information.
>Aber das fehlende erste end if und das stattdessen verwendete elsif>alles... :-o>Dadurch erhält der (asynchrone) Reset genau die Priorität, die er im FF>tatsächlich auch hat.
Habt ihr denn meinen Post von 22:06 nicht gesehen ? Da hatte ich meinen
Fehler schon korrigiert
>Hey nicht zanken !! und daran denken, ich will den Zähler mit nem>anderen Wert als 0 laden !! da geht := others nicht !
Tja jetzt kommt zum vorschein, das std_logic nicht zum rechnen gedacht
ist, denn eine zuweisung wie zaehler <= 23 funktioniert nicht.
>Wenn ich so seh was ihr scheit, bin ich froh gefragt zu haben, denn es>scheint ja doch nicht leicht zu sein.
Lach , ne vhdl ist nicht einfach
VHDL ist keine Sprache wie C, in der man die Konstrukte nach Belieben
optimieren oder umändern sollte. Man soll sich bei HDLs am besten strikt
an die Templates halten, denn letztendlich sollen diese Templates
richtig von der Software erkannt werden und in HW umgesetzt werden.
Ralph H. schrieb:> Ein einfacher 4Bit-Zähler, der geladen wird, um ihn später auszulesen :)
Man starte ISE Project Navigator und clicke auf die gelbe Glühlampe in
der Toolbar.
Dann VHDL -> Synthesis Constructs -> Coding Examples -> Counters -> /w
Load, CE and Synch Active High Reset wählen, weil der die meisten
Features hat und weil synchrones Design (zumindest bei FPGAs immer
vorzuziehen ist) und schon hat man den richtigen Template-Code:
1
process(<clock>)
2
begin
3
if<clock>='1'and<clock>'eventthen
4
if<reset>='1'then
5
<count><=(others=>'0');
6
elsif<clock_enable>='1'then
7
if<load_enable>='1'then
8
<count><=<input>;
9
else
10
<count><=<count>+1;
11
endif;
12
endif;
13
endif;
14
endprocess;
Falls man möchte, kann man den jetzt etwas vereinfachen, falls man etwas
nicht braucht. Oder man schaut sich mal die anderen Counter-Templates
an.