Hallo Leute,
ich habe ein kleineres Problem mit einer Konvertierungseinheit.
Kompilieren lässt sich der Code, jedoch erscheint während der Simulation
folgende Fehlermeldung:
Alexander F. schrieb:> Für deinen Fehler habe ich jetzt nichts spezielles, aber ich> vermisse gray_2_b_out und bcd_2_b_out in der Sensitivity-List vom> Prozess BCD_OR_GRAY.
Und ich vermisse low_bcd und high_bcd (die übrigens völlig
unnötigerweise im Prozess sind, die wären besser concurrent
aufgehoben)...
Oder noch besser die sechs Zeilen hier:
1
low_bcd(11downto0)<=l0;
2
low_bcd(23downto12)<=l1;
3
high_bcd(11downto0)<=h0;
4
high_bcd(23downto12)<=h1;
5
6
7
bcd_2_b_out(23downto0)<=low_bcd(23downto0);
8
bcd_2_b_out(47downto24)<=high_bcd(23downto0);
Durch diese ersetzen:
1
bcd_2_b_out<=h1&h0&l1&l0;
Stichwort: Concatenation
Aber dein eigentliches Problem dürfte von den arithmetischen Operationen
(Addition, Multiplikation) kommen, denn das Ergebnis der Rechnungen kann
ein zusätzliches Übertragsbit ergeben, das dann abgeschnitten wird.
Übrigens glaube ich noch nicht, dass die BCD nach Binär Wandlung
funktioniert. Es sei denn, du hast es im Vektor GRAY_OR_BCD_IN mit 4
dreistelligen zusammengefügten BCD-Zahlen zu tun...
was mir noch so aufgefallen ist:
* Du arbeitest z.T. mit nicht initialisierten Signalen und Variablen
* Verwendung von Variablen in nicht getakteten Prozessen: Du bringst da
sequentielle Abhaengigkeiten (noch mehr als ohnehin im process) rein die
dich bei komplexeren Sachen einholen werden. Warum nicht 'concurrent'
und evtl. 'generate' loops?
Lothar Miller schrieb:> Übrigens glaube ich noch nicht, dass die BCD nach Binär Wandlung> funktioniert. Es sei denn, du hast es im Vektor GRAY_OR_BCD_IN mit 4> dreistelligen zusammengefügten BCD-Zahlen zu tun...
Hm.. im Vektor GRAY_OR_BCD_IN sind 12 BCD Zahlen enthalten:
GRAY_OR_BCD_IN[47..44]: hoechstwertigste BCD Zahl
GRAY_OR_BCD_IN[43..40]
GRAY_OR_BCD_IN[39..36]
.
.
.
GRAY_OR_BCD_IN[3..0]: niederwertigste BCD Zahl
Lothar Miller schrieb:> Aber dein eigentliches Problem dürfte von den arithmetischen Operationen> (Addition, Multiplikation) kommen, denn das Ergebnis der Rechnungen kann> ein zusätzliches Übertragsbit ergeben, das dann abgeschnitten wird.
Glaube ich auch, gibt es da eine geschicktere Methode?
Gruß
MemY schrieb:> Hm.. im Vektor GRAY_OR_BCD_IN sind 12 BCD Zahlen enthalten:
Womit dann 1 Wert von 0..999999999999 darstellbar ist, oder womit 4
unabhängige Werte von 0..999 dargestellt werden?
Lothar Miller schrieb:> Womit dann 1 Wert von 0..999999999999 darstellbar ist
Ja, im Prinzip ein Wert 1 BCD Wert aus dem Wertebereich von
0..FFFFFFFFFFFF
MemY schrieb:> Sorry! Natürlich 1 BCD Wert aus dem Wertebereich von 0..999999999999.
Dafür braucht es dann 37 Bit Ausgabe.
Der einfache parallele Ansatz wird zum Resourcengrab.
Ausserdem programmiere das erst mal zu Fuss (d.h. ohne zuhilfenahme von
Libraryfunktionen) in C. Aber nein, man kann das C Programm dann nicht
einfach nach VHDL übersetzen, aber ohne zu verstehen wie man die Aufgabe
in Teilaufgaben zerlegt hast du in VHDL keinen Chance.
Übrigens für GRAY funktioniert das ohnehin nicht. GRAY_OR_BCD ist also
falsch.
Wo kommt die Eingabe her, und wie schnell muss es sein?
MemY schrieb:> Sorry! Natürlich 1 BCD Wert aus dem Wertebereich von 0..999999999999.
Deshalb kannst du eben nicht einfach 4 mal 3 Zehnerstellen nach binär
wandeln und die 4 Ergebnisse einfach binär aneinander ketten. Probiere
das einfach mal mit der BCD Zahl 0000001000 aus (= dezimal 1000). Dein
Ergebnis ist Hex 000000001000, das richtige wäre Hex 0000000003E8...
Lattice User schrieb:> Wo kommt die Eingabe her, und wie schnell muss es sein?
Die BCD Daten kommen von einem Sensor. Fuer die Auswertung habe ich
schon ein paar Takte zeit. Allerdings auch nicht all zu viele ;-)
Lothar Miller schrieb:> Dein> Ergebnis ist Hex 000000001000, das richtige wäre Hex 0000000003E8...
Mit diesem Ansatz ist zumindest in der Theorie die Umwandlung BCD ->
Binaer korrekt.
48Bit BCD in 2x24Bit BCD splitten, mit kleineren Konstanten 2x24Bit BCD
umrechnen in binär, beide Binärwerte am Ende zusammenbauen, dabei den
einen Wert um X Bits linksshiften. Ist Trivialwissen aus der
Grundschule.
MemY schrieb:> Jedoch sind die letzten beiden Multiplikationen, aufgrund des> Wertebereichs der Integer, nicht zulaessig.> Kann man dies umgehen?
Rechne mit unsigned Vektoren. Die kannst du beliebig lang machen...
> Oder muss ein komplett anderer Ansatz gewaehlt warden?
Das schon eher, denn dir wird 1. mit diesen Mosntermultiplizierern das
FPGA zu klein und 2. das Design insgesamt zu langsam werden...
MemY schrieb:> Fuer die Auswertung habe ich schon ein paar Takte zeit. Allerdings auch> nicht all zu viele ;-)
Wenn du 12 Takte Zeit hast, dann könntest du einfach die 12 BCD-Stellen
nacheinander über 1 Multiplizierer jagen und aufsummieren...
Pseudocode (mit links = BCD12, rechts = BCD0)
1
Sum = BCD(12);
2
Sum *=10;
3
Sum += BCD(11);
4
Sum *=10;
5
Sum += BCD(10);
6
Sum *=10;
7
Sum += BCD(9);
8
:
9
:
10
:
11
Sum *=10;
12
Sum += BCD(0);
Und jetzt kommt der Trick: das Ganze nicht einfach so hintereinander
schreiben, sondern einen Takt einführen, der dann den Index
weiterschaltet:
Lothar Miller schrieb:> Wenn du 12 Takte Zeit hast, dann könntest du einfach die 12 BCD-Stellen> nacheinander über 1 Multiplizierer jagen und aufsummieren...
Ja, 12 Takte haette ich auf jeden Fall zeit! Ich werde mir dein
Pseudocode anschauen - Danke!
Hagen Re schrieb:> Ist Trivialwissen aus der> Grundschule.
Ist das so? Mir erschließt sich dein Vorgehen gerade nicht.
verkürztes Beispiel mit 16 Bit BCD:
BCD: 2073
Zerlegt:
BCD 20 = Hex 14 = Binär 0001 0100
BCD 73 = Hex 49 = Binär 0100 1001
Und wie baust du jetzt die beiden Zahlen zusammen und shiftest, dass das
korrekte Ergebnis Hex 819 oder Binär 0000 1000 0001 10001 rauskommt?
> Und wie baust du jetzt die beiden Zahlen zusammen und shiftest, dass das> korrekte Ergebnis Hex 819 oder Binär 0000 1000 0001 1001 rauskommt?
Come on, so schwierig ist es nun auch wieder nicht:
X = 3 * 1 +
7 * 10 +
0 * 100 +
2 * 1000
= 0x0819
P. K. schrieb:>> Und wie baust du jetzt die beiden Zahlen zusammen und shiftest, dass das>> korrekte Ergebnis Hex 819 oder Binär 0000 1000 0001 1001 rauskommt?> Come on, so schwierig ist es nun auch wieder nicht:> X = 3 * 1 + 7 * 10 + 0 * 100 + 2 * 1000 = 0x0819
Das ist mein Verfahren. Aber: eine Addition ist kein Schieben. Mir
ist das mit dem Schieben auch nicht klar... ;-)
MemY schrieb:> Lothar Miller schrieb:>> Wenn du 12 Takte Zeit hast, dann könntest du einfach die 12 BCD-Stellen>> nacheinander über 1 Multiplizierer jagen und aufsummieren...> Ja, 12 Takte haette ich auf jeden Fall zeit! Ich werde mir dein> Pseudocode anschauen - Danke!
Wenn du deinen Code dann fertig hast, kannst du ja mal mit meinem Code
vergleichen:
http://www.lothar-miller.de/s9y/archives/89-BCD-nach-Binaer-wandeln.html
Lothar Miller schrieb:> http://www.lothar-miller.de/s9y/archives/89-BCD-na...
Dein Code ist natuerlich sehr elegant geloest! Habe nun den „BCD nach
Binaer Wandler“ für meine Applikation implementiert und anhand deines
Codes optimiert. Die Simulation bringt korrekte Ergebnisse!
Vielen Dank an dich Lothar, aber auch an die anderen!
Gruß MemY
Der Synthesizer erkennt, dass tmp*8 und tmp*2 keine wirklichen
Multiplikationen sind, und kann diese Operationen durch ein simples
Umverdrahten erledigen. Kurz: es ist kein Multiplizierer nötig, das
Design kann schneller getaktet werden...
Lothar Miller schrieb:> Kurz: es ist kein Multiplizierer nötig, das> Design kann schneller getaktet werden...
Das ist natuerlich nochmal etwas besser ;-)
Lothar Miller schrieb:> MemY schrieb:>> Dein Code ist natuerlich sehr elegant geloest!> Es gibt nichts, was nicht noch besser ginge... ;-)> Die Multiplikation in dieser Zeile:>
1
>tmp<=resize(tmp*10+unsigned(BCD(idx*4-1downto
2
>idx*4-4)),tmp'length);
3
>
> Kann durch eine zusätzliche Addition ersetzt werden:>
> Der Synthesizer erkennt, dass tmp*8 und tmp*2 keine wirklichen> Multiplikationen sind, und kann diese Operationen durch ein simples> Umverdrahten erledigen. Kurz: es ist kein Multiplizierer nötig, das> Design kann schneller getaktet werden...
simples Umverdrahten -> übertragen in mathe = multplikation zur Potenz
mit Basis 2 -> shiften.
Du kannst also den 48Bit BCD in zb. 2*24Bit zerlegen, dann so rechnen
wie oben und beide Zwischenresultate wieder in ein Resulat
zusammenbauen. Dabei entstehen Additionen und Multiplikationen zur basis
2, was man im FPGA durch Verdrahtung lössen kann und deine Konstanten
werden in den Teilberechnungen kleiner, PEK hat es oben schon erkannt.
P. K. schrieb:> Come on, so schwierig ist es nun auch wieder nicht:>> X = 3 * 1 +> 7 * 10 +> 0 * 100 +> 2 * 1000
Aha... dass das so funktioniert, weiss hier glaub jeder. Aber damit hast
du ja nicht wirklich neue Erkenntnisse herbeigebracht.
Lothar Miller schrieb:> Das ist mein Verfahren. Aber: eine Addition ist kein Schieben. Mir> ist das mit dem Schieben auch nicht klar... ;-)
Mir ist auch nicht klar, was er damit gemeint hat:
Hagen Re schrieb:> 48Bit BCD in 2x24Bit BCD splitten, mit kleineren Konstanten 2x24Bit BCD> umrechnen in binär, beide Binärwerte am Ende zusammenbauen, dabei den> einen Wert um X Bits linksshiften. Ist Trivialwissen aus der> Grundschule.
Schlumpf schrieb:>> Come on, so schwierig ist es nun auch wieder nicht:>>>> X = 3 * 1 +>> 7 * 10 +>> 0 * 100 +>> 2 * 1000>> Aha... dass das so funktioniert, weiss hier glaub jeder. Aber damit hast> du ja nicht wirklich neue Erkenntnisse herbeigebracht.
Nein, natürlich nicht. Nur hatte weiter oben jemand Mühe mit dem Wissen
aus der Grundschule:
Schlumpf schrieb:> Hagen Re schrieb:>> Ist Trivialwissen aus der>> Grundschule.>> Ist das so? Mir erschließt sich dein Vorgehen gerade nicht.
Und wenn man dieses Wissen geeignet darstellt erschliesst sich manchem
das vorgehen dann doch, z.B. dass die Multiplikation mit der Konstanten
10 nicht wirklich eine Multiplikation ist, sondern die noch weiter oben
erwähnte Shift-Geschichte.