Gibt es eine alternative Beschreibung, mittels derer der Zähler beim
Maximalwert stehenbleibt, man jedoch keinen Komparator verwenden muss?
Grüsse, Harry
> Gibt es eine alternative Beschreibung, mittels derer der Zähler beim> Maximalwert stehenbleibt, man jedoch keinen Komparator verwenden muss?>
Ich weiss nicht, was dich dabei stört? Oder was genau dein Problem ist.
Dein Code muss noch zwei Sachen sinnvoller Weise beinhalten.
--ein Wert von wo aus gezählt wird
--Rücksetzmechanismus
Wenn der Zähler so gestrickt ist, dass der Endwert eine Binärzahl ist
und er rückwärtsläuft, dann ist der "Komparator" nur ein einziges Bit,
dass den enable des Zählers freigibt.
JBB schrieb:> Wenn der Zähler so gestrickt ist, dass der Endwert eine Binärzahl ist> und er rückwärtsläuft, dann ist der "Komparator" nur ein einziges Bit,> dass den enable des Zählers freigibt.
Ach, geh...
Der Komparator ist immer über die volle Breite, weil alle Bits gestestet
werden müssen, ob sie 0 sind.
Es stimmt aber, dass ein Vergleich auf Gleichheit wahrscheinlich
effizenter ist als ein Vergleich auf kleiner.
Ob er nach oben oder unten zählt ist egal.
Harry schrieb:> Gibt es eine alternative Beschreibung, mittels derer der Zähler beim> Maximalwert stehenbleibt, man jedoch keinen Komparator verwenden muss?
Nur, wenn du (wie schon erwähnt) eine Zweierpotenz hast, dann kannst du
ein Bit mehr spendieren und diesen Überlauf (beim Hochzählen) zum
Anhalten des Zählers verwenden...
Klaus Falser schrieb:> JBB schrieb:>> Wenn der Zähler so gestrickt ist, dass der Endwert eine Binärzahl ist>> und er rückwärtsläuft, dann ist der "Komparator" nur ein einziges Bit,>> dass den enable des Zählers freigibt.>> Ach, geh...> Der Komparator ist immer über die volle Breite, weil alle Bits gestestet> werden müssen, ob sie 0 sind.> Es stimmt aber, dass ein Vergleich auf Gleichheit wahrscheinlich> effizenter ist als ein Vergleich auf kleiner.> Ob er nach oben oder unten zählt ist egal.
es geht aoch ohne all bits zu vergleichen:
1) One-Hot schieberegister verwenden, dann braucht man nur ein bit
vergleichen
2) Zähler als binärinkrement bauen mit Maximalwert "alle bits '1'",
dann ist das carry_out der höchsten Zählerstelle das einzige zu testende
bit.
MfG,
Sigi schrieb:> (signed!) Zähler von MAX-1 runterzählen lassen und bei Überlauf stoppen.
So wurde das schon in den Urgesteinen 8048 und 8051 uCs gemacht... ;-)
> bei Überlauf stoppen
Eigentlich ist das ein Unterlauf...
>1) One-Hot schieberegister verwenden, dann braucht man nur ein bit>vergleichen
Na das wird von der Größe des Schieberegisters für größere Zähler nicht
haltbar sein.
Was haltet ihr von folgender Variante?
Man lagert den Vergleich getaktet aus. Dabei muss man dafür sorgen, dass
aufgrund des Delays der Zähler rechtzeitig aufhört zu zählen.
Hintergrund meiner Überlegungen: Für große Zähler möchte ich NICHT
Zähler und Komparator in einem Takt behandeln, um die Performance
zu steigern.
Harry schrieb:> Man lagert den Vergleich getaktet aus.
Hört sich an wie: man lügt sich was in die Tasche...
Warum sollte da ein Vergleicher gespart werden?
Was ist denn eigentlich dein Ziel?
> if cnt = cMAX-1 or cnt = cMAX then
Wie bitte?
Das solltest du dir nochmal überlegen.
Ich würde da einfach so schreiben:
if cnt>=cMAX-1 then
Harry schrieb:> Für große Zähler möchte ich NICHT> Zähler und Komparator in einem Takt behandeln, um die Performance> zu steigern.
Wie groß sollen denn Deine Zähler werden? Und wie schnell möchtest Du
damit zählen. Üblicherweise sind in einem Design nicht die Zähler das
limitierende Element.
Duke
>Hört sich an wie: man lügt sich was in die Tasche...>Warum sollte da ein Vergleicher gespart werden?>Was ist denn eigentlich dein Ziel?
OK, man spart keinen Vergleicher, sondern separiert Zähler und
Komparator derart, dass die kombinatorische Logik kleiner wird.
>if cnt>=cMAX-1 then
ACK
>Was ist denn eigentlich dein Ziel?
Kombinatorik verkleinern und somit fMAX steigern.
Grüsse, Harry
Harry schrieb:> OK, man spart keinen Vergleicher, sondern separiert Zähler und> Komparator derart, dass die kombinatorische Logik kleiner wird.
Nein. Sie bleibt genau gleich. Denn es ist ja auch der selbe
Vergleicher (es steht ja auch genau der selbe VHDL-code da)...
Harry schrieb:> Kombinatorik verkleinern und somit fMAX steigern.
Du kannst mit dem Einfügen von zusätzlichen Registern und dem Aktivieren
von "Register Balancing" eventuell Taktfrequenz gegen Latenz
eintauschen. Aber dein Vergleicher wird in der Summe niemals
"schneller":
Wenn der 8 Logikebenen hat, dann kannst du z.B. in die 4. Ebene einen
Zwischenspeicher einfügen und dadurch die Taktfrequenz (fast)
verdoppeln. Dein Vergelich ist dann aber erst nach 2 Takten fertig....
>Nein. Sie bleibt genau gleich
Das ist so aber nicht richtig, denn ich generiere mir ein getaktetes
Enable-Signal und verwende dieses statt des Komparators für den
Zählvorgang.
Durch das Enable-Signal habe ich die Kombinatorik gesplittet.
Harry schrieb:> Das ist so aber nicht richtig, denn ich generiere mir ein getaktetes> Enable-Signal und verwende dieses statt des Komparators für den> Zählvorgang.> Durch das Enable-Signal habe ich die Kombinatorik gesplittet.
Hast du dir den RTL-Plan mal angeschaut? Dieses zusätzliche Flipflop
sitzt einfach hinter dem gleichen Vergleicher und bringt dir 1 Takt
Latency. Sonst ändert sich nichts.
Harry schrieb:> dass bei Verwendung von "ena" die Kombinatorik gesplittet wird.
In der Praxis sieht so ein Zähler aber ganz anders aus, weil dieser
Addierer einfach als Carryeingang im FPGA realisiert wird, und daher
keine zusätzliche Logikebene erfordert. Dies wird vom Synthesetool hier
nur unzureichend abgebildet...
>In der Praxis sieht so ein Zähler aber ganz anders aus, weil dieser>Addierer einfach als Carryeingang im FPGA realisiert wird
Mit welchem Tool kann man sich die Praxis im FPGA denn anschauen?
Harry schrieb:> Beide Schaltungen sollten funktional gleich sein.
Sind sie aber nicht, in der 2. Variante wird der Zähler einen Takt
später gestoppt. Und das ist genau das was Lothar meint, fMax gegen
Latency getauscht.
Harry schrieb:> Mit welchem Tool kann man sich die Praxis im FPGA denn anschauen?
Das ist der RTL-Schaltplan. Wie du den bekommst, das kommt auf den
Synthesizer an. Mit XST geht es seit der Version 13 gar nicht mehr: das
Ding vergisst einfach, die Module miteinander zu verbinden.. :-(
Dann kommt mit dieser Beschreibung nur noch sowas raus wie im Anhang...
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.NUMERIC_STD.ALL;
4
5
entityctois
6
Port(clk:inSTD_LOGIC;
7
o:outSTD_LOGIC_VECTOR(7downto0)
8
);
9
endcto;
10
11
architectureBehavioralofctois
12
signalcnt:integer:=0;
13
constantcMAX:integer:=8;
14
begin
15
16
process(clk)
17
begin
18
ifrising_edge(clk)then
19
ifcnt/=cMAXthen
20
cnt<=cnt+1;
21
endif;
22
endif;
23
endprocess;
24
25
o<=std_logic_vector(to_unsigned(cnt,8));
26
27
endBehavioral;
Lattice User schrieb:> fMax gegen Latency getauscht.
Richtig, und das kann man machen, solange man noch einen Takt "Luft"
hat.
Harry schrieb:> if cnt2 < 2**16-1 then -- Komparator und zähler zusammen> if cnt >= 2**16-2 then
Ja. Das ist Latency... ;-)
Es macht übrigens in der Realität auch was aus, ob du das schreibst:
if cnt2 < 2**16-1 then
Oder das:
if cnt2 != 2**16-1 then
Und das, obwohl die Funktion hier exakt gleich ist: es wird gezählt
solange cnt kleiner als 65535 ist.
Fakt ist: "cnt" und "cnt2" verhalten sich identisch.
Fakt ist auch: Die "cnt"-Variante kann ein höheres fmax fahren.
Ergo: Für Performance ist die cnt-Variante mit Enable die Bessere.
Grüsse, Harry
Harry hat zwar Latenz erzeugt (und idR auch mehr Logik+FF),
bei ZMAX>>1 ist das mit der Latenz aber egal, wei's nur
zählerintern gebraucht wird. Und viel schneller lässt's sich
auch takten (Stopp hängt nur noch von einem Signal ab).
x /= y bzw. x < y:
bei modernen FPGAs (Xilinx,Altera CarryChains) ist das bei
idealer Implementierung gleich aufwendig, Synthesetools
sollte es aber auch können.
Harry schrieb:> Ergo: Für Performance ist die cnt-Variante mit Enable die Bessere.
Streitet niemand ab.
Man muss nur die Latency beachten, ich habe übersehen dass du genau
deswegen auf einen anderen Endwert vergleichst.
IMO geht noch mehr:
Keinen < Vergleich verwenden um die Komplexität des Vergleichs zu
reduzieren.
Beim Resetwert des Zählers kompensieren und nur auf Überlauf abfragen (1
bit vs viele).
Im Technology View von Synplify kann man sehen wie das ganze auf die
FPGA Primitiven abgebildet wird.
Sigi schrieb:> x /= y bzw. x < y:> bei modernen FPGAs (Xilinx,Altera CarryChains) ist das bei> idealer Implementierung gleich aufwendig
Leider nein. Probiers aus. Da war letzthin wieder mal ein Thread zum
Thema, und ich habe das selbe behauptet. Naja, Pech... ;-)
@Lothar Miller,
>> x /= y bzw. x < y:>..> Leider nein...
doch, zumindestens bei Xilinx Spartan3/Virtex4 (LUT4-CarryChain)
und Virtex5 (LUT5/6+CarryChain) bin ich mir sicher, habe mal die
CarryChain-Logik in eine Gleichung gefasst um das max. Mögliche
für mich zu ermitteln. Daraus habe ich dann die Gleichungen für
eine Menge von Operationen (ADD/SUB/CMP etc.) ermittelt. Vorteil
von CMP ist ausserdem, dass gleichzeitig le LUT 2Bits mit 2Bits
verglichen werden können (sozusagen braucht man nur die
"halbe Länge" an CarryChain).
Sigi schrieb:> doch, zumindestens bei Xilinx Spartan3/Virtex4 (LUT4-CarryChain)> und Virtex5 (LUT5/6+CarryChain) bin ich mir sicher
Für welche Synthese (Version)?
> habe mal die CarryChain-Logik in eine Gleichung gefasst um das> max. Mögliche für mich zu ermitteln.
Hat der Synthesizer das kapiert?
Mein Ansatz funktioniert ab ISE 5.1 (?), 6.1 sicher.
Allerdings benutze ich das Synthesetool nur für
die Instanziierung der Spartan3/Virtex4-Komonenten
(LUT4/FF/CARRYCHAIN etc.), d.h. die komplette Logik
muss von Hand erstellt werden (geht aber sehr leicht,
insb. generisch). Angewendet habe ich es z.B. in einer
eigenen CPU, die im Virtex4 (10er Speedgrade) mit
400 MHz läuft.
Von ISE selber kannst du eine solche Performance nicht
erwarten, selbst Harry's Ansatz mit dem vorgezogenen
Vergleich liefert eine laue Leistung.
Das zeigt mal wieder, wie mittelmässig ISE (Quartus
kenne ich kaum) einfach zu erkennende Konstrukte in
die Fabrikeigene Logik giessen kann.
Gruss