Hallo,
gibt es einen Trick bei VHDL bei Integerzahlen bestimmte Anzahl von 0ern
abzuschneiden ohne zu dividieren?
Beispiel...
Ich habe einen Counter der bis in den 100tausender bereich zaehlt,
moechte aber nicht mit der grossen Zahl fortfahren sondern nur die
ersten drei Ziffern verwenden...
Bsp.:
Counter zaehlt bis 130000, moechte aber nur die 130 davon verwenden...
die restlichen drei 0er sollen abgeschnitten werden...
Komme ich da an einer Division vorbei oder ist die Division unabdingbar?
Vielen Dank im voraus.
Mfg
Fellap
Schlumpf schrieb:> Willst du immer die gleichen Stellen aus deiner Zahl> rausschneiden?> Müssen die Grenzen Dezimal sein, oder dürfen es auch Hexadezimale> Grenzen sein?
jepp immer die gleichen Stellen...
solange ich die Hexadezimale wieder in Dezimal casten kann.. ist das
egal :)
.... schrieb:> als BCD zählen?
genau.
jede einzelne stelle der zahl als bcd-Zähler, dann kann man einfach die
hinteren stellen weglassen
EDIT: oder zwei getrennte Zähler: abschneidbare stellen und nicht
abschneidbare. Das dürfte besser sein, wenn die schnittgrenze konstant
ist
Fellap schrieb:> solange ich die Hexadezimale wieder in Dezimal casten kann.. ist das> egal :)
Ich meinte eher, ob diese Stellen, an denen du abschneidest, 10er sein
müssen, oder ob es auch 16er sein dürfen.
Jonas K. schrieb:> .... schrieb:>> als BCD zählen?>> genau.> jede einzelne stelle der zahl als bcd-Zähler, dann kann man einfach die> hinteren stellen weglassen>> EDIT: oder zwei getrennte Zähler: abschneidbare stellen und nicht> abschneidbare. Das dürfte besser sein, wenn die schnittgrenze konstant> ist
BCD-Zaehler ist aber recht kompliziert oder?
Wie meinst du das mit zwei Zaehlern? das hoert sich interessant an...
Kannst du mir mal bitte ein Bsp. geben.. (muss jetzt kein code sein..)
verstehe noch nicht ganz was du damit meinst...
Ein BCD-Zähler zählt einfach jede Stelle für sich Binär, erzeut aber den
Übertrag, wenn er von 9 nach 0 springt..
z.B.
Dezimal: 123 = BCD 0001 0010 0011
1 2 3
Schlumpf schrieb:> Ich meinte eher, ob diese Stellen, an denen du abschneidest, 10er sein> müssen, oder ob es auch 16er sein dürfen.
nee muss schon 10er sein
Schlumpf schrieb:> Ein BCD-Zähler zählt einfach jede Stelle für sich Binär, erzeut aber den> Übertrag, wenn er von 9 nach 0 springt..>> z.B.> Dezimal: 123 = BCD 0001 0010 0011> 1 2 3
ja aber dann habe ich ja drei Variablen oder Signale, richtig?
Ich moechte von der Zahl aber dann jedoch was abziehen .. dann muss ich
die andere zahl, die abgezogen wird auch in BCD umrechnen oder?
bzw BCD wieder in einen Bitvector, Integer oder sonstwas umwandeln...
und das ist recht kompliziert oder?
Fellap schrieb:> Kannst du mir mal bitte ein Bsp. geben.. (muss jetzt kein code sein..)> verstehe noch nicht ganz was du damit meinst...
Angenommen, du weißt schon, du willst immer durch eine bestimmte Zahl
teilen (kann z. B. 100 sein). Dann machst du einen ersten Zähler, der
bis 99 zählt, und einen zweiten, der mit dem Überlauf (99 -> 0) des
ersten Zählers hochgezählt wird.
Das Ergebis der Division ist damit jederzeit der Wert des zweiten
Zählers.
Zähler 1 Zähler 2 Gesamtzahl
0 0 0
1 0 1
2 0 2
... 0 ...
98 0 98
99 0 99
0 -> 1 100
... 1 1..
99 1 199
0 -> 2 200
Jonas K. schrieb:> Angenommen, du weißt schon, du willst immer durch eine bestimmte Zahl> teilen (kann z. B. 100 sein). Dann machst du einen ersten Zähler, der> bis 99 zählt, und einen zweiten, der mit dem Überlauf (99 -> 0) des> ersten Zählers hochgezählt wird.>> Das Ergebis der Division ist damit jederzeit der Wert des zweiten> Zählers.>> Zähler 1 Zähler 2 Gesamtzahl> 0 0 0> 1 0 1> 2 0 2> ... 0 ...> 98 0 98> 99 0 99> 0 -> 1 100> ... 1 1..> 99 1 199> 0 -> 2 200
ah.. ja verstehe.. aber wie bekomme ich die zusammenfuerhung von zaehler
eins und zwei hin?
du machst ein signal, das im ersten Process (1. zähler) den overflow
anzeigt, und verwendest es als enable-signal für den zweiten process.
Such mal nach enable-signal...
Fellap schrieb:> Also z.B. zahl 6 bis zahl 4 als einen vektor?
schaut schon recht gut aus!
du musst also die integer-Werte zusammenzählen und mit 10
multiplizieren.
Besser wäre schon die Version mit nur zwei Zählern, weil du dann die
obere Zahl direkt abgreifen kannst.
Konvertierung und Casts siehe hier:
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std
Ich hab mal deinen Code modifiziert.
1
libraryIEEE;
2
useIEEE.STD_LOGIC_1164.ALL;
3
useIEEE.STD_LOGIC_ARITH.ALL;
4
useIEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
7
8
9
entitycounteris
10
Port(clk:inSTD_LOGIC;
11
q:outSTD_LOGIC_VECTOR(6downto0)
12
);
13
endcounter;
14
15
16
architectureBehavioralofcounteris
17
18
signalzahl1:integer:=0;
19
signalzahl4:integer:=0;
20
21
begin
22
23
process(clk)
24
begin
25
26
ifclk'eventandclk='1'then-- rising clock edge
27
-- ausgang synchron treiben
28
q<=std_logic_vector(to_unsigned(zahl4,7));-- 7 Bits bei 99
29
-- zählen
30
ifzahl1=999then-- diesen Wert anpassen für beliebige andere "Division"
31
zahl1<=0;
32
ifzahl4=99then-- dieser Wert legt das gesamtmaximum fest
Fellap schrieb:> Counter zaehlt bis 130000, moechte aber nur die 130 davon verwenden...> die restlichen drei 0er sollen abgeschnitten werden...
Was ist denn das eigentliche Problem, die eigentliche Aufgabenstellung
hier? Wofür braucht man sowas?
Ich würde wie Jonas den Counter einfach um den Faktor 100 langsamer
zählen lassen. In einem uC macht man das mit einem Vorteiler. Nur sähe
mein Code ein klein wenig anders aus... ;-)
Jonas K. schrieb:> signal zahl1: integer := 0;
Ich würde hier z.B. immer eingeschränkte Integer nehmen.
Ingo schrieb:> Was is denn so schlimm an einer Division?
Sie ist entweder unglaublich langsam oder unglaublich aufwendig. Oder
beides...
Nur vorzeichenlose Divisionen durch Zweierpotenzen sind trivial.
Ich verstehe den Sinn nicht so ganz.
Falls der Computer rechnet, ist es doch wesentlich einfacher hinten
binär etwas abzuschneiden.
Dezimalsystem ist doch nur für Ausgabe an Menschen. Denn nur die Rechnen
im 10er System. Und für Menchen kann man doch mal 1000 Takte für eine
Division bereitstellen. Bei 50 MHz wäre das eine Update-Rate von 50 KHz.
Immer noch zu schnell für einen Menschen.
Und bei einem FPGA kann ja die Rechnung parallel laufen, stört also die
anderen Algorithmen gar nicht.
Ich habe das Gefühl, dass dir eine Division zu kompliziert ist, und du
sie deshalb umgehen möchtest. Dabei gibt schon bei Lothar eine fertige
Lösung:
http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html
Lothar Miller schrieb:> Ich würde wie Jonas den Counter einfach um den Faktor 100 langsamer> zählen lassen. In einem uC macht man das mit einem Vorteiler. Nur sähe> mein Code ein klein wenig anders aus... ;-)
Ich moechte die Periode von einem Takt bestimmen... damit die Bestimmung
genauer wird, wollte ich anstatt einer Periode, 100 Perioden zaehlen...
Deswegen moechte ich durch 100 teilen... bzw. die nullen abschneiden...
Fellap schrieb:> Deswegen moechte ich durch 100 teilen... bzw. die nullen abschneiden...
Auch in VHDL muss es doch eine Möglichkeit geben, einen Zähler zu
implementieren, der als Vorteiler arbeitet.
Fellap schrieb:> Ich moechte die Periode von einem Takt bestimmen... damit die Bestimmung> genauer wird, wollte ich anstatt einer Periode, 100 Perioden zaehlen...
Du hast damit immer noch nicht meine Fragen beantwortet. Du siehst das
Problem zu fokussiert und nimmst das Drumrum nicht wahr...
WARUM machst du das Ganze? WAS für ein Gerät soll das geben? Einen
Frequenzmesser, der die Frequenz dann anzeigt? ODer wird dieser Wert
nicht für irgendeine Anzeige verwendet? Falls das so ist: WER braucht
diesen Wert und wie kommt er dort hin?
Fellap schrieb:> 100 Perioden zaehlen...> Deswegen moechte ich durch 100 teilen... bzw. die nullen abschneiden...
Du bist gut beraten, wenn du in einem digitalen System bei sowas deine
Grenzen auf 2er Potenzen legst.
Ob du nun 100 oder 128 Perioden zählst, sollte vom Prinzip ja egal sein.
Mit dem kleinen Unterschied, dass eine Division mit 128 viel einfacher
ist.
Du willst also messen, wie lange 100 Taktperioden dauern. Sprich, du
zählst lässt einen schnellen Zähler x laufen und mit einem anderen
Zähler zählst du 100 Perioden von deinem zu messenden Signal. Nach 100
Perioden dividierst du dann den Zählerstand von x mit 100 und hast deine
gemittelte Periodendauer der letzten 100 Takte. Richtig?
Wenn das so ist, dann zähle doch einfach nicht 100 sondern 128 Perioden
lang.
Dann musst x nicht durch 100, sondern durch 128 teilen und das ist
trivial
Fellap schrieb:> Ich moechte die Periode von einem Takt bestimmen... damit die Bestimmung> genauer wird, wollte ich anstatt einer Periode, 100 Perioden zaehlen...> Deswegen moechte ich durch 100 teilen... bzw. die nullen abschneiden...
Wieso erwartest du, dass beim Auszählen der Dauer von 100 Perioden das
Zählergebnis hinten lauter Nullen hat? Gerade die Information in diesen
hinteren Stellen erhöht deine Genauigkeit. Wenn du diese Stellen
abschneidest (Integer-Division durch 100), kannst du auch gleich nur
eine einzelne Periode zählen.
Wenn 100 Perioden lang gezählt wird und die (eine) Periodendauer in
Zählerschritten gesucht ist, dann kann man doch die Gesamtzahl durch die
Zahl der Perioden teilen und erhält wie viele Zählerschritte eine
Periode im durchschnitt dauert. Oder verstehe ich da was nicht?! Der
Zähler sollte natürlich deutlich schneller wie die zu bestimmende
Frequenz sein.
Gustl Buheitel schrieb:> Wenn 100 Perioden lang gezählt wird und die (eine) Periodendauer in> Zählerschritten gesucht ist, dann kann man doch die Gesamtzahl durch die> Zahl der Perioden teilen und erhält wie viele Zählerschritte eine> Periode im durchschnitt dauert.
Stimmt schon: wenn man die Dauer einer Periode in Zählerschritten wissen
will, dann kann man hundert Perioden ausmessen und dann den Zählerstand
durch 100 dividieren. Aber das wird nur dann genauer als die Messung
einer einzelnen Periode, wenn man nach der Division auch die
Nachkommastellen betrachtet. Wenn man die ignoriert ("die restlichen
Stellen abschneidet") dann wird die Messgenauigkeit nicht höher als bei
der Messung einer einzelnen Periode.
Einen Vorteil hätte dieser Ansatz nur dann, wenn die einzelnen
Periodendauern variieren und er den Mittelwert der Periodendauer
bestimmen will. Das ist aber etwas anderes als "die Genauigkeit der
Periodenmessung erhöhen".
Und genau das nehme ich an, dass die Perioden leicht in ihrer Länge
variieren und er eben einen Durchschnitt bilden will.
Für etwas anderes macht was tatsächlich keinen Sinn.
Lothar Miller schrieb:> Fellap schrieb:>> Ich moechte die Periode von einem Takt bestimmen... damit die Bestimmung>> genauer wird, wollte ich anstatt einer Periode, 100 Perioden zaehlen...> Du hast damit immer noch nicht meine Fragen beantwortet. Du siehst das> Problem zu fokussiert und nimmst das Drumrum nicht wahr...>> WARUM machst du das Ganze? WAS für ein Gerät soll das geben? Einen> Frequenzmesser, der die Frequenz dann anzeigt? ODer wird dieser Wert> nicht für irgendeine Anzeige verwendet? Falls das so ist: WER braucht> diesen Wert und wie kommt er dort hin?
Genau so ist es.. Ich habe Eingangssignal, das anfangs paar Sekunden
eine konstante Frequenz hat. Und von diesem Eingangssignal moechte ich
gerne die Periodendauer bestimmen. Und wenn man anstatt eine Periode,
mehrere Perioden misst, dann wird es ja genauer.. - klar. Und dann würde
ich gerne die Periodendauer in us auf 4x 7Segmentanzeigen anzeigen
lassen... Dazu verwende, ich das von Dir bereitgestellten Bitvektor ->
BCD Wandler...
Aber dein BCD Wandler gibt "nur" die Moeglichkeit 16 Bit einzulesen und
diese als BCD auszugeben.. und mir fehlen die Skills um zu erweitern...
Drum moechte ich gerne die Vektor kuerzen.
Schlumpf schrieb:> Fellap schrieb:>> 100 Perioden zaehlen...>> Deswegen moechte ich durch 100 teilen... bzw. die nullen abschneiden...>> Du bist gut beraten, wenn du in einem digitalen System bei sowas deine> Grenzen auf 2er Potenzen legst.> Ob du nun 100 oder 128 Perioden zählst, sollte vom Prinzip ja egal sein.> Mit dem kleinen Unterschied, dass eine Division mit 128 viel einfacher> ist.>> Du willst also messen, wie lange 100 Taktperioden dauern. Sprich, du> zählst lässt einen schnellen Zähler x laufen und mit einem anderen> Zähler zählst du 100 Perioden von deinem zu messenden Signal. Nach 100> Perioden dividierst du dann den Zählerstand von x mit 100 und hast deine> gemittelte Periodendauer der letzten 100 Takte. Richtig?>> Wenn das so ist, dann zähle doch einfach nicht 100 sondern 128 Perioden> lang.> Dann musst x nicht durch 100, sondern durch 128 teilen und das ist> trivial
Ganz genau so ist es.
Ja klar, wenn das so einfach ist kann ich den Zaehler 128 Perioden
zaehlen lassen.. Aber wie funktioniert dann ein solcher trivialer 128er
Teiler?
Fellap schrieb:> Aber wie funktioniert dann ein solcher trivialer 128er Teiler?
So: ergebnis <= wert/128;
Und was passiert da in der Hardware?
Es werden nur die untersten 7 Bit des Zählers nicht verwendet. Fertig.
Lothar Miller schrieb:> Fellap schrieb:>> Aber wie funktioniert dann ein solcher trivialer 128er Teiler?> So: ergebnis <= wert/128;> Und was passiert da in der Hardware?> Es werden nur die untersten 7 Bit des Zählers nicht verwendet. Fertig.
Das ist tatsaechlich trivial. Super - vielen Dank!
Lothar Miller schrieb:> Fellap schrieb:>> Aber wie funktioniert dann ein solcher trivialer 128er Teiler?> So: ergebnis <= wert/128;> Und was passiert da in der Hardware?> Es werden nur die untersten 7 Bit des Zählers nicht verwendet. Fertig.
Aber eine doofe Frage habe ich noch:
Muss ich dann den Zaehler bis 128 oder bis 127 zaehlen lassen?
Fellap schrieb:> Ich habe Eingangssignal, das anfangs paar Sekunden> eine konstante Frequenz hat. Und von diesem Eingangssignal moechte ich> gerne die Periodendauer bestimmen. Und wenn man anstatt eine Periode,> mehrere Perioden misst, dann wird es ja genauer.. - klar.
Machen wir mal ein einfaches Zahlenbeispiel: dein Referenztakt hat 10ns
Periode, das Eingangssignal hat genau 1300ns Periode. Wenn du nur eine
Periode ausmisst ist dein Zählerstand danach 130 +1/-1 (also entweder
131 oder 130 oder 129). Dein Fehlerbereich wird +1/-1 betragen.
Wenn du 100 Perioden des Eingangssignals misst, dann ist dein
Zählerstand danach 13000 +1/-1. (13001, 13000 oder 12999). Wenn du davon
die letzten beiden Stellen abschneidest bleibt als Ergebnis 130 oder
129. Der Fehlerbereich beträgt +0/-1. Ist das die Genauigkeitserhöhung,
die erwartest?
Betrachten wir jetzt mal ein Eingangssignal von 1305ns Periode. Misst du
eine Periode aus, dann ist der Zahlerstand danach 131 oder 130. Misst du
stattdessen 100 Perioden aus, dann ist der Zählerstand danach 13051,
13050 oder 13049. Schneide die letzten beiden Stellen ab und das
Ergebnis ist immer 130. Da war die Messung einer einzelnen Periode mit
ihrem zufälligen Springen zwischen 130 und 131 näher am richtigen Wert
dran.
Wenn du nur x Stellen zur Anzeige nutzen kannst, dann bringt es dir
keine höhere Genauigkeit, x+2 Stellen auszuzählen und danach die letzten
beiden Stellen zu ignorieren.
Lothar Miller schrieb:> Fellap schrieb:>> Aber wie funktioniert dann ein solcher trivialer 128er Teiler?> So: ergebnis <= wert/128;> Und was passiert da in der Hardware?> Es werden nur die untersten 7 Bit des Zählers nicht verwendet. Fertig.
Aber eine doofe Frage habe ich noch:
Muss ich dann den Zaehler bis 128 oder bis 127 zaehlen lassen?
Achim S. schrieb:> Fellap schrieb:>> Ich habe Eingangssignal, das anfangs paar Sekunden>> eine konstante Frequenz hat. Und von diesem Eingangssignal moechte ich>> gerne die Periodendauer bestimmen. Und wenn man anstatt eine Periode,>> mehrere Perioden misst, dann wird es ja genauer.. - klar.>> Machen wir mal ein einfaches Zahlenbeispiel: dein Referenztakt hat 10ns> Periode, das Eingangssignal hat genau 1300ns Periode. Wenn du nur eine> Periode ausmisst ist dein Zählerstand danach 130 +1/-1 (also entweder> 131 oder 130 oder 129). Dein Fehlerbereich wird +1/-1 betragen.>> Wenn du 100 Perioden des Eingangssignals misst, dann ist dein> Zählerstand danach 13000 +1/-1. (13001, 13000 oder 12999). Wenn du davon> die letzten beiden Stellen abschneidest bleibt als Ergebnis 130 oder> 129. Der Fehlerbereich beträgt +0/-1. Ist das die Genauigkeitserhöhung,> die erwartest?>> Betrachten wir jetzt mal ein Eingangssignal von 1305ns Periode. Misst du> eine Periode aus, dann ist der Zahlerstand danach 131 oder 130. Misst du> stattdessen 100 Perioden aus, dann ist der Zählerstand danach 13051,> 13050 oder 13049. Schneide die letzten beiden Stellen ab und das> Ergebnis ist immer 130. Da war die Messung einer einzelnen Periode mit> ihrem zufälligen Springen zwischen 130 und 131 näher am richtigen Wert> dran.>> Wenn du nur x Stellen zur Anzeige nutzen kannst, dann bringt es dir> keine höhere Genauigkeit, x+2 Stellen auszuzählen und danach die letzten> beiden Stellen zu ignorieren.
Oh.. ja ok.. verstehe... Danke Dir... Dann mache ich das nun doch
anders..
Gustl Buheitel schrieb:> Wenn 100 Perioden lang gezählt wird und die (eine) Periodendauer in> Zählerschritten gesucht ist, dann kann man doch die Gesamtzahl durch die> Zahl der Perioden teilen und erhält wie viele Zählerschritte eine> Periode im durchschnitt dauert. Oder verstehe ich da was nicht?! Der> Zähler sollte natürlich deutlich schneller wie die zu bestimmende> Frequenz sein.
Ich bezweifle, das das genauer wird als eine Periode des Referenztaktes,
da man das zu messende Signal mit dem Referenztakt einsynchronisiert.
Dadurch entsteht ein Fehler von höchstens einer Referenz-Periode
(setup/Hold verletzung), sehr unwahrscheinlich zwei Perioden. Dieser
Fehler ist weniger von der tatsächlichen Frequenz des Messsignlas
abhängig, als von dem Setup/Hold Fenster und statistischen
Wahrscheinlichkeiten was bei einer Setup/Holdverletzung eintritt.
Fellap schrieb:> Muss ich dann den Zaehler bis 128 oder bis 127 zaehlen lassen?
Du musst 128 Zyklen zählen. Im Normalfall wird das erreicht, indem ein
Zähler von 0..127 zählt.
Nimm mal zum Nachdenken einfach eine kleinere Zahl: Wenn ein Zähler
von 0 bis 3 zählt (also 0, 1, 2, 3) wieviele Schritte sind das dann?
Lothar Miller schrieb:> Fellap schrieb:>> Muss ich dann den Zaehler bis 128 oder bis 127 zaehlen lassen?> Du musst 128 Zyklen zählen. Im Normalfall wird das erreicht, indem ein> Zähler von 0..127 zählt.> Nimm mal zum Nachdenken einfach eine kleinere Zahl: Wenn ein Zähler> von 0 bis 3 zählt (also 0, 1, 2, 3) wieviele Schritte sind das dann?
4.. Haha... verstehe.. :) danke!
@ Fpga Kuechle:
Ja, klar stimmt das es wird nicht genauer, aber ich vermute er will die
Periode von irgendeinem Signal bestimmen das von aussen reinkommt und
nicht immer die gleiche Periodendauer hat. Also so wie wenn ich da Audio
habe das ich ueber das Micro aufnehme, auch wenn der Lautsprecher vorher
einen schoenen 1kHz Sinus bekommen hat, ist das hinter dem Micro eben
ziemlich unsauber. Ich vermute daher, dass es um eine Mittelwertbildung
geht, etwas anderes hat wirklich keinen Sinn, da soll er lieber
schneller zaehlen.