Datum: 13.05.2008 15:28
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.
Datum: 13.05.2008 15:33
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;
Datum: 13.05.2008 15:33
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;
Datum: 13.05.2008 15:52
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!
Datum: 14.05.2008 20:56
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
Datum: 14.05.2008 21:46
@Rick: Stimmt, hast recht... Ich hatte den Text nicht richtig gelesen... ;)
Datum: 15.05.2008 09:49
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!
Datum: 15.05.2008 10:10
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.
Datum: 15.05.2008 10:22
Und wie stoppst du den Zähler bei z.B. FFFF?
Datum: 15.05.2008 10:25
Wenn der Wert kleiner 22 ist, wird inkrementiert, ansonsten nicht. Sowas kann zB so aussehen:
counter : process(Reset, Clk) signal cnt : unsigned(4 downto 0) := (others => '0'); begin if reset = '1' then cnt <= (others => '0'); elsif(rising_edge(Clk))then if cnt /= 22 then cnt <= cnt + 1; end if; end if; end process counter; |
Datum: 20.05.2008 09:44
@TM du schreibst: : Wenn der Wert kleiner 22 ist, wird inkrementiert, ansonsten nicht : und programmierst: :
if cnt /= 22 then |
: richtig wäre aber doch: :
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:
if counter < 22 then |
--> 6 Slices Vergleich auf UNGLEICH mit Konstante:
if counter /= 22 then |
--> 7 Slices Vergleich auf UNGLEICH mit Variable:
if counter /= endwert then |
--> 8 Slices Vergleich auf KLEINER mit Variable:
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?
Datum: 20.05.2008 12:47
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.
Datum: 28.05.2008 23:22
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.
Datum: 28.05.2008 23:28
Aehm 22 = 16 + 4 +2 , da hab ich bit1 vergessen passt aber immer noch in die 4LUT
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [vhdl]VHDL-Code[/vhdl]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel