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
waituntilrising_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
endif;
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
endif;
20
elsif(counter>="1010")then
21
counter<="0000";
22
endif;
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
endif;
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
waituntilrising_edge(clk,reset);
35
if(reset='1')then
36
counter<="0000";
37
elsif(reset='0')then
38
counter<=counter+"0001";
39
endif;
40
41
endprocess;
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
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_StdBeitrag "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.vhdhttps://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
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
-....
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!.htmlGutachter 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... ;-)
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".
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.
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@(posedgeclkorposedgereset)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.
Eine eigene Frage?
Dieser Thread ist über 6 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.