MIP32 - weiter - 2024-12-11


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;