Forum: FPGA, VHDL & Co. Zähler: Variationen im process


von Maximilian L. (mex_1991)


Lesenswert?

Hi,

ich arbeite mich zurzeit in VHDL rein und versuche viele mögliche 
Variationen für den Zähler im process zu konstruieren. Es wäre super, 
wenn ihr euch diese kurz anschauen könntet und ggf. auf Fehler 
aufmerksam machen könntet.
1
process
2
begin
3
4
wait until rising_edge(clk);
5
6
--synchroner Reset auf 0 wenn Taster betätigt
7
if(reset='1') then
8
counter<="0000";
9
elsif(reset='0') then
10
counter<=counter+"0001";
11
end if;
12
13
--synchroner Reset auf 5 wenn Taster betätigt und Zählerbegrenzung auf den Wert 9
14
if(counter<"1010") then
15
      if(reset='1') then
16
      counter<="0101";
17
      elsif(reset='0') then
18
      counter<=counter+"0001";
19
      end if;
20
elsif(counter>="1010") then
21
counter<="0000";
22
end if;
23
24
--Zähler, der von oben nach unten zählt (von 10 zu 0) mit synchronem  Reset --auf 10
25
if(reset='1') then
26
counter<="1010";
27
elsif(reset='0') then
28
counter<=counter-"0001";
29
end if;
30
31
--Zähler mit asynchronem Reset
32
--bei asynchronem Reset muss der Reset-Auslöser in der Senitivity List
33
--stehen, da es taktunabhängig sein soll
34
wait until rising_edge(clk,reset);
35
if(reset='1') then
36
counter<="0000";
37
elsif(reset='0') then
38
counter<=counter+"0001";
39
end if;
40
41
end process;

Mir ist bewusst, dass es sich nicht um einen vollständigen Code handelt 
sondern nur um ein Fragment des process.

Zum synchronen/asynchronen Zähler:
Ich bin mir nicht sicher ob das Aufnehmen des Resets in die Sensivity 
List gleich für einen asynchronen Reset sorgt. Ich habe nämlich auch 
andere Codes gesehen die für den synchronen Reset die Bedingung 
"rising_edge" mit rein packen. Demzufolge wären alle meine Resets 
asynchron da ich nicht die steigende Flanke abfrage. Was ist denn nun 
richtig?

Zur Zählvariable "counter":
Darf die Variable "counter" vom Typ std_logic_vector sein? Mal habe ich 
gehört dass es sich bei std_logic_vector nur um eine Reihe von Bits 
handelt--> nicht für Rechenoperationen, zB Inkrementierungen zu 
gebrauchen. Muss ich die Variable counter also zu unsigned konvertieren 
bevor ich Inkrementierungen durchführe?

Ich danke euch im Voraus,

MfG

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


Lesenswert?

Maximilian L. schrieb:
> --Zähler mit asynchronem Reset
Wenn da ganz vorne ein wait for rising_edge() steht, dann ist der 
komplette nachfolgende Prozess synchron. Egal, ob und wie danach 
irgendwelche if-else verschachtelt sind.
http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozess

> Mir ist bewusst, dass es sich nicht um einen vollständigen Code handelt
> sondern nur um ein Fragment des process.
Dieser Prozess wird so bestenfalls vom Simulator irgendwie "gefressen". 
Der Synthesizer wird da sehr wahrscheinlich wild den Kopf schütteln. 
Denn der Synthesizer muss alles als Flipflop abbilden, was mit einem 
rising_edge() oder falling_edge() oder genauer mit einem 'event zu tun 
hat. Und das schafft er mit deiner Hardwarebeschreibung garantiert 
nicht.

> Mir ist bewusst, dass es sich nicht um einen vollständigen Code handelt
Wenn du konkrete Fragen hast, dann solltest du genau und komplett 
den Code posten, den du dem Simulator bzw. dem Synthesizer vorgelegt 
hast.
Den Beitrag "Re: Wie funktioniert dieses VHDL Programm?" könntest du dir 
da auch kurz mal ansehen.

> wait until rising_edge(clk,reset);
Das hast du dir jetzt aber selbst ausgedacht? Oder wo im Handbuch deines 
Synthesizers steht, dass das geht?

> Was ist denn nun richtig?
Lass dir von deiner Hardwarebeschreibung ab&zu einfach mal einen 
Schaltplan malen (RTL Schematic) und sieh dir die Komponenten an, die da 
drin verwendet werden. Sind das synchrone oder asynchrone Flipflops?

> Darf die Variable "counter" vom Typ std_logic_vector sein?
1. Du verwendest keine Variable "counter", sondern ein Signal "counter".
2. Nimm keine Variablen, wenn du keine brauchst. Hier brauchst du keine.
3. Rechne nicht mit std_logic_vector. Nimm (un)signed oder integer 
dafür. Am besten siehst du dir die numeric_std mal ganz genau an. Die 
reicht, um später sein Brot damit verdienen zu können.
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std
Beitrag "VHDL Grundlagen : Rechnen"

> Muss ich die Variable counter also zu unsigned konvertieren bevor ich
> Inkrementierungen durchführe?
Deklariere das Signal "counter" als unsigned oder integer. Dann sparst 
du dir das Umwandeln.

> Ich bin mir nicht sicher ob das Aufnehmen des Resets in die Sensivity
> List gleich für einen asynchronen Reset sorgt.
Ich sehe da nirgends eine Sensitivliste!
Ein "wait until rising_edge(clk);" macht viel, viel mehr als wenn du 
einfach nur clk in eine Sensitivliste eintragen würdest. Sieh dir 
einfach mal den Code an, der hinter rising_edge() steckt:
https://www.csee.umbc.edu/portal/help/VHDL/packages/std_logic_1164.vhd
https://tams.informatik.uni-hamburg.de/vhdl/doc/faq/FAQ1.html#rising_edge

> ich arbeite mich zurzeit in VHDL rein und versuche viele mögliche
> Variationen für den Zähler im process zu konstruieren.
Vergiss das. Das ist planloses Herumgebastel. Geh besser her und mache 
einen einzigen einfachen Zähler. Schau dir den RTL-Schaltplan an und 
überleg dir, ob du das wolltest, was der Synthesizer aus deiner 
Beschreibung gemacht hat.
Dann mache den Zähler "komplzierter" oder "anders" und schau, ob der 
Synthesizer das verstanden hat, was du beschrieben hast.
So ähnlich habe ich das z.B. im 
Beitrag "Re: Hardware mit VHDL "richtig" beschreiben." mal mit 
einem einzigen Flipflop gemacht.


BTW: bitte nimm die [vhdl] Tags zum Umrahmen des geposteten VHDL Codes. 
Einfach mal den Text unter
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
durchlesen

BTW2:
Im Beitrag "Re: Einfacher VHDL Zähler" sind auch noch 
ein paar brauchbare Links... ;-)

: Bearbeitet durch Moderator
von Gutachter h.c. (Gast)


Lesenswert?

Lothar M. schrieb:
>> ich arbeite mich zurzeit in VHDL rein und versuche viele mögliche
>> Variationen für den Zähler im process zu konstruieren.
> Vergiss das. Das ist planloses Herumgebastel. Geh besser her und mache
> einen einzigen einfachen Zähler. Schau dir den RTL-Schaltplan an und
> überleg dir, ob du das wolltest, was der Synthesizer aus deiner
> Beschreibung gemacht hat.
> Dann mache den Zähler "komplzierter" oder "anders" und schau, ob der
> Synthesizer das verstanden hat, was du beschrieben hast.

Die Synthesetools arbeiten nach 'templates' die im "synthesis Style 
guide" o.ä. beschrieben sind.

Bspw Xilinx, vivado 
https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_7/sim.pdf 
S. 37ff ..


Du hast also garnicht alle Möglichkeiten, die Dir der 'Syntaktische 
Zucker' von VHDL bietet.

Stattdessen solltest du die verschiedenen Hardwaremöglichkeiten von 
counter ausprobieren und am Synthesereport checken, wie gross und 
schnell diese Varianten sind. Da sind bspw:
-Shiftregister basierte counter
-Gray encoded counter
-binar ancoded counter
-counter mit synchronen/asynchronen PowerUp-Reset
-counter ohne PowerUp-reset
-counter aus SRL32 macros
-counter aus FIFO-primitiven
-Ripple-counter
-Linear Feedback Shift register (LFSR) als counter
-run-once counter/overwrap counter
-....

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


Lesenswert?

Gutachter h.c. schrieb:
> Du hast also garnicht alle Möglichkeiten, die Dir der 'Syntaktische
> Zucker' von VHDL bietet.
Sagen wir mal so: der gesamte Sprachumfang von VHDL ist 100%. Davon 
kommt der Simulator mit 80% zurecht. Für die Synthese kannst du 
bestenfalls 5% verwenden und musst dafür noch bestimmte Reglen anwenden.

Letztendlich muss die gesamte VHDL-Beschreibung im FPGA mit LUTs und 
Flipflops abgebildet werden können. Schon bei einem simplen "wait for 
100 ns;" geht das nicht mehr: 
http://www.lothar-miller.de/s9y/archives/80-Hello-World!.html

Gutachter h.c. schrieb:
> Stattdessen solltest du die verschiedenen Hardwaremöglichkeiten von
> counter ausprobieren und am Synthesereport checken
Und den RTL-Plan ansehen, ob tatsächlich der gewünschte Zähler 
implementiert wurde... ;-)

: Bearbeitet durch Moderator
von Gutachter h.c. (Gast)


Lesenswert?

Maximilian L. schrieb:
> Zum synchronen/asynchronen Zähler:
> Ich bin mir nicht sicher ob das Aufnehmen des Resets in die Sensivity
> List gleich für einen asynchronen Reset sorgt.

Nein, da muss trotzdem ein IF arst = '1' then rein und das höher prior 
als das rising_edge(clk). Wäre es niederprior dann wär es ein synchroner 
reset.

Synchron meint eben "auf der Taktflanke" und asynchron "takt is 
wurscht".

von Gutachter h.c. (Gast)


Lesenswert?

Lothar M. schrieb:
> Gutachter h.c. schrieb:
>> Stattdessen solltest du die verschiedenen Hardwaremöglichkeiten von
>> counter ausprobieren und am Synthesereport checken
> Und den RTL-Plan ansehen, ob tatsächlich der gewünschte Zähler
> implementiert wurde... ;-)

Manchmal genügt die Suche im Synthesereport nach der Phrase "counter 
inferred"
http://www.cs.columbia.edu/~sedwards/classes/2005/emsys-summer/xst.pdf 
S. 54ff.

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


Lesenswert?

Maximilian L. schrieb:
> --Zähler mit asynchronem Reset
> wait until rising_edge(clk,reset);
Zudem ist ein asynchroner Reset nicht flankengengetriggert(*), sondern 
üblicherweise pegelabhängig: so lange der Reset aktiv ist, wird der Takt 
ignoriert.


(*) auch wenn man das bei so mancher Verilog-Beschreibung meinen könnte, 
wenn dort steht:
1
always @(posedge clk or posedge reset) begin
denn dieser Code wird dann gefolgt von sowas:
1
    if(reset == 1'b1)
2
       reg <= 0; // reset condition
3
    else
4
       reg <= whatever; // non-reset condition
5
end
Und das bedeutet: wenn eine steigende Flanke vom clk kommt, wird 
trotzdem erst mal der Pegel vom reset abgefragt.

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.