Zähler mit Selbst-Stop

Gast #865963
In Hardware ist das kein Problem: Ein Zähler soll z.B. bis zum Zustand 
22
zählen und dann selbst stoppen. Mit einem Reset soll er dann wieder auf 
Null gesetzt werden und erneut mit dem Takt bis 22 laufen und stoppen.

In der ISE kann ich das als Schematic zeichnen und es funktioniert auch.
Aber ich will es unbedingt in VHDL haben.

Die VHDL-Zählerimplementierungen habe ich mir angesehen und finde sie 
auch soweit einleuchtend. Muß ich da noch eine state-machine reinbauen?

Bitte nicht schlagen - ich weiß, es muß relativ trivial sein.
Gast #865970
Mit ner FSM gehts garantiert, aber ich glaube dass man das auch ohne 
hinkriegen kann.

so nach dem Schema (mein VHL ist eingerostet, nicht schlagen wenns nicht 
macht)

if clock'event and clock='1' then
   if cnt <= "22" then
      cnt <= cnt +1;
   elif
      cnt <= cnt;
   end if;
end if;
Gast #865971
Du musst nur den Zähler mit nem Wert vergleichen.
[vhdl]
process(Reset, Clk)
begin
 if reset = '1' then
   cnt <= (others => '0');
 elsif(rising_edge(Clk))then
   if cnt = vergleichsWert then
     cnt <= (others => '0');
   else
     cnt <= cnt + 1;
   end if;
 end if;
end process;
Gast #865991
Danke, ich glaube, jetzt habe ich es geschnallt!
Genial, erst vergleichen und dann zählen, ich hatte es immer umgekehrt 
versucht - aber so wird ein Schuh daraus!

Danke!
Gast #867211
Die Variante von Mathi dürfte nicht gehen, die setzt sich ja beim 
Erreichen des Soll-Wertes, wieder zurück.

Ansonsten denk nochmal drüber nach: Auch ein Zähler ist gewissermaßen 
nur eine State-Machine. Es findet bei jedem Takt ein Übergang in den 
nächsten Zustand statt und Zustände gibt es anhängig davon, wie weit 
gezählt werden muß.

Rick
Gast #867531
Hmm, ja...

Könnte man es vielleicht so machen:

process(Reset, Clk)
signal cnt : std_logic_vector (4 downto 0) := "00000";
begin
 if reset = '1' then
   cnt <= (others => '0');
 elsif(rising_edge(Clk))then
   if cnt = 22 then              -- Vergleichswert
     cnt <= "10110";             -- 22
   else
     cnt <= cnt + 1;
   end if;
 end if;
end process;                   -- ?

Danke für jeden sachdienlichen Hinweis!
Gast #867552
Ich lasse einen Zähler immer entweder inkremtieren oder nach Erreichen 
des Endwertes in FFFF springen. Bei REset dann auch null. Das ist das 
Durchsichtigste.
Gast #867574
Wenn der Wert kleiner 22 ist, wird inkrementiert, ansonsten nicht. Sowas 
kann zB so aussehen:

1
counter : process(Reset, Clk)
2
signal cnt : unsigned(4 downto 0) := (others => '0');
3
begin
4
 if reset = '1' then
5
   cnt <= (others => '0');
6
 elsif(rising_edge(Clk))then
7
   if cnt /= 22 then
8
     cnt <= cnt + 1;
9
   end if;
10
 end if;
11
end process counter;
Gast #872092
@TM
du schreibst:
:
Wenn der Wert kleiner 22 ist, wird inkrementiert, ansonsten nicht
:

und programmierst:
:
1
if cnt /= 22 then
:

richtig wäre aber doch:
:
1
if cnt < 22 then
:

Ja, jetzt kannst du mir Centfuchserei vorwerfen, aber in diesem 
Zusammenhang ist vielleicht auch interessant:
Abhängig von der Vergleich-Art werden unterschiedlich viel Ressourcen 
auf einem FPGA verbraucht. Hier ein kleines Beispiel mit Xilinx S3.

Aufgabe siehe oben (Zähler, der seinen Endwert hält)

counter ist ein 8-Bit Register
endwert ist ein 8-Bit Input

Vergleich auf KLEINER mit Konstante:
1
if counter < 22 then
       --> 6 Slices

Vergleich auf UNGLEICH mit Konstante:
1
if counter /= 22 then
       --> 7 Slices

Vergleich auf UNGLEICH mit Variable:
1
if counter /= endwert then
  --> 8 Slices

Vergleich auf KLEINER mit Variable:
1
if counter < endwert then
  --> 9 Slices


Es macht übrigens beim Ressourcenverbrauch keinen Unterschied, ob ich 
einen Abwärtszähler (also Start beim Zählwert und Ende bei 0) oder einen 
Aufwärtszähler (Start bei 0 und Ende beim Zählwert, s.o.) verwende.

Was mich jetzt bewegt ist die Frage: Wie sieht das bei Altera aus?
Gast #872325
Das /= mehr Ressourcen als < verbraucht, weiss ich. Wollte ja auch noch 
Platz für Optimierungen lassen ;-) Vielleicht wäre es sogar besser auf = 
22 zu prüfen.
Gast #880287
Vergleich auf KLEINER mit Konstante:

<if counter < 22 then
<
<       --> 6 Slices
<
<Vergleich auf UNGLEICH mit Konstante:
<
<if counter /= 22 then
<
<       --> 7 Slices

Glückstreffer? nach meinem Erfahrungen (S3E) ist = kleiner
, als > oder <. Vielleicht weil ich keinen asynchronen reset verwende. 
Ach und es geht  bei einem (nicht ladbaren) counter noch kleiner: Man 
braucht nur zu testen ob bit2 und bit4 '1' eins sind. Das passt dick in 
die 4er LUT's.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.