Forum: FPGA, VHDL & Co. VHDL, FPGA timer aus zwei unterschiedlichen Prozessen zurücksetzen


von zimmerpflanze (Gast)


Lesenswert?

Hallo zusammen,

da ich vor ein paar Tagen schon mal eine Frage gestellt habe und sofort 
hilfreiche Antworten bekommen habe, wende ich mich nochmal an euch :)

Ich habe in meinem VHDL Code einen Timer gebaut, der einfach bei jeder 
steigenden Taktflanke 1 hochzählt. Die Clock dafür läuft mit 50 Mhz und 
der timer counter zählt von 0 bis 50000, also bis hoch auf 1000us.

Hier der VHDL Code dafür:
1
entity timer_counter is 
2
3
  port (
4
    i_clock   : in std_logic;
5
    i_reset   : in std_logic;
6
    o_counter   : out integer
7
    );
8
9
end entity timer_counter;
10
11
architecture behaviour of timer_counter is
12
13
signal r_counter : integer range 0 to 50000 := 0;
14
15
begin
16
  process(i_clock)
17
  
18
  begin
19
    if rising_edge(i_clock) then
20
      if i_reset = '1' then
21
        r_counter <= 0;
22
      else 
23
        r_counter <= r_counter + 1;
24
      end if;
25
    end if;
26
  end process;
27
  
28
  o_counter <= r_counter;
29
  
30
end behaviour;

Ich würde diesen Timer gerne in einem anderen Modul verwenden, und habe 
ihn daher mit Hilfe der .work lib in einem anderen .vhd file angelegt:
1
  
2
bus_timer : entity work.timer_counter
3
    port map (
4
      i_clock =>     i_main_clk,
5
      i_reset =>     r_timer_reset,
6
      o_counter =>   r_timer_counter
7
      );

Wie ihr sehen könnt, soll der timer von dort mit Hilfe des Signals 
r_timer_reset zurückgesetzt werde.

Ich würde diesen Timer gerne aus zwei, parallel laufenden Prozessen 
resetten können, da in meiner Anwendung nur immer einer der beiden 
Prozesse "aktiv" sein wird während der andere unbeteiligt im Idle state 
sein wird.

Dafür habe ich mir überlegt zwei Hilfssignale einzuführen und diese 
beiden zu ver-odern.
1
r_timer_reset <= r_timer_reset0 or r_timer_reset1;

r_timer_reset0 wird in Prozess 1 gesetzt.
r_timer_reset1 wird in Prozess 2 gesetzt.

Beide Prozesse werden von dem selben Takt auf die steigende Flanke 
ausgeführt.

Mein Problem:
Wenn ich den timer direkt über r_timer_reset zurücksetzte funktioniert 
es wie es soll, der timer funktioniert also.
Ich ahbe auch schon versucht nur das eine reset Signal zu vernwenden, 
also so:
1
r_timer_reset <= r_timer_reset0;
Auch das hat leider nicht funktioniert.
Die Methode mit den beiden ver-oderten Signalen funktioniert leider 
icht.
Bin ich damit auf dem Holzweg? Bin für jede Hilfe dankbar. Gruß

von Duke Scarring (Gast)


Lesenswert?

Prinzipiell sollte das schon gehen. Ich würde den veroderten Reset als 
asynchrones Signal betrachten und so behandeln:
http://www.lothar-miller.de/s9y/archives/41-Einsynchronisieren-von-asynchronen-Signalen.html

Duke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

zimmerpflanze schrieb:
> Die Methode mit den beiden ver-oderten Signalen funktioniert leider icht.
Was funktioniert da nicht? Wie stellst du das fest? Was sagt der 
Simulator? Ist dieses Reset-Signal synchron zum Sytemtakt i_clock? Wie 
viele solcher Systemtakte hast du?

> r_timer_reset0 wird in Prozess 1 gesetzt.
> r_timer_reset1 wird in Prozess 2 gesetzt.
>
> Beide Prozesse werden von dem selben Takt auf die steigende Flanke
> ausgeführt.
Du hast noch die grundlegend falsche Denkweise. Da wird auf dem FPGA 
nichts irgendwie "ausgeführt". Sondern da sind Flipflops, die einen 
Takteingang haben und wegen einer Taktflanke des i_clock entweder den 
Wert am Eingang übernehmen oder zurückgesetzt werden.

> Ich würde diesen Timer gerne aus zwei, parallel laufenden Prozessen
> resetten können, da in meiner Anwendung nur immer einer der beiden
> Prozesse "aktiv" sein wird während der andere unbeteiligt im Idle state
> sein wird.
Hier hört sich irgendwas arg holprig bzw. umständlich an.

zimmerpflanze schrieb:
> Die Clock dafür läuft mit 50 Mhz und der timer counter zählt von 0 bis
> 50000, also bis hoch auf 1000us.
Der klassische Off-by-one Fehler...

> und der timer counter zählt von 0 bis 50000, also bis hoch auf 1000us.
Dieser Timer, den du da hast, der zählt auf deiner Hardware dann munter 
weiter bis 65535 und fängt dann wieder bei 0 an. Im Simulator bekommst 
du eine Fehlermeldung bezüglich eines Werteüberlaufs aufs Auge.

von zimmerpflanze (Gast)


Lesenswert?

Duke Scarring schrieb:
> Ich würde den veroderten Reset als
> asynchrones Signal betrachten und so behandeln:

Danke, genau so hats funktioniert.

Lothar M. schrieb:
> Du hast noch die grundlegend falsche Denkweise. Da wird auf dem FPGA
> nichts irgendwie "ausgeführt". Sondern da sind Flipflops, die einen
> Takteingang haben und wegen einer Taktflanke des i_clock entweder den
> Wert am Eingang übernehmen oder zurückgesetzt werden.

Danke für deine Hinweise. Ja ich steh noch ganz am Anfang damit, das 
merkt man wohl direkt. Ich hoffe das wird mit der Übung besser. Ich 
werde trotzdem versuchen besser zu formulieren.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

zimmerpflanze schrieb:
> Duke Scarring schrieb:
>> Ich würde den veroderten Reset als
>> asynchrones Signal betrachten und so behandeln:
> Danke, genau so hats funktioniert.
Und das musst solltest du jetzt noch hinterfragen...
Dafür sind die Antworten auf die Fragen, die ich gestellt habe, 
relevant.

Denn: warum musst du für dieses Signal einsynchronisieren, wenn es doch 
(hoffentlich) aus einer zu i_clock taktsynchronen Komponente kommt? Denn 
dann  sollte das eigentlich nicht nötig sein.

von zimmerpflanze (Gast)


Lesenswert?

Lothar M. schrieb:
> Denn: warum musst du für dieses Signal einsynchronisieren, wenn es doch
> (hoffentlich) aus einer zu i_clock taktsynchronen Komponente kommt? Denn
> dann  sollte das eigentlich nicht nötig sein.

Du hattest recht, es war wirklich nicht nötig. Ich hatte noch einen ganz 
anderen Fehler, hab beide Dinge geändert obwohl das ein-synchronisieren 
gar nicht nötig war.

Mein Eigentlicher Fehler:

Der Timer Counter wird bei r_timer_reset = '1' zurückgesetzt bzw. 
"angehalten". Um ein gemeinsames reset Signal aus den beiden Signalen 
r_timer_reset0 und r_timer_reset1 zu erzeugen, muss ich also beide 
Signale verunden und nicht verodern..

Die Reset Signale sind default auf '1' gesetzt und werden auf '0' 
gesetzt um den counter loslaufen zu lassen.

Ich glaube du merkst ich stehe wirklich noch ganz am Anfang..

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

zimmerpflanze schrieb:
> Der Timer Counter wird bei r_timer_reset = '1' zurückgesetzt
Nein, dieser Zähler oben wird bei i_reset = '1' zurückgesetzt. Der 
Zählerreset ist also high-aktiv. Du willst diesen high-aktiven i_reset 
durch low-aktive Signale r_timer_reset0 und r_timer_reset1 ansteuern und 
musst aus diesem Grund deren Pegel erst anpassen.
Du solltest da bei solchen Signalen unbedingt eine gewisse 
Geradlinigkeit einhalten: entweder sind alle Reset low- oder high-aktiv.

> Um ein gemeinsames reset Signal aus den beiden Signalen r_timer_reset0
> und r_timer_reset1 zu erzeugen, muss ich also beide Signale verunden und
> nicht verodern..
Du kannst die beiden auch negieren (dann sind sie high-aktiv) und dann 
wie ursprünglich geplant verODERn:
i_reset  =  NICHT r_timer_reset0   ODER   NICHT r_timer_reset1

Aber du hast durch die Anwendung der De Morganschen Gesetze und die 
implizite funktionelle Invertierung des Signals in simples UND 
umgewandelt:
i_reset  =  r_timer_reset0   UND   NICHT r_timer_reset1


Schwer zu verstehen?
Durchaus.
Das ist der Grund, warum alle Resetsignale die gleiche "Polarität" haben 
sollten...  ;-)

> Die Reset Signale sind default auf '1' gesetzt und werden auf '0'
> gesetzt um den counter loslaufen zu lassen.
Low-aktive Signale bekommen bei mir immer den Anhang 'n', dann weiß 
jeder(!) sofort(!), dass etwas anders ist an dem Signal. Ein 'resetn' 
ist ganz was anderes als ein reset.

Und solche "systemrelevanten" Informationen sind allemal wichtiger als 
die unnötigen Präfixe...  ;-)

von Samuel C. (neoexacun)


Lesenswert?

Ich denke das Problem ist hier nicht die Polarität der Resets, sondern 
dass sie von beiden "parallel laufenden Prozessen" im Leerlauf gezogen 
werden.

Ist ein komisches Design, aber kein Polaritätsproblem. Die Resets werden 
hier überall high-active betrachtet.

von zimmerpflanze (Gast)


Lesenswert?

Lothar M. schrieb:
> Low-aktive Signale bekommen bei mir immer den Anhang 'n', dann weiß
> jeder(!) sofort(!), dass etwas anders ist an dem Signal. Ein 'resetn'
> ist ganz was anderes als ein reset.
>
> Und solche "systemrelevanten" Informationen sind allemal wichtiger als
> die unnötigen Präfixe...  ;-)

Samuel C. schrieb:
> Ich denke das Problem ist hier nicht die Polarität der Resets, sondern
> dass sie von beiden "parallel laufenden Prozessen" im Leerlauf gezogen
> werden.

Ich habe die Polarität der reset Signale jetzt angepasst und beide auf 
aactive low gestellt. Das mit dem 'n' Anhang habe ich auch gleich so 
übernommen.
Danke für all eure Antworten.

Lothar M. schrieb:
> Und solche "systemrelevanten" Informationen sind allemal wichtiger als
> die unnötigen Präfixe...  ;-)

Mir helfen diese Präfixe tatsächlich wirklich gut den Überblick zu 
behalten, aber ich verstehe wenn das andere Leute irritiert :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.