Ich baue gerade an einer ALU herum. Die library ieee.numeric_std.all unterstützt die Operationen + und -. Nur wie kann ich das Overflowbit noch herausfischen? Wer hat da eine Idee?
Welches Overflowbit willst du? Der Überlauf ist für vorzeichenbehaftete Zahlen anders zu erkennen, als für vorzeichenlose (der Addition selbst ist das ja egal).
du machst deinen additionsvektor um ein bit größer, und schaust dann das bit an
user schrieb: > du machst deinen additionsvektor um ein bit größer, und schaust dann das > bit an Addition ist mir schon klar. und bei der Subtraktion? Wo steckt da das bit? Subtraktion in eine Addtion überführen? Zweikomplement bilden (Minuend negieren ein bit addieren und dann beide Zahlen addieren) Das ist nicht toll, weil es zwei Addition werden und damit die Subtraktion länger als die Addition dauert.
Georg A. schrieb: > Welches Overflowbit willst du? Der Überlauf ist für vorzeichenbehaftete > Zahlen anders zu erkennen, als für vorzeichenlose (der Addition selbst > ist das ja egal). Das ist eine gute Frage. Ich bin mir selber nicht im Klaren was ich für ein Overflow benötige. Ich will einen Mips Softcore bauen. Da gibt es zwei Befehlen ADD und ADDU. Bei einem wird das Overflowbit nicht ausgewertet. Es ist jedoch die gleiche Additionsoperation. Die Addtionen sind bei signed und unsigned gleich, nur das Overflow bit unterscheidet sich. Nur wie wird es bei der Mips gemacht? Ich wollte es mir nicht aus Halb- und Volladdieren haerausfiltern.
René D. schrieb: > Das ist nicht toll, weil es zwei Addition werden und damit die > Subtraktion länger als die Addition dauert. not, bei nem RCA zum beispiel nicht
René D. schrieb: >> >> not, bei nem RCA zum beispiel nicht > > RCA ?? ripple carry addierer, den kann man ganz leicht zu nem subtrahierer umbauen: man XORed den carry_in eingang vom ersten glied mit dem 2. operanden: Setzt man nun carry_in vom ersten glied auf 1 hat man einen subtrahierer ansonsten einen addierer (2er komplement, da negiert und +1)
> Nur wie wird es bei der Mips gemacht?
Meine MIPSeleien sind schon länger her, aber wenn es da noch ein
Carry-Flag gibt, ist es klar: Carry=unsigned, Overflow=signed.
Georg A. schrieb: >> Nur wie wird es bei der Mips gemacht? > > Meine MIPSeleien sind schon länger her, aber wenn es da noch ein > Carry-Flag gibt, ist es klar: Carry=unsigned, Overflow=signed. Es gibt kein Flags bei der Mips. Es wird ein interrupt ausgelöst. Wobei ich das Wort trap nicht ganz deuten kann. Format: ADDI rt, rs, immediate MIPS I Purpose: To add a constant to a 32-bit integer. If overflow occurs, then trap. Description: rt ¬ rs + immediate Exceptions: Integer Overflow
hallo,
ich habe das selbe problem. folgende befehle sollen realisiert werden:
ALUfunc Output
0000 C = 0
0001 C = A+B
0010 C = A-B
0011 C = B-A
0100 C = A
0101 C = B
0110 C = A+1
0111 C = B+1
1000 C = A AND B
1001 C = A OR B
1010 C = A XOR B
1011 C = B-1
1100 C = NOT A
1101 C = NOT B
1110 C = (NOT A)+1
1111 C = (NOT B)+1
wir haben alle zahlen zu unsigned konvertiert, ein bit vorrangestellt
und es dann auch mit diesem !!!schema!!! versucht:
A, B : in std_logic_vector(15 downto 0);
C : out std_logic_vector(15 downto 0);
ALUFunc : in std_logic_vector(3 downto 0);
variable result_temp : std_logic_vector(16 downto 0);
-- z.B. Overflow bei B-A
elsif ALUFunc = "0011" then
result_temp := std_logic_vector(unsigned('0' & B) + unsigned('0' &
not A) + 1);
result <= result_temp(15 downto 0);
cout <= result_temp(16);
if (A(15)='1' and B(15)='0' and unsigned(result_temp(15 downto 0))
> 32767) or (A(15)='0' and B(15)='1' and unsigned(result_temp(15 downto
0)) < 32768) then
ov <= '1';
else
ov <= '0';
end if;
-- z.B. Carry bei Addition B+1
elsif ALUFunc = "0111" then
result_temp := std_logic_vector(unsigned('0' & B) + 1);
result <= result_temp(15 downto 0);
cout <= result_temp(16);
if (A(15)='0' and unsigned(result_temp(15 downto 0)) > 32767) or
(A(15)='1' and unsigned(result_temp(15 downto 0)) < 32768) then
ov <= '1';
else
ov <= '0';
end if;
leider stimmt irgendetwas noch nicht...
> leider stimmt irgendetwas noch nicht...
Und wir sollen jetzt nicht nur die Ursache sondern auch noch das
"Irgendwas" suchen?
BTW: Der Overflowcheck ist aber auf jeden Fall falsch, die Eingangswerte
haben da nichts zu suchen.
nachdem ich ein bisschen auf wikipedia (zweierkomplement, unterpunkt vorzeichenerweiterung) und in dem wirklich guten buch "how computers do math" von maxfield und brown (verlag wiley) geschmöckert habe bin ich zu folgenden folgerungen (in "pseudocode") gekommen: 0) bei subtraktion 2er-komplement des jeweils zweiten operanden bilden, bei den 2er-komplement-operationen sowieso, bei den NOT-operationen das 1er-komplement bilden 1) 16 bit vektoren von A und B als signed verwenden 2) 1 vorzeichenbit an A und B anhängen (natürlich vorne), das heißt: msb-bit des 16 bit vektors des jeweiligen vektors kopieren (NICHT immer 0en anhängen!!!) 3) die beiden 17 bit vektoren ganz normal addieren 4) JETZT wirds spannend: ACHTUNG fürs verständnis: das ergebnis wird später auf 16 bit breite beschnitten und hat dann trotzdem noch bzw. wieder ein "zweites" vorzeichenbit!!!! 4)a) falls 17. und 16. bit des ergebnisses gleich sind (beide 0 oder 1) 4)a)i) ...beide 0 dann positives ergebnis im erlaubten bereich (ov = 0, cout = 0) 4)a)ii) ... beide 1 dann negatives ergebnis im erlaubten bereich (ov = 0, cout = 0) 4)b) falls 17.bit = 0 und 16.bit = 1 dann positives ergebnis außerhalb des erlaubten bereichs (dann ist das 16.bit das carry flag, sonst würde es ja eine negative zahl andeuten) (ov = 0, cout = 1) 4)c) falls 17.bit = 1 und 16.bit = 0 dann negatives ergebnis außerhalb des erlaubten bereichs (dann ist das 17.bit das overflow flag, sonst würde das positive 16.bit ja eine positive zahl andeuten) (ov = 1, cout = 0) was haltet ihr davon? in dem oben genannten buch ist die rede von flags, die bei hintereinander durchgeführten operationen irgendwie "propagieren". dann ist ja auch ein carry_in und overflow_in notwendig, oder? wie wird das realisiert?
Bei 4b meinst du wohl auch ov=1, wenn ov das Overflow-Flag der gesamten
Operation sein soll. Und für den Check von 4b/c gibt es passenderweise
eine boolsche Operation...
> wie wird das realisiert?
Overflow_in gibts nicht, Carry_in schon. Macht halt +1. Damit reduziert
sich das SUB auf A + NOT B mit invertiertem Carry_in.
Florian Kromer schrieb: > 0) bei subtraktion 2er-komplement des jeweils zweiten operanden bilden, Kann man zwar machen, ist aber unnötig aufwendig. Das +1 der Bildung des Zweierkomplements lässt sich mit dem eingehenden Carry der Addition kombinieren. Eine Zweierkomplement-Subtraktion ist daher technisch die Addition des Einer(!)komplements, allerdings mit invertiertem Carry (rein wie raus). Bei manchen Architekturen funktioniert das Carry auch exakt so (z.B. 6502), bei anderen wird das eigens invertiert.
@ Andre: Auf "C=A-1" habe ich verzichtet, weil ich diese Funktion nicht unbedingt brauche und ansonsten die ALUfunc-Breite von 4 Bit (max. 16 Befehle) auf 5 Bit (max.32 Befehle) hätte erweitern müssen. Die Funktion "C=B-1" ist wichtiger, da sie für Dekrementierungen von Zeigern bei indirekter Adressierung benutzt wird. Am A-Eingang liegt der Akkumulator, am B-Eingang die Register über Multiplexer.
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.