Hi
ich schreibe gerade eine State-Maschiene und bin mir nicht sicher ob ich
da "spramaßnahmen" einfügen soll oder ob es dem FPGA egal ist.
Ein Beispiel - ich will 20 ms abwarten, dazu zähle ich 100000 cycles ab
(ist die Zahl übrigens richtig bei 50MHz Takt?). Also schreibe ich
folgendes:
...
case cur_state is
...
when count =>
if ( i >= 100000 ) then -- i ist die Zählvariable
cur_state <= pulse;
i := 0;
else
i := i + 1;
-- tick <= '0';
-- cur_state <= count;
end if;
...
Fraglich sind die 2 auskommentierte Zeilen.
Erstens spielt die Zeile "tick <= '0';" nur bei dem ersten Durchlauf
eine Rolle (anders müsste ich ein zusätzliches "init" State einfügen).
Zweitens ist der cur_state sowieso "count", aber zur Sicherheit würde
ich es gern drin haben (habe so in Beispielen gesehen).
Also sind beide Zeilen mehr oder weniger überflüssig und z.B. in einem C
Programm würde ich diese Zeilen ganz sicher streichen. Jedoch bin ich
grad auf einem FPGA und vermute, dass es dem egal ist, ob diese Zeilen
da ind oder nicht. Sprich sie stellen kein zusätzliches Aufwand für den
FPGA dar. Oder irre ich mich da?
Was passiert beim hinzufügen / weglassen der Beiden?
Die Zeile mit
cur_state <= count;
macht deshalb keinen Unterschied, weil in beiden Fällen cur_state auf
count bleibt und die selbe Logik erzeugt wird.
Die Zeile mit
tick <= '0';
kann einen Unterschied machen, je nachdem ob und wie Tick sonst
verwendet wurde, weil in diesem Fall tick beim Zählen auf 0 gesetzt
werden muss.
Wäre es nicht geschickter, counter zu Anfang auf 100000 zu setzen, nach
unten zu zählen, und bei 0 etwas zu tuen? Denn der Vergleich mit 0 ist
angeblich platzsparender als größer-gleich.
Meine Frage war eher ob FPGA zusätzliche Arbeit durch diese Zeilen
bekommt.
Denn daraus werden ja physikalische schaltungen gemacht, und wenn ich
meine egal ob ich 1 mal oder 100000000000000000000 mal die "tick <=
'0';" zuweisung mache - die Leitung ist vorhanden, FPGA lässt da einfach
strom durch und entscheidet nicht jedes mal neu ob er das macht oder
nicht (verrichtet also keine zusätzliche Arbeit im Vergleich z.B. zu
einem mikrokontroller, der jedes mal an der Stelle '0' in den Register
schreiben würde).
Zumindest sehe ich die Sache so, und wollte wissen ob meine Sicht
richtig ist.
p.s. Die Idee mit dem Vergleich gegen 0 ist meiner ansicht nach richtig,
nur habe ich so viel platz, dass es mir egal ist; FPGA macht ja beides
in einem Takt und wird deswegen nicht langsamer
@ Dima Schmitt (onkelbenz)
>Meine Frage war eher ob FPGA zusätzliche Arbeit durch diese Zeilen>bekommt.
Dort nicht.
>Denn daraus werden ja physikalische schaltungen gemacht, und wenn ich>meine egal ob ich 1 mal oder 100000000000000000000 mal die "tick <=>'0';" zuweisung mache - die Leitung ist vorhanden, FPGA lässt da einfach>strom durch und entscheidet nicht jedes mal neu ob er das macht oder>nicht (verrichtet also keine zusätzliche Arbeit im Vergleich z.B. zu>einem mikrokontroller, der jedes mal an der Stelle '0' in den Register>schreiben würde).
Richtig.
>p.s. Die Idee mit dem Vergleich gegen 0 ist meiner ansicht nach richtig,>nur habe ich so viel platz, dass es mir egal ist; FPGA macht ja beides>in einem Takt und wird deswegen nicht langsamer
Ich dachte du wolltest dem FPGA "Arbeit" sparen? Klar, bei 50 MHz und
den heutigen FPGAs ist das erstmal egal. Aber wenn man effiziente und
schnelle Schaltungen bauen will, gelten viele der alten Reglen immer
noch, nur bei höheren Frequenzen ;-)
MfG
Falk
Dima Schmitt schrieb:> case cur_state is> ...> when count =>> if ( i >= 100000 ) then -- i ist die Zählvariable> cur_state <= pulse;> i := 0;> else> i := i + 1;
Das ist vermutlich die Zwei-Prozess-Schreibweise (wegen
cur(rent)_state). Und damit ist der Zähler mit i eine (versteckte)
kombinatorische Schleife.... :-o
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife
Dima Schmitt schrieb:> Ein Beispiel - ich will 20 ms abwarten, dazu zähle ich 100000 cycles ab> (ist die Zahl übrigens richtig bei 50MHz Takt?). Also schreibe ich> folgendes:> when count =>> if ( i >= 100000 ) then -- i ist die Zählvariable> cur_state <= pulse;> i := 0;> else> i := i + 1;> end if;
Nur am Rande: 0...10000 sind 10001 Zählschritte. Der Zähler wird also
systematisch um 0,1 Promille falsch gehen....
Dima Schmitt schrieb:> p.s. Die Idee mit dem Vergleich gegen 0 ist meiner ansicht nach richtig,> nur habe ich so viel platz, dass es mir egal ist;
Wenn du soviel Platz hast, dann kann es dir doch egal sein, ob da noch
ein Slice mehr oder weniger benötigt wird ...
Seltsame Fragestellung ...
Was du aber machen kannst ist, es einfach synthetisieren zu lassen und
dir entweder die erzeugte Ersatzschaltung anzusehen, was wirklich
gemacht wird, oder einfach zu kucken, wie deine FPGA-Auslastung ist.
Fetz schrieb:> Wenn du soviel Platz hast, dann kann es dir doch egal sein, ob da noch> ein Slice mehr oder weniger benötigt wird ...
Es geht eher darum, dass der eine zusätzliche Slice evtl. hinter den
anderen sitzt und so die max. Taktfrequenz reduziert...
Man kann tun&lassen, was man will, aber wenn man seinen Baustein kennt,
kann man besser bewerten, was die Konsequenzen draus sind.
Der Weise schrieb:> Wäre es nicht geschickter, counter zu Anfang auf 100000 zu setzen, nach> unten zu zählen, und bei 0 etwas zu tuen? Denn der Vergleich mit 0 ist> angeblich platzsparender als größer-gleich.
Kuehne Behauptung, kannst du die belegen?
Was man machen kann ist, auf Zweierpotenzen abzufragen und die LSBs zu
ignorieren. Z.B. wenn du 128 mal incrementen willst waere das ja von
x"00" bis x"7F". Wuerdest du deinen Zaehler von x"01" bis x"80" laufen
lassen, dann muesstest du nur das MSB abfragen, also: if hugo (7) = '1'
then ...
Das spart dann wirklich Logik
berndl schrieb:> Der Weise schrieb:>> Wäre es nicht geschickter, counter zu Anfang auf 100000 zu setzen, nach>> unten zu zählen, und bei 0 etwas zu tuen? Denn der Vergleich mit 0 ist>> angeblich platzsparender als größer-gleich.>> Kuehne Behauptung, kannst du die belegen?>> Was man machen kann ist, auf Zweierpotenzen abzufragen und die LSBs zu> ignorieren. Z.B. wenn du 128 mal incrementen willst waere das ja von> x"00" bis x"7F". Wuerdest du deinen Zaehler von x"01" bis x"80" laufen> lassen, dann muesstest du nur das MSB abfragen, also: if hugo (7) = '1'> then ...>> Das spart dann wirklich Logik
Mooooment ... das ist nicht ganz richtig ...
Wenn der Ausgang nur einen Puls bei "128" erzeugen soll, dann brauchst
du trotzdem einen Vergleich, der alle Bits berücksichtigt.
In deinem Beispiel hast du einfach die Logik geändert ... Passt nicht
mehr zum ursprünglichen Beispiel.
Fetz schrieb:>> Das spart dann wirklich Logik> Mooooment ... das ist nicht ganz richtig ...
Doch, das stimmt. Leider ist dein Beispiel am Thema vorbei.
Beschreib den Enable mal so wie hier:
Lothar Miller schrieb:
ah, Lothar hat aufgepasst :o)
Man kann auch noch eine Zeile einsparen:
1
process(clk)begin-- Pulserzeugung
2
pulse<='0';
3
cnt<=cnt+1;
4
ifcnt(7)='1'then
5
pulse<='1';
6
cnt<=to_unsigned(1,8);
7
endif;
8
endprocess;
Uebrigens, weil Lothar auch den 'unsigned' counter verwendet: Da sieht
man wenigstens, wo Optimierungspotential besteht. Mit Integer kommst du
da nicht so leicht drauf...
Eine weitere Frage ist auch, ob das 'zuruecksetzen' eines counters auf
einen krummen Wert mehr Resourcen verbraucht als ein 'reset' auf 0
berndl schrieb:> Eine weitere Frage ist auch, ob das 'zuruecksetzen' eines counters auf> einen krummen Wert mehr Resourcen verbraucht als ein 'reset' auf 0
Nein, tut es nicht, solange nicht ein zusätzlicher "globaler" Reset
definiert ist. Das hier ist schlecht:
1
processbegin-- Pulserzeugung
2
waituntilrising_edge(clk);
3
ifreset='1'then-- synchroner Zählerreset Nummer 1 --> alle Bits auf '0'
4
cnt<=(others=>'0');
5
else
6
ifcnt(7)='1'then
7
pulse<='1';
8
cnt<=to_unsigned(1,8);-- synchroner Zählerreset Nummer 2 --> cnt(0) wird anders behandelt...
9
else
10
pulse<='0';
11
cnt<=cnt+1;
12
endif;
13
endif;
14
endprocess;
Wenn es nur 1 Reset/Preset gibt, dann kann das 1:1 auf diese Eingänge am
Flipflop abgebildet werden. Wenn aber beim 1. Reset das FF zurückgesetzt
und beim 2. Reset gesetzt werden soll, dann braucht das zusätzliche
Logik.
Hallo,
was halten die Spezialisten eigentlich davon das Signal pulse
kombinatorisch zu erzeugen?
Ich glaub zwar daß das den Pulse einen Clock nach vorn zieht, aber es
spart ein Register?
Ciao, Günter
Günter (dl4mea) schrieb:> Ich glaub zwar daß das den Pulse einen Clock nach vorn zieht, aber es> spart ein Register?
Ja. Sieht man schoen an deinem 2. Beispiel (clock Abfrage fehlt aber
noch). Beim 1. Beispiel koennte man noch denken, es braeuchte eine LUT
fuer den Vergleich...
Lothar Miller schrieb:> process (clk) begin -- Pulserzeugung> if cnt(7)='1' then> pulse <= '1';> cnt <= to_unsigned(1,8);> else> pulse <= '0';> cnt <= cnt+1;> end if;> end process;
Ja gut, so geht natürlich. Dachte, du lässt den Counter freilaufen und
nimmst nur das 8te Bit.