Hallo alle zusammen,
ich habe folgende Frage: Ich habe als Input 2 Integer und als Output
will ich ein Float (2 stellen nach dem Koma).
Ich habe mich schon in Internet Erkundigt und hier auch mehrere Foren
Einträge mir angeschaut.
Ist dies die Einzige Möglichkeit? Also muss man die Zahlen(Integer)
vorher zu Signed Convertieren oder gibt es eine Möglichkeit direkt
Integer zu Teilen und da denn Output als Float zuzuweisen?
Convertierung:
signal input_3 : integer;
signal output_3 : signed(3 downto 0);
output_3 <= to_signed(input_3, output_3'length);
Quelle:
https://stackoverflow.com/questions/19161454/division-in-vhdl-int-float?rq=1
Danke!
Ich würde sagen, dass du beides machen kannst:
Fall 1: alles in float convertieren, rechnen lassen float rausbekommen,
benutzen.
Vorteil: Höchste Genauigkeit bei definierter Bitbreite
Nachteil: Schweinegross und Langsam
Fall 2: Alles in INT belassen, auf benötigte Genauigkeit aufbohren,
rechnen lassen, INT erhalten, in float konvertieren
Vorteil: Minimaler Platz- und Rechenbedarf
Nachteil: Berechnungsabhängige Breite der Vektoren und Anforderung an
Gehirnschmalz
Praktisch rechnet man in FPGAs IMMER in INT, es sei denn man kriegt
alles in float und muss es auch wieder so abliefern, z.B. an eine CPU.
P.S. Division in Float ist in VHDL wirklich saulangsam und umständlich.
Binäre DIV nach schriftlichem Dividieren ist hingegen hoch effektiv und
klein.
VHDL-Polizei schrieb im Beitrag #6968049:
> P.S. Division in Float ist in VHDL wirklich saulangsam und umständlich.
Wenns nur für den Simulator ist...
Manah schrieb:> oder gibt es eine Möglichkeit direkt Integer zu Teilen> und da denn Output als Float zuzuweisen?
Kannst du machen, nach der Integer-Division sind dann aber natürlich die
Nachkommastellen weg.
> Ich habe als Input 2 Integer und als Output will ich ein Float
Soll das auf Hardware laufen? für eine simple Anzeige? Dann vergiss
float ganz schnell.
Denn eigentlich willst du nicht in float rechnen, sondern du willst
lediglich
> (2 stellen nach dem Koma).
Also mach es so: rechne einfach alles in Integer und "um den Faktor 100
zu groß" und dann denkst du dir zwischen die 10er und die 100er-Stelle
ein Komma.
Deiser Ansatz nennt sich übrigens "Festkommaarithmetik".
BTW: warum beschreibst du nicht einfach die eigentliche Aufgabe? Mit
Angaben zu Toolchain und Hardwareplattform undsoweiterundsofort...
Danke für die ganzen Antworten!
ich will eigentlich nur eine Konstante 30/eine sich je Takt Zyklus
ändernde zahl teilen (die ist in integer). Aber das Ergebnis ist
höchstwahrscheinlich ein Float.
Ich brauche eine Genauigkeit von 2 nach Komma stellen.
Lothar M. schrieb:> Kannst du machen, nach der Integer-Division sind dann aber natürlich die> Nachkommastellen weg.
Die Nachkommastellen sind natürlich in INT so zu bemessen, dass sie
ausreichend genau sind. Also für A = 16 Bit / B = 16 Bit -> 0...1 , wenn
B auch kleiner sein kann, als 1, dann hat das Ergebnis z.B. 16 Vorkomma
und 16-Nachkommastellen ->
Y = ( K * A ) / B mit K =16 -> (15 downto 0).(15 downto 0).
Das Ergebnis ist dann auf 1/32768 genau und muss auf mindestens 32 Bit
skaliert werden, um es an float zu übergeben. Kann aber auch sein, dass
die Ergbnisse so aussehen, dass der Wert immer zwischen 0 und 1 liegt,
gfs reichen dann 24 Bit Nachkommastellen und man hat es direkt in float.
ich will das Ergebnis später in einer 7-Seg anzeige darstellen, ein
Array eignet sich wunderbar dafür, aber gibt es eine Möglichkeit, wenn
das Ergebnis als integer vorliegt zb 12545 integer in ein array zu
packen (1,2,5,4,5)?
Wenn das möglich ist würde ich das machen:
Also mach es so: rechne einfach alles in Integer und "um den Faktor 100
zu groß" und dann denkst du dir zwischen die 10er und die 100er-Stelle
ein Komma.
Deiser Ansatz nennt sich übrigens "Festkommaarithmetik".
Manah schrieb:> Aber das Ergebnis ist höchstwahrscheinlich ein Float.
Nein. Die Lösung lässt sich in 99% der Fälle ohne float finden.
Du willst auf realer Hardware (z.B. ein FPGA) solche einfache
Grundrechnugen sicher nicht in float lösen. Auch wenn das beim Arduino
(oder sonst einem µC) in einer Hochsprache "so nebenher" geht: in
Hardware gegossen ist ein float ein richtig großer und schwerer Koffer.
Den packt man nicht für 2 simple Nachkommastellen raus.
> 30/x> Ich brauche eine Genauigkeit von 2 nach Komma stellen.
Wie gesagt, dann rechne einfach: 3000/x und dann denk dir zwischen die
3. und 2. letzte Stelle ein Komma.
Und nochmal das Stichwort: Festkommaarithmetik
So sieht z.B. eine Division in VHDL aus:
http://www.lothar-miller.de/s9y/categories/24-RechnenManah schrieb:> aber gibt es eine Möglichkeit, wenn das Ergebnis als integer vorliegt> zb 12545 integer in ein array zu packen (1,2,5,4,5)?
Du kannst die Integerzahl (also einen binären Vektor) in eine BCD-Zahl
wandeln und die einzelnen Stellen dann darstellen.
http://www.lothar-miller.de/s9y/categories/44-BCD-Umwandlung
BTW: Du denkst in Software. Das geht schief.
Ich führe eine bestimmte Rechnung aus, dass Funktioniert auch alles.
Das was ich benötige um fertig zu werden ist folgendes:
30/Integer* => erg
erg will ich in ein 7-Segment Display auf ein VHDL Board(DE10-Lite)
packen, da will ich das Ergebnis als Array, da die 7-Seg Anzeige keinen
Multiplexer hat und ich jedes einzelne Segment ansprechen muss.
*Integer,denn mir mein vorheriger Code ausgibt.
Lothar M. schrieb:> http://www.lothar-miller.de/s9y/categories/44-BCD-Umwandlung
danke für denn link, ich schaue es mir mal genau an, ich werde dann
folgendes machen:
1) (Die Berechnung(Division) in Integer)*100
2) Das Ergebnis der Division in STD_Logic_Vector Convertieren
3) dann wie in oben genannten Link die STD_Logic_Vector in hex -> BCD
->* 7-Seg
* Beim übergeben, denn Blinker der DP immer auf 0
aber mein Ausgabe Vector muss 42 downto 0 lang sein, da kein
multiplexer.
Manah schrieb:> 30/Integer* => erg>> erg will ich in ein 7-Segment Display auf ein VHDL Board(DE10-Lite)> packen, da will ich das Ergebnis als Array, da die 7-Seg Anzeige keinen> Multiplexer hat und ich jedes einzelne Segment ansprechen muss.
Also rechne einfach 3000/Integer* => erg, stelle das erg auf der Anzeige
dar und dann nimm einen Lötkolben und löte den Punkt der
7-Segmentanzeige zwischen der 3. und 2. Stelle von rechts so, dass er
leuchtet.
Also Beispiel zum Mitrechnen:
30/14 = 2.14
Rechne
3000/14 = 214 --> mach den Punkt rein: 2.14
Fertig.
Manah schrieb:> aber mein Ausgabe Vector muss 42 downto 0 lang sein
Seltsamer Vektor mit 43 Bits Breite... Naja, seis drum. Vermutlich ist
der Vektor doch nur (41 downto 0).
Das musst du dann halt passend hinbiegen. Denn von der BCD-Zahl mit 4
Bit pro Stelle musst du ja auf deine 7 (oder 8) Bits pro Stelle kommen.
Und eben dann den Punkt an der richtigen Stelle anschalten.
Meine frage, wie sieht denn der std_vector aus?
Wenn ich ein Integer zu std_vector convertiere, kann ich dann jede
einzelne Zahl einzeln ansprechen?
std_vector(pos5), also kann man da mit indizes arbeiten?
532 integer -> std_vector => (101,11,10) oder ist das (1000010100)?
Manah schrieb:> Wenn ich ein Integer zu std_vector convertiere, kann ich dann jede> einzelne Zahl einzeln ansprechen?
Du verwechselst hier Zahl mit Ziffer oder Stelle in einem
Stellenwertsystem.
Manah schrieb:> 532 integer -> std_vector => (101,11,10) oder ist das (1000010100)?
532 im Dezimalsystem wird im Binärsystem zu 1000010100. Und genau wie im
Dezimalsystem kannst du jede Stelle einzeln ansprechen. Nur hat die Zahl
im Dezimalsystem eben 3 Stellen, im Binärsystem aber 10 Stellen.
Du kannst also nicht mehr die 5, 3 oder 2 "ansprechen", dafür aber die
1, die 0, die 1 oder auch nochmal die 0.
Der Weg wäre:
532 zerlegen in seine Stellen 5, 3 und 2 und diese dann einzeln in 7
Segment Vektoren wandeln.
Wie kann man 532 in seine Stellen zerlegen? Wenn man viele Takte Zeit
hat geht das mit Zählern. Einer für die Einer, einen für die Zehner und
einen für die Hunderter, jeweils mit Überlauf zum nächsten Zähler.
Kostet dich bei 532 eben auch 532 Takte.
Am Ende hat du die einzelnen Stellen/Ziffern der Dezimalzahl als 4 Bit
Binärwert, denn zum Darstellen der Zahlen 0 ... 9 benötigt man 4 Bits.
Und von den 4 Bit Werten nach 7 Segment ist es eine einfache
Abbildung/Zuordnung, geht aber auch mit ein paar Logikgattern.
Edit:
Die Lösung mit den Zählern ist fertig und im Anhang. Hier jetzt für 3
Dezimalstellen. Also Zahlen von 0 ... 999.
Manah schrieb:> Lothar M. schrieb:>> BTW: Du denkst in Software. Das geht schief.>> hahaha ja da hast du recht, ich schreibe normalerweise in c/c++ und> python :D
Warum nimmst du nicht gleich eine passende Python HDL?
MyHDL oder hwt z.B. hat eine vernünftige Fixpoint-Arithmetik, wo man
nicht umständlich in VHDL von Hand rumkodieren muss. Hinten kommt VHDL
oder Verilog raus. Float-Konversion sollte man nur dann machen, wenn's
in ein entsprechendes austauschbares Format soll.
Danke dir.
ich habe gerade die Integer Zahl fertig bekommen. Jetzt Konvertiere ich
die in Dual.
Dann werde ich das Split digit drauf anwenden.
Der letzte schritt, dann aufs Board.
Stimmt das, dass man Variablen meiden sollte?
Es gibt keinen Grund, Variablen zu vermeiden, wenn man (vollständig)
verstanden hat, wozu sie gut (und nicht gut) sind.
Im Gegenteil - man kann Code damit deutlich lesbarer gestalten.
Manah schrieb:> Stimmt das, dass man Variablen meiden sollte?
Man sollte sie dann meiden, wenn man sich nicht sicher ist, on man sie
meiden sollte... 😉
Lies dir mal den Beitrag "Variable vs Signal" durch.
Wenn du das da drin verstanden hast, dann ist es egal was du nimmst.
Manah schrieb:> ich habe gerade die Integer Zahl fertig bekommen. Jetzt Konvertiere ich> die in Dual.
Wie sieht diese "Integerzahl" zb. für den Wert 159 denn aus? Etwa so:
000101011001?
Okan M. schrieb:> Ich würde split digits nutzen aber vorher muss ich unsigned zum> std_logic_vector(9 downto 0); Konvertieren.
Nein, casten. Da ändert sich an den Bits nichts. Mit signed oder
unsigned wird nur mitgeteilt als was der Vektor interpretiert werden
soll.
Okan M. schrieb:> Codeansicht> Warum brauche ich das?
Du hast den Code gelesen?
Das funktioniert über Zähler, der Zähler muss also je nach
Implementierung zu einem Zeitpunkt geladen oder Zurückgesetzt werden.
Dafür ist das Start Signal da. Und auch das Busy ist wichtig denn erst
wenn das wieder low ist, dann liegt das korrekte Ergebnis am Ausgang an.
danke für die schnelle Rückmeldung.
Ja ich habe denn code gelesen, ich bin nicht so die leuchte.... ich fand
die stelle sehr kompliziert.
<= '1' when i_start = '1' or s_counter > 0 else '0';
ich habe noch eine frage...
https://www2.cs.sfu.ca/~ggbaker/reference/std_logic/1164/std_logic_vector.html
heißt das, ich kann die einzelnen bits in einem std_logic_vector
ansprechen?
x("010")
x(0) = ("0")
x(1) = ("1")
x(2) = ("0")
oder geht das nur mit array?
Ich habe in verschiedenen foren gelsen, dass man dies in ein array
konvertiren muss mit einem for loop und man erst dann die einzellen bits
ansprechen kann.
Okan M. schrieb:> x(0) = ("0")> x(1) = ("1")> x(2) = ("0")
Korrekt ist es so:
x(0) = '0'
x(1) = '1'
x(2) = '0'
Denn Achtung:
"0" ist nicht das selbe wie '0'
Okan M. schrieb:> ich fand> die stelle sehr kompliziert.>> <= '1' when i_start = '1' or s_counter > 0 else '0';
Das ist nur eine andere Schreibweise für 'if'.
Außerhalb von Prozessen ist 'if' nicht nutzbar.
Im Prozess würde das so aussehen:
Hallo alle,
Ich bin auf Ihren Code gestoßen. Könnten Sie mir eventuell ein paar
stellen erklären?
Division in VHDL - Lothar Miller (lothar-miller.de)
Warum benötige ich ein Start Signal?
Gestartet wird die Division, nachdem der Dividend und der Divisor
zugewiesen wurden, mit dem Signal start='1'. Es reicht aus, wenn Start
für einen Taktzyklus aktiv ist
Also wie müsste der ankommen?
Wenn ich eine Division „will“ oder reicht es auf wenn ich da eine clock
anschließe?
Die selbe frage gilt für Busy.
Ich benötige eine Division, die ein Integer/Konstante(Integer teilt)
Mein Ansatz, ich habe zum Debuggen 2 Konstante benutzt, aber die geben
mir in der TB auch ein „UUUUUUU…“ als Ergebnis.
1
libraryieee;
2
useieee.std_logic_1164.all;
3
useieee.numeric_std.all;
4
entityDivisionis
5
port
6
(
7
t:inINTEGER;
8
v:outunsigned(19downto0);
9
v_std:outstd_logic_vector(19downto0)
10
11
);
12
endentity;
13
14
ARCHITECTURErtlOFDivisionIS
15
signalv_tmp:unsigned(19downto0);
16
17
BEGIN
18
19
Division:PROCESS(t)
20
21
VARIABLEt_tmp:unsigned(19downto0);
22
VARIABLEt_100:INTEGER;
23
VARIABLEDurchmesser:INTEGER;
24
VARIABLEDurchmesser_tmp:unsigned(19downto0);
25
26
BEGIN
27
Durchmesser:=2199;-- radius = 3.5cm // (r pi 2)*100
Okan M. schrieb:> Warum benötige ich ein Start Signal?
Sieh dir in der Simulation an, was der Code dort macht: es wird eine
Zahl binär Bit für Bit geteilt wie man es bei den binären
Grundrechenarten lernt.
Denn ein simples c<=a/b kann in der Hardware nur dann effizient
umgesetzt werden, wenn b eine Zweierpotenz ist. Sieh dir das Handbuch
des Synthesizers an. Dort steht drin was der tatsächlich von VHDL in
Hardware abbilden kann.
Lothar M. schrieb:> Denn ein simples c<=a/b kann in der Hardware nur dann effizient> umgesetzt werden, wenn b eine Zweierpotenz ist.
Die Aussage ist zwar richtig, führt den TO (vielleicht) auch zur Lösung,
aber nicht zum Verständnis.
Das ist wie wenn man behaupten würde "die Division kann vom Grundschüler
nur dann effizient umgesetzt werden, wenn durch 10 geteilt wird".
Tatsächlich ist die Multiplikation/Division einer Zahl in
Binärdarstellung mit 2 durch Hinzufügen bzw. Weglassen einer Stelle am
rechten Ende nur eine Abkürzung, die durch die Wahl der
Zahlendarstellung ermöglicht wird. Beim Rechnen im Zehnersystem machen
wir das ja genauso:
150 / 10 = 15 (rechts einfach eine Stelle weglassen)
Entsprechende "Abkürzungen" sind auch bei anderen Zahlensystemen
möglich:
oktal (Teilen durch 8er-Potenzen):
142 (98) / 10 (8) = 14 (12)
sedezimal (Teilen durch 16er-Potenzen):
FE (254) / 10 (16) = F (15)
Wenn wir ein 1,27381er - Zahlensystem hätten, könnten wir also ganz
einfach und schnell durch 1,27381 teilen (täten uns aber naturgemäss mit
anderen Teilern schwer).
Die Vorgehensweise ist elementar für das Verständis von
Zahlendarstellung und mir unverständlich, warum man anscheinend
teilweise meint, Grundschülern das schriftliche Dividieren nicht mehr
beibringen zu müssen, weil es ja Taschenrechner gibt. Wir "alten Säcke"
haben das intensiv gelernt und benutzt, deswegen ist das für uns
"einfach logisch".
Das ist nicht selbstverständlich.
Markus F. schrieb:> das schriftliche Dividieren
Das ist der eigentliche Trick zum Verstehen meines Codes: man muss
einfach mal die schriftliche Division zweier Binärzahlen auf einem Blatt
Papier verstanden haben. Dann ist klar, was der Code macht: es wird
Binärstelle für Binärstelle abgearbeitet. Genauso wie man eben bei de
schriftlichen Division zweier Dezimalzahlen eben Dezimalstelle für
Dezimalstelle abarbeitet.
Und genauso wie man eine schriftliche Division auf einem Blatt Papier
vorbereiten und dann "starten" muss, um nach einigen Berechnungen zum
"Ende" zu kommen, genauso muss man es in der Hardware machen: Dividend
und Divisor bereitstellen, die Rechnung "starten" und warten,solange die
Rechnung noch andauert.
Länger Rede kurzer Sinn: in VHDL einfach nur ein c<=a/b hinzuschreiben
ist ein berechtigter Kündigungsgrund.
Der Fall hier ist zudem eins Division durch eine Konstante 50, die in
Hardware (auf 5 Dezimalstellen genau) als Multiplikation mit 41 und
anschließender "Division" durch 2048 darstellbar ist:
x/50 = x * 1/50 = x * 41/2048, also x * 41 und die unteren 11 Bits
ignorieren.
Wenn die 5 Dezimalstellen nicht reichen, dann muss man einfach ein paar
Bit mehr zugeben und so rechnen: X * 5243/262144, also x * 5243 und die
unteren 18 Bits ignorieren.
ich habe versucht die Division von Division in VHDL - Lothar Miller
(lothar-miller.de) zu benutzen. Bekomme das nicht hin, weil ich
folgendes Problem habe.
Ich will Seconds in ein std_logic_vector Konvertieren. Habe dafür ein
Identisches input gebaut.
Ich bekomme einen Falschen Wert nach der Konvertierung, und folgende
Fehlermledung: "** Error: (vsim-86) Argument value -2147483647 is not in
bounds of subtype NATURAL."
Die Fehlermeldung in TB tritt aber nur an denn Stellen auf, wo ich kein
Signal mehr bekomme (also nach dem der Durchlauf Fertig war), das ist
auch gewollt so.
Ich denke also nicht das der Fehler Relevant ist.
Habe versehentlich ein älteren Screenshot angehangen. Der Relevante
Screenshot ist div.png.
Okan M. schrieb:> Ich will Seconds in ein std_logic_vector Konvertieren.
Beschreibe doch einfach mal die eigentliche Aufgabe und eben NICHT wie
du sie lösen willst.
Also ganz einfach: wie lautet die ursprüngliche Hausaufgabe? Was sollst
du machen? Eine (Stopp-)Uhr auf 7-Segment-Anzeigen?
Okan M. schrieb:> Die Fehlermeldung in TB tritt aber nur an denn Stellen auf, wo ich kein> Signal mehr bekomme
Im echten Leben auf echter Hardware gibt es das eben nicht, dass du
"kein Signal mehr bekommst", denn die Leitungen im FPGA haben immer
irgendeinen Signalpegel.
Deine Denkweise ist ganz extrem prozedural, wie z.B. bei einem
Softwareprogramm. So funktioniert HardwareBESCHREIBUNG nicht! Sondern du
musst eine Schaltung im Kopf haben und die dann mit der
HardwareBESCHREIBUNGssprache VHDL so beschreiben, dass der Synthesizer
aus deiner Beschreibung wieder die von dir ausgedachte Schaltung im FPGA
erzeugen kann.
Es wird bitter schiefgehen, wenn du mit VHDL programmieren willst.
> Seconds : inout integer
Aus reiner Gedankenlosigkeit oder Schreibfaulheit inout Ports zu
verwenden, wo eigentlich out oder in korrekt wäre, ist für mich ein
plausibler Grund für eine fristlose Kündigung.
Zudem bekommt man damit gern mal ganz eigenartige Effekte mit multiplen
Treibern.
Meine Aufgabe ist es, mit einem Hall-Sensor die Geschwindigkeit zu
messen. Ich habe ein Magneten und einen Sensor.
Die Geschwindigkeit soll ich dann in kmh auf einer 7-Seg Anzeige
darstellen.
Ich habe bereits mit Seconds die Zeit, wie lange es für eine Umdrehung
braucht. denn Umfang habe ich auch. Der ist eine Konstante von 30cm.
Ich will als vorletzten schritt nur noch:
v = s/t
s die konstante von 30cm
t die zeit die mir meine VHDL - Datei stopuhr zur Verfügung stellt.
Okan M. schrieb:> Die Geschwindigkeit soll ich dann> in kmh auf einer 7-Seg Anzeige darstellen.
Nach kurzem Nachdenken komme ich zur Idee, dass 3333 U/h einer
Geschwindigkeit von 1km/h = 1km/3600s entsprechen. Man muss also nur die
Umdrehungsimpulse zählen, die in der Zeit 3333/3600 = 0,926 Sekunden
hereinkommen und hat damit schon die gewünschte Geschwindigkeit in km/h.
Und durch diese Zählung der sich ändernden Anzahl der Impulse pro
konstanter Zeit erspare ich mir durch die geschickte Skalierung mit
926ms 1. jegliche Umrechnung und 2. die Division, die ich brauche, wenn
ich eine konstante Impulszahl durch eine sich ändernde Zeit teilen muss.
Kannst du das näher Erläutern bitte,
was meinst du mit Umdrehungsimpulse.
Ich habe bereits ein Counter, welche mir als std_logic immer dann eine 1
liefert, wenn eine Umdrehung durch ist.
Lothar M. schrieb:> Man muss also nur die> Umdrehungsimpulse zählen, die in der Zeit 3333/3600 = 0,926 Sekunden> hereinkommen und hat damit schon die gewünschte Geschwindigkeit in km/h.
Ja, aber eben auch extrem ungenau, also ohne Nachkommastellen. Und wenn
mit dieser Methde von sagen wir 0 bis 100 km/h messen können will, dann
bekommt er nur alle 92,6 Sekunden einen neuen Messwert.
Aber auch hier im Thread genauso wie bei den eMail mangelt es an
Details. Welche Frequenz oder welchen Frequenzbereich wird das Signal
vom Sensor haben? Ist das ein Rechteck? Muss das entprellt werden?
Okan M. schrieb:> Ich habe bereits mit Seconds die Zeit, wie lange es für eine Umdrehung> braucht.
Nein, das liefern deine Komponenten nicht. Simuliere die doch einzeln
und gucke ob die wirklich das tun was du von ihnen erwartest. Sekunden
ist auch eine Einheit die zu grob ist um Nachkommastellen bei der
Geschwindigkeit zu bekommen, so wird das eine ungenaue Messung.
Okan M. schrieb:> was meinst du mit Umdrehungsimpulse.
Die liefert dein Sensor. Weitere Dateils zu deinem Signal S_1 willst du
ja nicht preisgeben. Aber mehr Details wären wichtig - vor allem für
dich selbst. Guck das mal mit dem Oszi an (vor allem die Flanken), mach
eine Abschätzung wie schnell sich das maximal dreht, ...
Gustl B. schrieb:> Ja, aber eben auch extrem ungenau, also ohne Nachkommastellen.
Ja, das macht mein Tacho im Auto auch. Und ich sehe keine Forderung,
dass Nachkommastellen angezeigt werden müssten.
Und (um im Konjunktiv zu bleiben) falls das der Fall wäre, dann würde
ich dafür sorgen, dass das Rad mehr Impulse pro Sekunde ausgeben würde
> Und wenn mit dieser Methde von sagen wir 0 bis 100 km/h messen können> will, dann bekommt er nur alle 92,6 Sekunden einen neuen Messwert.
Nein, er bekommt immer nach 926ms einen neuen km/h Wert. Denn wenn sich
das Rad in diesen 926ms einmal dreht, dann fährt er 1km/h, wenn es sich
5x dreht, dann sind es 5km/h.
> Und wenn mit dieser Methde von sagen wir 0 bis 100 km/h messen können> will, dann bekommt er nur alle 92,6 Sekunden einen neuen Messwert.
Wenn er mit diese Methode und nur 1 Impuls pro Umdrehung auf 2
Nachkommastellen auflösen möchte, dann muss er 100x926ms messen.
Alternativ kann man z.B. ein Zahnrad mit 100 Zähnen als Impulsgeber
verwenden und kann wieder in 926ms auf 2 Nachkommastellen genau messen.
Und wenn ich die Kehrwertmethode (also Dauer von Impuls zu Impuls
umrechnen in km/h) nehmen müsste, dann würde ich mit einer Tabelle samt
Interpolation arbeiten.
Lothar M. schrieb:> Nein, er bekommt immer nach 926ms einen neuen km/h Wert. Denn wenn sich> das Rad in diesen 926ms einmal dreht, dann fährt er 1km/h, wenn es sich> 5x dreht, dann sind es 5km/h.
Stimmt, das war dumm von mir.
Lothar M. schrieb:> Alternativ kann man z.B. ein Zahnrad mit 100 Zähnen als Impulsgeber> verwenden und kann wieder in 926ms auf 2 Nachkommastellen genau messen.Lothar M. schrieb:> Und (um im Konjunktiv zu bleiben) falls das der Fall wäre, dann würde> ich dafür sorgen, dass das Rad mehr Impulse pro Sekunde ausgeben würde
Alles gute Ideen.
Ich habe jedes Detail preis gegeben, es ist ein Hallsensor, der mir eine
0 oder 1 liefert, sobald er einen Magneten entdeckt.
Board: De10 lite
Der Name des Sensors: Hall Magnetic Field Sensor KY-003
Ich wollte es so simpel wie möglich für mich machen. ich wollte die Zeit
stoppen zwischen der ersten Entdeckung und der letzten Entdeckung.
Dann über die folgende Formel lösen.
v = s/t
Was für Details benötigt Ihr noch?
Okan M. schrieb:> der mir eine> 0 oder 1 liefert, sobald er einen Magneten entdeckt.
Und du glaubst dass es da eine harte Grenze gibt zwischen "Magnet da"
und "kein Magnet da"?
Wenn da der Magnet in die Nähe kommt kann es sehr gut sein, dass der
Sensor - das ist übrigens der hier
https://www.elecrow.com/download/A3141-2-3-4-Datasheet.pdf - nicht einen
schönen 00000000011111111111 Übergang liefert, sondern eher sowas
0000001001010111011110111111111111. Um das herauszufinden könntest du
dir das mal mit einem Oszilloskop oder Logikanalysator angucken.
Okan M. schrieb:> Board: De10 lite
Das macht schonmal das mit den Segmenten einfach, denn die sind alle
einzeln an das FPGA angeschlossen. Du muss also nicht multiplexen.
Okan M. schrieb:> ich wollte die Zeit> stoppen zwischen der ersten Entdeckung und der letzten Entdeckung.Okan M. schrieb:> Was für Details benötigt Ihr noch?
Um herauszufinden was denn der einfachste Weg ist wäre es gut zu wissen
mit welchem Wertebereich du rechnest oder welchen Wertebereich du
anzeichen können möchtest. Genau danach hatte ich mehrmals gefragt.
Minimum sind natürlich 0 Pulse. Aber was ist die maximale Pulsrate oder
die maximale Geschwindigkeit die du messen können willst?
Und was sie die Auflösung mit der du das messen willst? Reicht dir eine
Anzeige von 0 ... 999999 km/h oder willst du 0 ... 999.999 km/h oder
sogar 0 ... 9.99999 km/h? Oder noch genauer: Was ist die minimale
Umdrehungsrate die du messen können willst, was sie maximale
Umdrehungsrate?
Wie sieht es mit den Ideen von Lothar aus? Willst du mehrere Magnete am
Rad befestigen? Willst du sonst wie mehr Pulse erzeugen?
Mit diesen ganzen Details entscheidet sich was am Ende der Lösungsweg
ist.
Okan M. schrieb:> Dann über die folgende Formel lösen.> v = s/t
Ist das dein Plan oder ist das Teil der Aufgabe?
> v = s/t> s die konstante von 30cm
Du willst aber keine Geschwindigkeit in cm pro irgendwas, sondern in km
pro h.
Insofern ist die Rechnung mit 30cm nutzlos.
> t die zeit die mir meine VHDL - Datei stopuhr zur Verfügung stellt.
In welchem Format wird diese Zeit "zur Verfügung gestellt"?
> Ich wollte es so simpel wie möglich für mich machen.
Den simpelsten Weg habe ich beschrieben. Auf diese Art könnte ich die
Aufgabe mit 30 Zeilen VHDL-Code lösen.
Gustl B. schrieb:> das war dumm von mir.
Halb so schlimm, du wärst bei erneutem Nachdenken sicher schnell drauf
gekommen... 😉
Gustl B. schrieb:> nicht einen> schönen 00000000011111111111 Übergang liefert, sondern eher sowas> 0000001001010111011110111111111111. Um das herauszufinden könntest du> dir das mal mit einem Oszilloskop oder Logikanalysator angucken.
Wenn man das geschickt filtert, kann man das auch nutzen!
Okan M. schrieb:> ich hab es hinbekommen
Um anderen zu helfen (wie dir auch geholfen wurde) , wäre es jetzt
schön, wenn du deine(n) Lösung(sansatz) zeigen würdest.
Manah schrieb:> Ich führe eine bestimmte Rechnung aus,
Nö. Stattdessen willst du eine Funktionalität, die du dir vorstellst,
formulieren, um sie schlußendlich in Form von digitalen Gattern,
Flipflops und E/A-Treibern in Silizium zu gießen. So herum.
Auch hier sieht es so aus, daß gerade VHDL zu schlecht gelehrt wird, so
daß die Studenten in höheren Sphären schweben (vulgo: den Teppich unter
den Füßen verloren haben) und sich keine Gedanken machen, ob und wie
ihre Ideen sich in einem Sack von LUT's und FF's tatsächlich machen
lassen. Sicherlich lassen sich da Formulierungen finden, die syntaktisch
OK sind, aber eben leider zu nicht synthetisierbarem Zeugs führen. Und
dann fragt der Urheber des ganzen Krams, _WIESO??_ Ich habe doch alles
richtig gemacht, denn der Compiler hat mich nicht angemeckert!
W.S.