Forum: FPGA, VHDL & Co. Zähler bei Überlauf auf 0 setzen


von Chris R. (mrgreen)


Lesenswert?

Hallo,
ich benutze einen integer, um damit einen Zähler zu erzeugen.

Der soll auf 0 gesetzt werden, sobald er einen Wert x erreicht hat.

Wo genau setze ich den Zähler zurück?

Ich sehe mehrere Möglichkeiten, weiß aber nicht, welche schön und welche 
hässlich ist:

[pre]1) TimeIt: process(Reset, Clock, Timer)
  begin
    if (Reset ='1') then
      Timer <= 0;
    elsif(rising_edge(Clock))
      Timer <= Timer+1;
    end if;

    --Wenn 1s um, wieder ab 0 zählen
    if (Timer = DesignClock) then
      Timer <= 0;
    end if;
  end process;[pre]

2) In einem eigenen Prozess, der auf Timer wartet und ihn 0 setzt, wenn 
der Wert erreicht ist

3) als Conditional Signal Assignment direkt in der architecture.

von Johannes T. (johnsn)


Lesenswert?

In einem sequentiellen Process, niemals andere Signale als Reset & Clk 
in die Sensitivity List aufnehmen!!!
1
TimeIt: process(Reset, Clock)
2
  begin
3
    if (Reset ='1') then
4
      Timer <= 0;
5
    elsif(rising_edge(Clock))
6
      if (Timer = <Wert x>) then
7
        Timer <= 0;
8
      else
9
        Timer <= Timer+1;
10
      end if;
11
    end if;
12
  end process;

Für solche Anwendungen würd ich dir aber grundsätzlich den unsigned 
Datentyp aus numeric_std-Lib empfehlen.

von Chris R. (mrgreen)


Lesenswert?

Warum denn unsigned und nicht integer?

Edit:
und was ist mit solchen Prozessen?

TimeIt: process(Reset, Reset2, Clock)
  begin
   if(Reset ='1' or Reset2='1') then
      ...


Darf man sowas machen?

von Johannes T. (johnsn)


Lesenswert?

Wenn du integer nimmst ohne den Wertebereich einzuschränken, macht die 
Synthese daraus wahrscheinlich ein 32-Bit breites Register, was sehr 
schnell die Ressourcen aufbrauchen kann.

Bei unsigned kannst du im Prinzip genausorechnen, wie mit Integer, da 
die Rechenoperationen überladen sind. Unsigned ist eigentlich ein 
std_logic_vector, dass heißt du gibst die Bitbreite vor und die Synthese 
kann keinen größeren Vektor draus machen. Dann hast du noch den Vorteil, 
dass du die Bitbreite genauso groß wählen kannst, dass der Überlauf 
automatisch durch addieren von 1 passiert, du sparst also wieder Logik.

Der TimeIt-Prozess ist nicht gut. Es gibt eigentlich nur einen globalen, 
asynchronen Reset. Wenn du nur Teile der Logik resetieren - oder besser 
- initialisieren willst, dann machs mit einem synchronen Init-Signal:

Die Sensitivity-List sequentieller Prozesse hat nur einen global Reset 
und ein Taktsignale und sonst nichts.

von Chris R. (mrgreen)


Lesenswert?

Ich habe nun aber zwei Quellen, die für den Timer einen Reset erzeugen 
sollen.

VerODERe ich die dann außerhalb des Timers, und das daraus erzeugte 
ResetSignal in den Timer?

Macht das einen Unterschied, ob ich in der Timer-Architektur das ODER 
einbaue oder außerhalb?

von Johannes T. (johnsn)


Lesenswert?

Wenn die 2 Timer-Reset signale synchron zum Systemtakt sind, dann 
veroderst du die beiden in der If-Abfrage, wo ich Init stehen hatte. Die 
Synthese wird dann den Synchronen Clear-Eingang der FF-Zellen verwenden. 
Der Reset-Eingang sollte nur für den globalen FPGA-Reset verwendet 
werden.

Wenn die Timer-Reset Signale asynchron sind, dann musst du sie vorher 
mit 2 FFs einsychronisieren.

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.