Ich schreibe im Moment mit Verilog einen Floating-Point-Adder/Subtractor. Ja, ich weiß, das gibt's schon tausend Mal, aber es ist ein Problem, das für mich als Anfänger die richtige Größenordung hat, und daher zum Lernen gut geeignet. Jedenfalls ist das Problem: Ich muss nach der Addition oder Subtraktion der Mantissen die resultierende Mantisse wieder normalisieren, also left-shiften, so dass die höchste Eins auf der Position des hidden bit steht. Aber dazu muss ich wissen, wie weit ich zu shiften habe, also wo diese erste Eins überhaupt steht. Nun könnte ich einfach so lange jeweils um eine Position bewegen, bis das hidden bit Eins ist, aber da das in möglichst wenigen Taktzyklen fertig sein soll, ist das ausgeschlossen. Im Moment benutze ich als Notlösung eine if-Kaskade, um für jede Stelle abzufragen, ob dort eine Eins steht. Aber das ist auch eine reichlich dämliche Lösung. Ich hätte gerne eine Möglichkeit, das möglichst einfach ohne ifs zu machen. Gibt es da einen allgemein bekannten einfachen Weg? Ich habe nichts gefunden. Oder macht man die Sache vielleicht auch ganz anders?
Es gibt eventuell Wege die schöner aussehen (z.b. for schleife, wobei das Geschmackssache ist), aber in hardware geht es nunmal eh nicht anders. Da muss ohnehin jedes bit geprüft werden, würde deshalb alle bits in eine zeile ver-oder-n und gut. außer es sind 32++, dann wohl doch eher die for schleife. Allerdings muss man sich fragen ob es nicht eine andere Lösung gibt. Das Konstrukt dürfte bei großen Breiten eine nicht unerhebliche Zahl an Ressourcen verschlingen und zudem das routing stark verlangsamen. Kannst du dir nicht während der Berechnung merken wo die ersten 1 hinwandert ? Bei der Addition hast du die zahlen doch eh schon angefasst, dann müsstest du nicht völlig blind irgenteine Zahl durchforsten. bsp : für jedes carry oder jede 1 im teilergebnis wird ein zähler um 1 inkrementiert. am zählerstand am ende kann man ablesen wo die höchste 1 steht. Klappt natürlich nur bei carry-chain Addierern, keine Ahnung welchen du einsetzt.
Grundsätzlich musst du dir erstmal über deine "Umwelt" im klaren sein. Nach einer Addition/Subtraktion/Multiplikation/Divsion zweier binärer Zahlen ist das Verhalten der höchstwertigen Bits der binären Zahlen exakt definiert. Dh. entgegen der Ausage >Allerdings muss man sich fragen ob es nicht eine andere Lösung gibt. Das >Konstrukt dürfte bei großen Breiten eine nicht unerhebliche Zahl an >Ressourcen verschlingen und zudem das routing stark verlangsamen. hast du eben keinen großen Aufwand zu betreiben. Normalerweise wird man eine Normalisierung nach jedem Rechenschritt durchführen. Ergo: deine beiden Manitissen sind schon normalisiert vor deiner Addition/Subtraktion. Nach deiner Addition/Subtraktion kann es nur 2 Fälle geben: du hast einen Bit-Überlauf oder Bit-Unterlauf je nachdem ob addiert oder subtrahiert wurde (errinnere dich, die Mantissen sind so normalisiert das deren höchstwertigstes Bit auch im MSB steht). Dieser Carry/Borrow Flag wird wenn es eintrifft dazu führen das du Normalisieren musst. Dh. nur in 50% aller Fälle must du überhaupt Normalisieren im Rest der Fälle machst du garnichts weiter. Bei der Normalisierung führst du deinen Shift um eine Bitposition durch und rechnest das Carry/Borrowflag ein. Deine Mantissen sind doch "rechts-ausgerichtet" also zum MSB hin oder ? Denn das entscheidet über den nötigen Aufwand für die Normalisierung. Eine Normalisierung heist bei Floats auch immer das Update der Exponenten so das die Mantissen virtuell im Bereich 0 bis 1 liegen. Gruß Hagen
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.