BEQ rs,rt,offset Branch On Equal if(rs==rt) pc+=offset*4 000100 rs rt offset |
-- ich "uberarbeite gerade diese nicht ganz falsche, aber auch nicht ganz tolle gleichung memtoreg <= x0 and (not x1 or not x2 or not x4); memwrite <= x0 and (not x1 or x2); branch <= x0 and (not x1 or not x2); alusrc <= x0 or (not x1 or x2); -- weil 0 +4 regdst <= x0 or (not x1 or x2); ---? Bei immidiate - 15:15 - ist aber x1 regwrite <= x0 or (x1 or not x2); -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 -- 0 0 1 0 -- 0 0 1 1 |
-- das ist quatsch -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 -- 0 0 1 0 -- 0 0 1 1 -- 0 1 0 0 -- 0 1 0 1 -- 0 1 1 0 -- 0 1 1 1 -- 1 0 0 0 -- 1 0 0 1 -- 1 0 1 0 -- 1 0 1 1 -- 1 1 0 0 -- 1 1 0 1 -- 1 1 1 0 -- 1 1 1 1 |
so, richtig -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 -- 0 0 1 0 -- 0 1 0 0 -- 1 0 0 0 |
-- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 0 0 0 0 0 0 (R-Typ) -- 0 0 1 0 1 0 0 1 1 1 load (lb, ...) -- 0 1 0 0 store (sb, ...) -- 1 0 0 0 0 0 1 1 1 0 beq |
wichtig ist, dass bei beq an die ALU die Operation SUB gesendet wird. Über unsere zwei Bit - die Null Feststellung findet automatisch jedes Mal statt
-- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 0 0 0 0 0 0 (R-Typ) -- 0 0 1 0 1 0 0 1 1 1 load (lb, ...) -- 0 1 0 0 store (sb, ...) -- 1 0 0 0 0 0 1 1 1 0 beq (und ALU-Op = 10) -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite ALU-Op1 ALU-Op0 -- 0 0 0 0 -- 0 0 0 1 0 0 0 0 0 0 0 0 (Add) -- 0 0 1 0 1 0 0 1 1 1 x x load (lb, ...) -- 0 1 0 0 x x store (sb, ...) -- 1 0 0 0 0 0 1 1 1 0 0 1 beq (und ALU-Op = 10) x0 <= '0'; x1 <= not opcode (5) and not opcode (4) and opcode (3) and not opcode (2) and not opcode (1) and not opcode (0); x2 <= opcode (5) and not opcode (4) and opcode (3) and not opcode (2) and not opcode (1) and not opcode (0); x4 <= not opcode (5) and not opcode (4) and opcode (3) and opcode (2) and not opcode (1) and not opcode (0); memtoreg <= x2; memwrite <= x0; branch <= x4; alusrc <= x2 or x4; regdst <= x2 or x4; regwrite <= x2; aluop (1) <= x0; aluop (0) <= x4; |
die subtraktion ist vollkommen richtig und hier müssen wir zwei dinge unterscheiden, im Befehl steht entweder ein negativer wert oder ein positiver - als zweierkomplement - das heisst, wir springen vor oder zurück. im Befehl selber. das ist das vor und zurück. Diese Addition entweder negativ oder positiv - zurück oder vor - nimmt aber nicht die ALU vor. es ist der zweite Addierer. Und hier muss kein Subtrahierer her, zurück, weil es Aufgabe des Assemblers ist, das um zu rechnen/fest zu legen, das negative Zweierkomplement steht im source code. Es bezieht sich auf den Programmspeicher. Anders ist es mit dem Vergleich der zwei Register, sie werden immer subtrahiert, ihr Vergleich entscheidet, wird der sprung genommen oder nicht
eine negative 1 im zweier komplement ist 11111....
0001 ist positiv 1110 ist einer komplement 1111 ist zweier komplement |
Das muss so in die Verzweigung wollen wir sie wiederholen
Zun"achst addieren wir zum Register $r1 - die ja alle geresettet sind, einen Wert - in unserem bisherigen Testprogramm durch ist $r0 bereits mit einem h"oheren Wert geladen. Wir m"ussen blos nun $r1 von $r0 abziehen. Dabei setzen wir f"ur das RS-Feld und RT-Feld des Befehls 0 und 1 ein |
das stimmt nicht, dass grosse zahlen raus kommen, kann nicht sein, die Addition im zweier komplement ist sicher - das ist quatsch, ergibt sich durch auslöschung durch Vorzeichenflag, vorausgesetzt, vom Betrag ist der Minuend grösser als der Subtrahend
library ieee; use ieee.std_logic_1164.all; entity opdecode is port ( opcode: in std_logic_vector (5 downto 0); memtoreg: out std_logic; memwrite: out std_logic; branch: out std_logic; alusrc: out std_logic; regdst: out std_logic; regwrite: out std_logic; aluop: out std_logic_vector (1 downto 0) ); end; architecture behaviour of opdecode is signal x0: std_logic; signal x1: std_logic; signal x2: std_logic; signal x3: std_logic; signal x4: std_logic; begin -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite -- 0 0 0 0 -- 0 0 0 1 0 0 0 0 0 0 (R-Typ) -- 0 0 1 0 1 0 0 1 1 1 load (lb, ...) -- 0 1 0 0 store (sb, ...) -- 1 0 0 0 0 0 1 1 1 0 beq (und ALU-Op = 10) -- x4 x3 x2 x1 memtoreg memwrite branch alusrc regdst regwrite ALU-Op1 ALU-Op0 -- 0 0 0 0 -- 0 0 0 1 0 0 0 0 0 0 0 0 (Add) -- 0 0 1 0 1 0 0 1 1 1 x x load (lb, ...) -- 0 1 0 0 x x store (sb, ...) -- 1 0 0 0 0 0 1 1 1 0 0 1 beq (und ALU-Op = 10) x0 <= '0'; x1 <= not opcode (5) and not opcode (4) and opcode (3) and not opcode (2) and not opcode (1) and not opcode (0); x2 <= opcode (5) and not opcode (4) and opcode (3) and not opcode (2) and not opcode (1) and not opcode (0); x4 <= not opcode (5) and not opcode (4) and opcode (3) and opcode (2) and not opcode (1) and not opcode (0); memtoreg <= x2; memwrite <= x0; branch <= x4; alusrc <= x2 or x4; regdst <= x2 or x4; regwrite <= x2; aluop (1) <= x0; aluop (0) <= x4; -- aluop -- 00 -- add -- 01 -- sub -- 10 -- nutze das func feld -- 11 -- aluop x -- 0 0 - (0) -- 0 1 1 -- 1 0 2 -- x x - end; |