MIPS32 in VHDL

david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

-- (C) David Vajda
-- MIPS32 - minimal
-- 2024-12-04

library ieee;
use ieee.std_logic_1164.all;

entity rslatch is
port (
    r: in std_logic;
    s: in std_logic;
    q: inout std_logic;
    p: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of rslatch is
begin
    q   <=  (r nor p) and not reset;
    p   <=  (s nor q);
end;

library ieee;
use ieee.std_logic_1164.all;

entity clktriggeredrslatch is
port (
    r: in std_logic;
    s: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of clktriggeredrslatch is
    component rslatch
    port (
        r: in std_logic;
        s: in std_logic;
        q: inout std_logic;
        p: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, d: std_logic;
begin
    rs: rslatch PORT MAP (r=>e, s=>d, q=>q, reset=>reset);
    d <= c and s;
    e <= c and r;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dlatch is
    component clktriggeredrslatch
    port (
        r: in std_logic;
        s: in std_logic;
        c: in std_logic;
        q: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, f: std_logic;
begin
    clkrs: clktriggeredrslatch PORT MAP (r=>f, s=>e, c=>c, q=>q, reset=>reset);

    e <= d;
    f <= not d;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dff is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dff is
    component dlatch
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal e, a, b: std_logic;
begin
    d1: dlatch PORT MAP (c=>a, d=>e, q=>q, reset=>reset);
    d2: dlatch PORT MAP (c=>b, d=>d, q=>e, reset=>reset);
    a <= not c;
    b <= c;
end;

library ieee;
use ieee.std_logic_1164.all;

entity reg32 is
port (
    c: in std_logic;
    d: in std_logic_vector (31 downto 0);
    q: out std_logic_vector (31 downto 0);
    reset: in std_logic
);
end;

architecture behaviour of reg32 is
    component dff
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal p: std_logic_vector (31 downto 0);
begin
    gen_reg: FOR i in 31 downto 0 generate
        dffx: dff PORT MAP (q=>p(i),d=>d(i),c=>c, reset=>reset);
        q(i) <= p (i);
    end generate;
end;

library ieee;
use ieee.std_logic_1164.all;

entity MUX32_2_1 is
port (
    c: out std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX32_2_1 is
begin
    MUX_generate: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity MUX5_2_1 is
port (
    c: out std_logic_vector (4 downto 0);
    b: in std_logic_vector (4 downto 0);
    a: in std_logic_vector (4 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX5_2_1 is
begin
    MUX_generate: FOR i IN 4 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regsrc2: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    srcmux2: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata2, x=>regsrc2);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity registerset4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regsrc2: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regsrc2: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (1));
    reg1: registerset2_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    reg2: registerset2_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity registerset8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regsrc2: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regsrc2: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (2));
    reg1: registerset4_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    reg2: registerset4_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity registerset16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regsrc2: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regsrc2: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (3));
    reg1: registerset8_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    reg2: registerset8_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regsrc2: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regsrc2: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (4));
    reg1: registerset16_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    reg2: registerset16_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;

-- (C) David Vajda
-- 32 Bit Ripple Carry Chain Adder / Subtrahierer / Volladdierer
-- 2024-12-02

library ieee;
use ieee.std_logic_1164.all;

entity fulladder is
port (
    a: in std_logic;
    b: in std_logic;
    c: out std_logic;
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of fulladder is
begin
    c <= a xor b xor s;
    t <= (a and b) or ((a or b) and s);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of ripplecarrychainadder32 is
    component fulladder
    port (
        a: in std_logic;
        b: in std_logic;
        c: out std_logic;
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (32 downto 0);
begin
        fa_loop: FOR i IN 31 DOWNTO 0 GENERATE
            fa: fulladder PORT MAP (a=>a(i), b=>b(i), c=>c(i), s=>x(i), t=>x(i+1));
        END GENERATE;
        t <= x (32) ;
        x (0) <= s;
    --fa3: fulladder20241128 PORT MAP (a=>a3, b=>b3, c=>c3, s=>s3, t=>t);
    --fa2: fulladder20241128 PORT MAP (a=>a2, b=>b2, c=>c2, s=>s2, t=>s3);
    --fa1: fulladder20241128 PORT MAP (a=>a1, b=>b1, c=>c1, s=>s1, t=>s2);
    --fa0: fulladder20241128 PORT MAP (a=>a0, b=>b0, c=>c0, s=>s, t=>s1);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32testbench is
port (
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;


architecture behaviour of ripplecarrychainadder32testbench is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal a: std_logic_vector (31 downto 0);
    signal b: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    rplcadd: ripplecarrychainadder32 PORT MAP (c=>c, b=>b, a=>a, s=>s, t=>t);
    -- 19219 + 14823 = 34042
    -- 0b100101100010011 + 0b11100111100111 = 0b1000010011111010
    a <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 20 ns;

    b <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 20 ns;
    s <= '0';
end;

library ieee;
use ieee.std_logic_1164.all;

entity com32 is
port (
    x: in std_logic_vector (31 downto 0);
    y: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of com32 is
begin
        com_connect: FOR i IN 31 DOWNTO 0 GENERATE
                y (i) <= not x (i);
        END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity neg32 is
port (
    b: out std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of neg32 is
    component com32
    port (
        x: in std_logic_vector (31 downto 0);
        y: out std_logic_vector (31 downto 0)
    );
    end component;

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal c: std_logic_vector (31 downto 0);
    signal d: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg32_generate_1: FOR i IN 31 DOWNTO 0 GENERATE
        d (i) <= '0';
    END GENERATE;
    s <= '1';
    com: com32 PORT MAP (x=>a, y=>c);
    add: ripplecarrychainadder32 PORT MAP (b=>d, a=>c, s=>s, t=>t, c=>b);
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of sub32 is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component neg32
    port (
        b: out std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg: neg32 PORT MAP (a=>a, b=>x);
    add: ripplecarrychainadder32 PORT MAP (b=>b, a=>x, c=>c, s=>s, t=>t);
    s <= '0';
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32testbench is
port (
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;


architecture behaviour of sub32testbench is
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal a: std_logic_vector (31 downto 0);
    signal b: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    sub: sub32 PORT MAP (a=>a, b=>b, c=>c, t=>t);

    a <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 10 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 20 ns;
    b <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 0 ns,  ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 10 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 20 ns;
    s <= '0' after 0 ns, '1' after 10 ns;
    -- 19219 - 14823 =
end;

library ieee;
use ieee.std_logic_1164.all;

entity or32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of or32 is
begin
    genor32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) or a (i);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity and32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of and32 is
begin
    genand32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) and a (i);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;


    entity sram is
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of sram is
    begin
        readdata <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    end;


library ieee;
use ieee.std_logic_1164.all;


    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of prom is
    begin
        readdata <= ('0','0','0','0','0','0', '0','0','0','0','0', '0','0','0','0','0', '0','0','0','0','0', '0','0','0','0','0', '1','0','0','1','0','0');
    end;


library ieee;
use ieee.std_logic_1164.all;

entity ALU is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic_vector (2 downto 0);
    t: out std_logic;
    nul: inout std_logic;
    globalcarryflag: out std_logic
);
end;

architecture behaviour of ALU is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    component and32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component or32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal z4, z3, z2, z1: std_logic;
    signal x3, x2, x1: std_logic;
    signal csub: std_logic_vector (31 downto 0);
    signal cor: std_logic_vector (31 downto 0);
    signal cmux1: std_logic_vector (31 downto 0);
    signal cmux2: std_logic_vector (31 downto 0);
    signal cadd: std_logic_vector (31 downto 0);
    signal cand:  std_logic_vector (31 downto 0);
    signal sadd: std_logic;
    signal d: std_logic_vector (31 downto 0);
begin
    -- 010 add
    -- 110 sub
    -- 000 and
    -- 001 or
    -- 111 slt set less than
    mux1: MUX32_2_1 PORT MAP (a=>cadd, b=>csub, c=>cmux1, x=>x1);
    mux2: MUX32_2_1 PORT MAP (a=>cand, b=>cor, c=>cmux2, x=>x2);
    mux3: MUX32_2_1 PORT MAP (a=>cmux1, b=>cmux2, c=>d, x=>x3);
    add1: ripplecarrychainadder32 PORT MAP (a=>a, b=>b, s=>sadd, t=>globalcarryflag, c=>cadd);
    sub1: sub32 PORT MAP (a=>a, b=>b, t=>globalcarryflag, c=>csub);
    and1: and32 PORT MAP (a=>a, b=>b, c=>cand);
    or1: or32 PORT MAP (a=>a, b=>b, c=>cor);

    z1 <= (not s (2) and s (1) and not s (0));
    z2 <= (s(2) and s(1) and not s(0));
    z3 <= (not s (2) and not s (1) and not s (0));
    z4 <= (not s (2) and not s (1) and s (0));

    --
    -- z4  z3  z2  z1       x3  x2  x1
    -- 0   0   0   1        0   x   0
    -- 0   0   1   0        0   x   1
    -- 0   1   0   0        1   0   x
    -- 1   0   0   0        1   1   x

    -- x3 <= z3 or z4
    -- x2 <= z3
    -- x1 <= z2

    x3 <= z3 or z4;
    x2 <= z4;
    x1 <= z2;
    sadd <= '0';
    c <= d;
    nul <= d (31);
    testnull: FOR i IN 30 DOWNTO 0 GENERATE
        nul <= d (i) nor nul;
    END GENERATE;
end;

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);
        cpuclock: in std_logic
    );
    end;

    architecture behaviour of opdecode is
    begin
        memtoreg <= '0';
        memwrite <= '0';
        branch <= '0';
        alusrc <= '0';
        regdst <= '1';
        regwrite <= '1' and cpuclock;
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
    begin
        aluoperation <= ('0', '0', '0');
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity Bit2Shift is
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of Bit2Shift is
    begin
        b   <=  a;
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity signunit is
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of signunit is
    begin
        b <=   ('0','0','0','0',   '0','0','0','0',   '0','0','0','0',   '0','0','0','0', '0','0','0','0',   '0','0','0','0',   '0','0','0','0',   '0','0','0','0');
    end;


library ieee;
use ieee.std_logic_1164.all;

entity mips32 is
port (
    globalCPUCLK: in std_logic
);
end;

architecture behaviour of mips32 is
    component registerset32_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (4 downto 0);
        regsrc2: in std_logic_vector (4 downto 0);
        regdest: in std_logic_vector (4 downto 0);
        en: in std_logic;
        clk: in std_logic;
        reset: in std_logic
    );
    end component;

    component ALU
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic_vector (2 downto 0);
        t: out std_logic;
        nul: inout std_logic;
        globalcarryflag: out std_logic
    );
    end component;

    -- 4 x MUX

    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;

    component MUX5_2_1
    port (
        c: out std_logic_vector (4 downto 0);
        b: in std_logic_vector (4 downto 0);
        a: in std_logic_vector (4 downto 0);
        x: in std_logic
    );
    end component;

    -- befehlszaehler, addierer + 4 u Sprung 2x Addierer

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;

    component Bit2Shift
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component signunit
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component sram
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end component;

    component prom
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end component;

    component reg32
    port (
        q: out std_logic_vector (31 downto 0);
        d: in std_logic_vector (31 downto 0);
        c: in std_logic;
        reset: in std_logic
    );
    end component;

    component opdecode
    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);
        cpuclock: in std_logic
    );
    end component;

    component funcdecode
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end component;

    signal op: std_logic_vector (31 downto 0);

    signal aluop: std_logic_vector (1 downto 0);
    signal func: std_logic_vector (5 downto 0);
    signal aluoperation: std_logic_vector (2 downto 0);
    signal memtoreg: std_logic;
    signal memwrite: std_logic;
    signal branch: std_logic;
    signal alusrc: std_logic;
    signal regdst: std_logic;
    signal regwrite: std_logic;

    signal pcsrc: std_logic;

    signal regdest: std_logic_vector (4 downto 0);
    signal aALUOperandBus, bALUOperandBUS, cALUOperandBus: std_logic_vector (31 downto 0);
    signal signunitBUS: std_logic_vector (31 downto 0);
    signal memReadData: std_logic_vector (31 downto 0);
    signal destdata: std_logic_vector (31 downto 0);
    signal srcdata1: std_logic_vector (31 downto 0);
    signal srcdata2: std_logic_vector (31 downto 0);

    signal nulbit: std_logic;

    signal pcBUSplus: std_logic_vector (31 downto 0);
    signal pcBUS: std_logic_vector (31 downto 0);

    signal Value32_4: std_logic_vector (31 downto 0);

    signal add1cBus: std_logic_vector (31 downto 0);
    signal add2cBus: std_logic_vector (31 downto 0);

    signal Bit2ShiftBus: std_logic_vector (31 downto 0);

    signal Value1_0: std_logic;

    signal nullbit: std_logic;

    signal globalCPUC: std_logic;

    signal reset: std_logic;
begin
    funcdecode1: funcdecode PORT MAP (aluoperation=>aluoperation,func=>func,aluop=>aluop);
    opdecode1: opdecode PORT MAP (opcode=>op(31 downto 26), aluop=>aluop, memtoreg => memtoreg, memwrite => memwrite, branch => branch, alusrc => alusrc, regdst => regdst, regwrite => regwrite, cpuclock=>globalCPUC);


    mux1: MUX5_2_1 PORT MAP (a=>op (20 downto 16), b=> op (15 downto 11), c=>regdest, x=>regdst);
    mux2: MUX32_2_1 PORT MAP (a=>srcdata1, b=>signunitBUS, c=>bALUOperandBUS, x=>alusrc);
    mux3: MUX32_2_1 PORT MAP (a=>cALUOperandBus, b=>memReadData, c=>destdata, x=>memtoreg);
    mux4: MUX32_2_1 PORT MAP (b=>add2cBus, a=>add1cBus, c=>pcBUSplus, x=>pcsrc);

    signunit1: signunit PORT MAP (a=>op (15 downto 0), b=>signunitBUS);
    Bit2Shift1: Bit2Shift PORT MAP (a=>signunitBUS, b=>Bit2ShiftBUS);

    add1: ripplecarrychainadder32 PORT MAP (a=>pcBUS, b=>Value32_4, c=>add1cBus, s=>Value1_0);
    add2: ripplecarrychainadder32 PORT MAP (a=>Bit2ShiftBus, b=>add1cBUS, c=>add2cBUS, s=>Value1_0);

    pc: reg32 PORT MAP (q=>pcBUS, d=>pcBUSplus, c=>globalCPUC, reset=>reset);

    alu1: alu PORT MAP (a=>srcdata1, b=>bALUOperandBUS, c=>cALUOperandBus, s=>aluoperation, nul=>nullbit);
    regset1: registerset32_32 PORT MAP (regdest=>regdest, destdata=>destdata, srcdata1=>srcdata1, srcdata2=>srcdata2, en=>regwrite, regsrc1=>op (25 downto 21), regsrc2=>op (20 downto 16), reset=>reset, clk=>globalCPUC);

    sram1: sram PORT MAP (en=>memwrite, addrs=>cALUOperandBus, writedata=>srcdata2, readdata=>memReadData);
    prom1: prom PORT MAP (addrs=>pcBUS, readdata=>op);

    pcsrc <= nullbit and branch;

    Value32_4 <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    Value1_0 <= '0';

    reset <= '1' after 0 ns, '0' after 2 ns;
    globalCPUC <= '1' after 0 ns, '0' after 1 ns, '1' after 2 ns, '0' after 3 ns, '1' after 4 ns, '0' after 5 ns, '1' after 6 ns, '0' after 7 ns, '1' after 8 ns, '0' after 9 ns, '1' after 10 ns;
end;
Attachments
Screenshot_20241205_003904.png
Screenshot_20241205_003904.png (47.94 KiB) Viewed 299 times
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

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;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1;
        regwrite <= x0 or x1;
    end;
    

Code: Select all

architecture behaviour of opdecode is
        signal x0: std_logic;
        signal x1: std_logic;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1;
        regwrite <= x0 or x1;

        -- aluop
        -- 00 -- add
        -- 01 -- sub
        -- 10 -- nutze das func feld
        -- 11

        aluop (1) <= x0 or not x1;
        aluop (0) <= x0 or not x1;
    end;
    

Code: Select all

entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
    begin
        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';
        x1 <= (not aluop (1) and not aluop (0));
        aluoperation (2) <= x0;
        aluoperation (1) <= x0 or x1;
        aluoperation (0) <= x0;

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

    end;
    

Code: Select all

-- signal x1, x0 vergessen

    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
        signal x1, x0: std_logic;
    begin
        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';
        x1 <= (not aluop (1) and not aluop (0));
        aluoperation (2) <= x0;
        aluoperation (1) <= x0 or x1;
        aluoperation (0) <= x0;

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

    end;
    
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

-- (C) David Vajda
-- MIPS32 - minimal
-- 2024-12-04

library ieee;
use ieee.std_logic_1164.all;

entity rslatch is
port (
    r: in std_logic;
    s: in std_logic;
    q: inout std_logic;
    p: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of rslatch is
begin
    q   <=  (r nor p) and not reset;
    p   <=  (s nor q);
end;

library ieee;
use ieee.std_logic_1164.all;

entity clktriggeredrslatch is
port (
    r: in std_logic;
    s: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of clktriggeredrslatch is
    component rslatch
    port (
        r: in std_logic;
        s: in std_logic;
        q: inout std_logic;
        p: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, d: std_logic;
begin
    rs: rslatch PORT MAP (r=>e, s=>d, q=>q, reset=>reset);
    d <= c and s;
    e <= c and r;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dlatch is
    component clktriggeredrslatch
    port (
        r: in std_logic;
        s: in std_logic;
        c: in std_logic;
        q: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, f: std_logic;
begin
    clkrs: clktriggeredrslatch PORT MAP (r=>f, s=>e, c=>c, q=>q, reset=>reset);

    e <= d;
    f <= not d;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dff is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dff is
    component dlatch
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal e, a, b: std_logic;
begin
    d1: dlatch PORT MAP (c=>a, d=>e, q=>q, reset=>reset);
    d2: dlatch PORT MAP (c=>b, d=>d, q=>e, reset=>reset);
    a <= not c;
    b <= c;
end;

library ieee;
use ieee.std_logic_1164.all;

entity reg32 is
port (
    c: in std_logic;
    d: in std_logic_vector (31 downto 0);
    q: out std_logic_vector (31 downto 0);
    reset: in std_logic
);
end;

architecture behaviour of reg32 is
    component dff
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal p: std_logic_vector (31 downto 0);
begin
    gen_reg: FOR i in 31 downto 0 generate
        dffx: dff PORT MAP (q=>p(i),d=>d(i),c=>c, reset=>reset);
        q(i) <= p (i);
    end generate;
end;

library ieee;
use ieee.std_logic_1164.all;

entity MUX32_2_1 is
port (
    c: out std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX32_2_1 is
begin
    MUX_generate: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity MUX5_2_1 is
port (
    c: out std_logic_vector (4 downto 0);
    b: in std_logic_vector (4 downto 0);
    a: in std_logic_vector (4 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX5_2_1 is
begin
    MUX_generate: FOR i IN 4 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regsrc2: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    srcmux2: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata2, x=>regsrc2);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity registerset4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regsrc2: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regsrc2: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (1));
    reg1: registerset2_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    reg2: registerset2_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity registerset8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regsrc2: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regsrc2: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (2));
    reg1: registerset4_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    reg2: registerset4_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity registerset16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regsrc2: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regsrc2: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (3));
    reg1: registerset8_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    reg2: registerset8_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regsrc2: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regsrc2: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (4));
    reg1: registerset16_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    reg2: registerset16_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;

-- (C) David Vajda
-- 32 Bit Ripple Carry Chain Adder / Subtrahierer / Volladdierer
-- 2024-12-02

library ieee;
use ieee.std_logic_1164.all;

entity fulladder is
port (
    a: in std_logic;
    b: in std_logic;
    c: out std_logic;
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of fulladder is
begin
    c <= a xor b xor s;
    t <= (a and b) or ((a or b) and s);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of ripplecarrychainadder32 is
    component fulladder
    port (
        a: in std_logic;
        b: in std_logic;
        c: out std_logic;
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (32 downto 0);
begin
        fa_loop: FOR i IN 31 DOWNTO 0 GENERATE
            fa: fulladder PORT MAP (a=>a(i), b=>b(i), c=>c(i), s=>x(i), t=>x(i+1));
        END GENERATE;
        t <= x (32) ;
        x (0) <= s;
    --fa3: fulladder20241128 PORT MAP (a=>a3, b=>b3, c=>c3, s=>s3, t=>t);
    --fa2: fulladder20241128 PORT MAP (a=>a2, b=>b2, c=>c2, s=>s2, t=>s3);
    --fa1: fulladder20241128 PORT MAP (a=>a1, b=>b1, c=>c1, s=>s1, t=>s2);
    --fa0: fulladder20241128 PORT MAP (a=>a0, b=>b0, c=>c0, s=>s, t=>s1);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32testbench is
port (
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;


architecture behaviour of ripplecarrychainadder32testbench is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal a: std_logic_vector (31 downto 0);
    signal b: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    rplcadd: ripplecarrychainadder32 PORT MAP (c=>c, b=>b, a=>a, s=>s, t=>t);
    -- 19219 + 14823 = 34042
    -- 0b100101100010011 + 0b11100111100111 = 0b1000010011111010
    a <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 20 ns;

    b <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 20 ns;
    s <= '0';
end;

library ieee;
use ieee.std_logic_1164.all;

entity com32 is
port (
    x: in std_logic_vector (31 downto 0);
    y: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of com32 is
begin
        com_connect: FOR i IN 31 DOWNTO 0 GENERATE
                y (i) <= not x (i);
        END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity neg32 is
port (
    b: out std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of neg32 is
    component com32
    port (
        x: in std_logic_vector (31 downto 0);
        y: out std_logic_vector (31 downto 0)
    );
    end component;

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal c: std_logic_vector (31 downto 0);
    signal d: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg32_generate_1: FOR i IN 31 DOWNTO 0 GENERATE
        d (i) <= '0';
    END GENERATE;
    s <= '1';
    com: com32 PORT MAP (x=>a, y=>c);
    add: ripplecarrychainadder32 PORT MAP (b=>d, a=>c, s=>s, t=>t, c=>b);
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of sub32 is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component neg32
    port (
        b: out std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg: neg32 PORT MAP (a=>a, b=>x);
    add: ripplecarrychainadder32 PORT MAP (b=>b, a=>x, c=>c, s=>s, t=>t);
    s <= '0';
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32testbench is
port (
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;


architecture behaviour of sub32testbench is
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal a: std_logic_vector (31 downto 0);
    signal b: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    sub: sub32 PORT MAP (a=>a, b=>b, c=>c, t=>t);

    a <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 0 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 10 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 20 ns;
    b <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','1','1', '1','0','0','1', '1','1','1','0', '0','1','1','1') after 0 ns,  ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 10 ns, ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','1','0','0', '1','0','1','1', '0','0','0','1' ,'0','0','1','1') after 20 ns;
    s <= '0' after 0 ns, '1' after 10 ns;
    -- 19219 - 14823 =
end;

library ieee;
use ieee.std_logic_1164.all;

entity or32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of or32 is
begin
    genor32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) or a (i);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity and32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of and32 is
begin
    genand32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) and a (i);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;


    entity sram is
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of sram is
    begin
        readdata <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    end;


library ieee;
use ieee.std_logic_1164.all;


    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of prom is
    begin
        readdata <= ('0','0','1','0','0','0',   '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','0');
    end;


library ieee;
use ieee.std_logic_1164.all;

entity ALU is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic_vector (2 downto 0);
    t: out std_logic;
    nul: inout std_logic;
    globalcarryflag: out std_logic
);
end;

architecture behaviour of ALU is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    component and32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component or32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal z4, z3, z2, z1: std_logic;
    signal x3, x2, x1: std_logic;
    signal csub: std_logic_vector (31 downto 0);
    signal cor: std_logic_vector (31 downto 0);
    signal cmux1: std_logic_vector (31 downto 0);
    signal cmux2: std_logic_vector (31 downto 0);
    signal cadd: std_logic_vector (31 downto 0);
    signal cand:  std_logic_vector (31 downto 0);
    signal sadd: std_logic;
    signal d: std_logic_vector (31 downto 0);
begin
    -- 010 add
    -- 110 sub
    -- 000 and
    -- 001 or
    -- 111 slt set less than
    mux1: MUX32_2_1 PORT MAP (a=>cadd, b=>csub, c=>cmux1, x=>x1);
    mux2: MUX32_2_1 PORT MAP (a=>cand, b=>cor, c=>cmux2, x=>x2);
    mux3: MUX32_2_1 PORT MAP (a=>cmux1, b=>cmux2, c=>d, x=>x3);
    add1: ripplecarrychainadder32 PORT MAP (a=>a, b=>b, s=>sadd, t=>globalcarryflag, c=>cadd);
    sub1: sub32 PORT MAP (a=>a, b=>b, t=>globalcarryflag, c=>csub);
    and1: and32 PORT MAP (a=>a, b=>b, c=>cand);
    or1: or32 PORT MAP (a=>a, b=>b, c=>cor);

    z1 <= (not s (2) and s (1) and not s (0));
    z2 <= (s(2) and s(1) and not s(0));
    z3 <= (not s (2) and not s (1) and not s (0));
    z4 <= (not s (2) and not s (1) and s (0));

    --
    -- z4  z3  z2  z1       x3  x2  x1
    -- 0   0   0   1        0   x   0
    -- 0   0   1   0        0   x   1
    -- 0   1   0   0        1   0   x
    -- 1   0   0   0        1   1   x

    -- x3 <= z3 or z4
    -- x2 <= z3
    -- x1 <= z2

    x3 <= z3 or z4;
    x2 <= z4;
    x1 <= z2;
    sadd <= '0';
    c <= d;
    nul <= d (31);
    testnull: FOR i IN 30 DOWNTO 0 GENERATE
        nul <= d (i) nor nul;
    END GENERATE;
end;

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;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1;
        regwrite <= x0 or x1;

        -- aluop
        -- 00 -- add
        -- 01 -- sub
        -- 10 -- nutze das func feld
        -- 11

        aluop (1) <= x0 or not x1;
        aluop (0) <= x0 or not x1;
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
        signal x1, x0: std_logic;
    begin
        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';
        x1 <= (not aluop (1) and not aluop (0));
        aluoperation (2) <= x0;
        aluoperation (1) <= x0 or x1;
        aluoperation (0) <= x0;

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

    end;

library ieee;
use ieee.std_logic_1164.all;


    entity Bit2Shift is
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of Bit2Shift is
    begin
        b (31 downto 2)  <=  a (29 downto 0);
        b (1 downto 0) <= ('0', '0');
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity signunit is
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of signunit is
    begin
        b (31 downto 16) <=   ('0','0','0','0',   '0','0','0','0',   '0','0','0','0',   '0','0','0','0');
        b (15 downto 0) <= a;
    end;


library ieee;
use ieee.std_logic_1164.all;

entity mips32 is
port (
    globalCPUCLK: in std_logic
);
end;

architecture behaviour of mips32 is
    component registerset32_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (4 downto 0);
        regsrc2: in std_logic_vector (4 downto 0);
        regdest: in std_logic_vector (4 downto 0);
        en: in std_logic;
        clk: in std_logic;
        reset: in std_logic
    );
    end component;

    component ALU
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic_vector (2 downto 0);
        t: out std_logic;
        nul: inout std_logic;
        globalcarryflag: out std_logic
    );
    end component;

    -- 4 x MUX

    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;

    component MUX5_2_1
    port (
        c: out std_logic_vector (4 downto 0);
        b: in std_logic_vector (4 downto 0);
        a: in std_logic_vector (4 downto 0);
        x: in std_logic
    );
    end component;

    -- befehlszaehler, addierer + 4 u Sprung 2x Addierer

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;

    component Bit2Shift
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component signunit
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component sram
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end component;

    component prom
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end component;

    component reg32
    port (
        q: out std_logic_vector (31 downto 0);
        d: in std_logic_vector (31 downto 0);
        c: in std_logic;
        reset: in std_logic
    );
    end component;

    component opdecode
    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 component;

    component funcdecode
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end component;

    signal op: std_logic_vector (31 downto 0);

    signal aluop: std_logic_vector (1 downto 0);
    signal func: std_logic_vector (5 downto 0);
    signal aluoperation: std_logic_vector (2 downto 0);
    signal memtoreg: std_logic;
    signal memwrite: std_logic;
    signal branch: std_logic;
    signal alusrc: std_logic;
    signal regdst: std_logic;
    signal regwrite: std_logic;

    signal pcsrc: std_logic;

    signal regdest: std_logic_vector (4 downto 0);
    signal aALUOperandBus, bALUOperandBUS, cALUOperandBus: std_logic_vector (31 downto 0);
    signal signunitBUS: std_logic_vector (31 downto 0);
    signal memReadData: std_logic_vector (31 downto 0);
    signal destdata: std_logic_vector (31 downto 0);
    signal srcdata1: std_logic_vector (31 downto 0);
    signal srcdata2: std_logic_vector (31 downto 0);

    signal nulbit: std_logic;

    signal pcBUSplus: std_logic_vector (31 downto 0);
    signal pcBUS: std_logic_vector (31 downto 0);

    signal Value32_4: std_logic_vector (31 downto 0);

    signal add1cBus: std_logic_vector (31 downto 0);
    signal add2cBus: std_logic_vector (31 downto 0);

    signal Bit2ShiftBus: std_logic_vector (31 downto 0);

    signal Value1_0: std_logic;

    signal nullbit: std_logic;

    signal globalCPUC: std_logic;

    signal reset: std_logic;
begin
    funcdecode1: funcdecode PORT MAP (aluoperation=>aluoperation,func=>func,aluop=>aluop);
    opdecode1: opdecode PORT MAP (opcode=>op(31 downto 26), aluop=>aluop, memtoreg => memtoreg, memwrite => memwrite, branch => branch, alusrc => alusrc, regdst => regdst, regwrite => regwrite);


    mux1: MUX5_2_1 PORT MAP (a=>op (20 downto 16), b=> op (15 downto 11), c=>regdest, x=>regdst);
    mux2: MUX32_2_1 PORT MAP (a=>srcdata1, b=>signunitBUS, c=>bALUOperandBUS, x=>alusrc);
    mux3: MUX32_2_1 PORT MAP (a=>cALUOperandBus, b=>memReadData, c=>destdata, x=>memtoreg);
    mux4: MUX32_2_1 PORT MAP (b=>add2cBus, a=>add1cBus, c=>pcBUSplus, x=>pcsrc);

    signunit1: signunit PORT MAP (a=>op (15 downto 0), b=>signunitBUS);
    Bit2Shift1: Bit2Shift PORT MAP (a=>signunitBUS, b=>Bit2ShiftBUS);

    add1: ripplecarrychainadder32 PORT MAP (a=>pcBUS, b=>Value32_4, c=>add1cBus, s=>Value1_0);
    add2: ripplecarrychainadder32 PORT MAP (a=>Bit2ShiftBus, b=>add1cBUS, c=>add2cBUS, s=>Value1_0);

    pc: reg32 PORT MAP (q=>pcBUS, d=>pcBUSplus, c=>globalCPUC, reset=>reset);

    alu1: alu PORT MAP (a=>srcdata1, b=>bALUOperandBUS, c=>cALUOperandBus, s=>aluoperation, nul=>nullbit);
    regset1: registerset32_32 PORT MAP (regdest=>regdest, destdata=>destdata, srcdata1=>srcdata1, srcdata2=>srcdata2, en=>regwrite, regsrc1=>op (25 downto 21), regsrc2=>op (20 downto 16), reset=>reset, clk=>globalCPUC);

    sram1: sram PORT MAP (en=>memwrite, addrs=>cALUOperandBus, writedata=>srcdata2, readdata=>memReadData);
    prom1: prom PORT MAP (addrs=>pcBUS, readdata=>op);

    pcsrc <= nullbit and branch;

    Value32_4 <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    Value1_0 <= '0';

    reset <= '1' after 0 ns, '0' after 2 ns;
    globalCPUC <= '1' after 0 ns, '0' after 1 ns, '1' after 2 ns, '0' after 3 ns, '1' after 4 ns, '0' after 5 ns, '1' after 6 ns, '0' after 7 ns, '1' after 8 ns, '0' after 9 ns, '1' after 10 ns;
end;
Attachments
Screenshot_20241205_013259.png
Screenshot_20241205_013259.png (48.09 KiB) Viewed 299 times
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

-- mein programmspeicher liefert uebrigens, das da
    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;
    architecture behaviour of prom is
    begin
        readdata <= ('0','0','1','0','0','0',   '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','0');
    end;
    
    


wenn ich das durch

Code: Select all

    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0)
    );
    end;
    architecture behaviour of prom is
    begin
        readdata <= ('0','0','1','0','0','0',   '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','1');
    end;
-- ersetze zaehlen wir dreierschritte

david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

-- (C) David Vajda
-- MIPS32 - minimal
-- 2024-12-04

library ieee;
use ieee.std_logic_1164.all;

entity rslatch is
port (
    r: in std_logic;
    s: in std_logic;
    q: inout std_logic;
    p: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of rslatch is
begin
    q   <=  (r nor p) and not reset;
    p   <=  (s nor q);
end;

library ieee;
use ieee.std_logic_1164.all;

entity clktriggeredrslatch is
port (
    r: in std_logic;
    s: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of clktriggeredrslatch is
    component rslatch
    port (
        r: in std_logic;
        s: in std_logic;
        q: inout std_logic;
        p: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, d: std_logic;
begin
    rs: rslatch PORT MAP (r=>e, s=>d, q=>q, reset=>reset);
    d <= c and s;
    e <= c and r;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dlatch is
    component clktriggeredrslatch
    port (
        r: in std_logic;
        s: in std_logic;
        c: in std_logic;
        q: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, f: std_logic;
begin
    clkrs: clktriggeredrslatch PORT MAP (r=>f, s=>e, c=>c, q=>q, reset=>reset);

    e <= d;
    f <= not d;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dff is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dff is
    component dlatch
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal e, a, b: std_logic;
begin
    d1: dlatch PORT MAP (c=>a, d=>e, q=>q, reset=>reset);
    d2: dlatch PORT MAP (c=>b, d=>d, q=>e, reset=>reset);
    a <= not c;
    b <= c;
end;

library ieee;
use ieee.std_logic_1164.all;

entity reg32 is
port (
    c: in std_logic;
    d: in std_logic_vector (31 downto 0);
    q: out std_logic_vector (31 downto 0);
    reset: in std_logic
);
end;

architecture behaviour of reg32 is
    component dff
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal p: std_logic_vector (31 downto 0);
begin
    gen_reg: FOR i in 31 downto 0 generate
        dffx: dff PORT MAP (q=>p(i),d=>d(i),c=>c, reset=>reset);
        q(i) <= p (i);
    end generate;
end;

library ieee;
use ieee.std_logic_1164.all;

entity MUX32_2_1 is
port (
    c: out std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX32_2_1 is
begin
    MUX_generate: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity MUX5_2_1 is
port (
    c: out std_logic_vector (4 downto 0);
    b: in std_logic_vector (4 downto 0);
    a: in std_logic_vector (4 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX5_2_1 is
begin
    MUX_generate: FOR i IN 4 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regsrc2: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    srcmux2: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata2, x=>regsrc2);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity registerset4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regsrc2: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regsrc2: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (1));
    reg1: registerset2_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    reg2: registerset2_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity registerset8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regsrc2: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regsrc2: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (2));
    reg1: registerset4_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    reg2: registerset4_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity registerset16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regsrc2: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regsrc2: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (3));
    reg1: registerset8_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    reg2: registerset8_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regsrc2: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regsrc2: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (4));
    reg1: registerset16_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    reg2: registerset16_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;





----------- SRAM

library ieee;
use ieee.std_logic_1164.all;

entity sram2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity sram4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    ram1: sram2_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    ram2: sram2_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity sram8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    ram1: sram4_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    ram2: sram4_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity sram16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    ram1: sram8_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    ram2: sram8_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity sram32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    ram1: sram16_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    ram2: sram16_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;










-- (C) David Vajda
-- 32 Bit Ripple Carry Chain Adder / Subtrahierer / Volladdierer
-- 2024-12-02

library ieee;
use ieee.std_logic_1164.all;

entity fulladder is
port (
    a: in std_logic;
    b: in std_logic;
    c: out std_logic;
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of fulladder is
begin
    c <= a xor b xor s;
    t <= (a and b) or ((a or b) and s);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of ripplecarrychainadder32 is
    component fulladder
    port (
        a: in std_logic;
        b: in std_logic;
        c: out std_logic;
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (32 downto 0);
begin
        fa_loop: FOR i IN 31 DOWNTO 0 GENERATE
            fa: fulladder PORT MAP (a=>a(i), b=>b(i), c=>c(i), s=>x(i), t=>x(i+1));
        END GENERATE;
        t <= x (32) ;
        x (0) <= s;
    --fa3: fulladder20241128 PORT MAP (a=>a3, b=>b3, c=>c3, s=>s3, t=>t);
    --fa2: fulladder20241128 PORT MAP (a=>a2, b=>b2, c=>c2, s=>s2, t=>s3);
    --fa1: fulladder20241128 PORT MAP (a=>a1, b=>b1, c=>c1, s=>s1, t=>s2);
    --fa0: fulladder20241128 PORT MAP (a=>a0, b=>b0, c=>c0, s=>s, t=>s1);
end;


library ieee;
use ieee.std_logic_1164.all;

entity com32 is
port (
    x: in std_logic_vector (31 downto 0);
    y: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of com32 is
begin
        com_connect: FOR i IN 31 DOWNTO 0 GENERATE
                y (i) <= not x (i);
        END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity neg32 is
port (
    b: out std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of neg32 is
    component com32
    port (
        x: in std_logic_vector (31 downto 0);
        y: out std_logic_vector (31 downto 0)
    );
    end component;

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal c: std_logic_vector (31 downto 0);
    signal d: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg32_generate_1: FOR i IN 31 DOWNTO 0 GENERATE
        d (i) <= '0';
    END GENERATE;
    s <= '1';
    com: com32 PORT MAP (x=>a, y=>c);
    add: ripplecarrychainadder32 PORT MAP (b=>d, a=>c, s=>s, t=>t, c=>b);
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of sub32 is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component neg32
    port (
        b: out std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg: neg32 PORT MAP (a=>a, b=>x);
    add: ripplecarrychainadder32 PORT MAP (b=>b, a=>x, c=>c, s=>s, t=>t);
    s <= '0';
end;


library ieee;
use ieee.std_logic_1164.all;

entity or32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of or32 is
begin
    genor32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) or a (i);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity and32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of and32 is
begin
    genand32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) and a (i);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;


    entity sram is
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic;
        reset: in std_logic
    );
    end;

    architecture behaviour of sram is
        component sram32_32
        port (
            srcdata1: out std_logic_vector (31 downto 0);
            destdata: in std_logic_vector (31 downto 0);
            regsrc1: in std_logic_vector (4 downto 0);
            regdest: in std_logic_vector (4 downto 0);
            en: in std_logic;
            reset: in std_logic;
            clk: in std_logic
        );
        end component;
    begin
        sram1: sram32_32 PORT MAP (en=>en, clk=>clk, reset=>reset, srcdata1=>readdata, destdata=>writedata, regsrc1=>addrs  (4 downto 0), regdest=>addrs (4 downto 0));
    end;


library ieee;
use ieee.std_logic_1164.all;


    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic
    );
    end;

    architecture behaviour of prom is
    begin
        readdata <= ('0','0','1','0','0','0',   '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','0');
    end;


library ieee;
use ieee.std_logic_1164.all;

entity ALU is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic_vector (2 downto 0);
    t: out std_logic;
    nul: inout std_logic;
    globalcarryflag: out std_logic
);
end;

architecture behaviour of ALU is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    component and32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component or32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal z4, z3, z2, z1: std_logic;
    signal x3, x2, x1: std_logic;
    signal csub: std_logic_vector (31 downto 0);
    signal cor: std_logic_vector (31 downto 0);
    signal cmux1: std_logic_vector (31 downto 0);
    signal cmux2: std_logic_vector (31 downto 0);
    signal cadd: std_logic_vector (31 downto 0);
    signal cand:  std_logic_vector (31 downto 0);
    signal sadd: std_logic;
    signal d: std_logic_vector (31 downto 0);
begin
    -- 010 add
    -- 110 sub
    -- 000 and
    -- 001 or
    -- 111 slt set less than
    mux1: MUX32_2_1 PORT MAP (a=>cadd, b=>csub, c=>cmux1, x=>x1);
    mux2: MUX32_2_1 PORT MAP (a=>cand, b=>cor, c=>cmux2, x=>x2);
    mux3: MUX32_2_1 PORT MAP (a=>cmux1, b=>cmux2, c=>d, x=>x3);
    add1: ripplecarrychainadder32 PORT MAP (a=>a, b=>b, s=>sadd, t=>globalcarryflag, c=>cadd);
    sub1: sub32 PORT MAP (a=>a, b=>b, t=>globalcarryflag, c=>csub);
    and1: and32 PORT MAP (a=>a, b=>b, c=>cand);
    or1: or32 PORT MAP (a=>a, b=>b, c=>cor);

    z1 <= (not s (2) and s (1) and not s (0));
    z2 <= (s(2) and s(1) and not s(0));
    z3 <= (not s (2) and not s (1) and not s (0));
    z4 <= (not s (2) and not s (1) and s (0));

    --
    -- z4  z3  z2  z1       x3  x2  x1
    -- 0   0   0   1        0   x   0
    -- 0   0   1   0        0   x   1
    -- 0   1   0   0        1   0   x
    -- 1   0   0   0        1   1   x

    -- x3 <= z3 or z4
    -- x2 <= z3
    -- x1 <= z2

    x3 <= z3 or z4;
    x2 <= z4;
    x1 <= z2;
    sadd <= '0';
    c <= d;
    nul <= d (31);
    testnull: FOR i IN 30 DOWNTO 0 GENERATE
        nul <= d (i) nor nul;
    END GENERATE;
end;

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;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1;
        regwrite <= x0 or x1;

        -- aluop
        -- 00 -- add
        -- 01 -- sub
        -- 10 -- nutze das func feld
        -- 11

        aluop (1) <= x0 or not x1;
        aluop (0) <= x0 or not x1;
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
        signal x1, x0: std_logic;
    begin
        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';
        x1 <= (not aluop (1) and not aluop (0));
        aluoperation (2) <= x0;
        aluoperation (1) <= x0 or x1;
        aluoperation (0) <= x0;

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

    end;

library ieee;
use ieee.std_logic_1164.all;


    entity Bit2Shift is
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of Bit2Shift is
    begin
        b (31 downto 2)  <=  a (29 downto 0);
        b (1 downto 0) <= ('0', '0');
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity signunit is
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of signunit is
    begin
        b (31 downto 16) <=   ('0','0','0','0',   '0','0','0','0',   '0','0','0','0',   '0','0','0','0');
        b (15 downto 0) <= a;
    end;


library ieee;
use ieee.std_logic_1164.all;

entity mips32 is
port (
    globalCPUCLK: in std_logic
);
end;

architecture behaviour of mips32 is
    component registerset32_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (4 downto 0);
        regsrc2: in std_logic_vector (4 downto 0);
        regdest: in std_logic_vector (4 downto 0);
        en: in std_logic;
        clk: in std_logic;
        reset: in std_logic
    );
    end component;

    component ALU
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic_vector (2 downto 0);
        t: out std_logic;
        nul: inout std_logic;
        globalcarryflag: out std_logic
    );
    end component;

    -- 4 x MUX

    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;

    component MUX5_2_1
    port (
        c: out std_logic_vector (4 downto 0);
        b: in std_logic_vector (4 downto 0);
        a: in std_logic_vector (4 downto 0);
        x: in std_logic
    );
    end component;

    -- befehlszaehler, addierer + 4 u Sprung 2x Addierer

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;

    component Bit2Shift
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component signunit
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component sram
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        reset: in std_logic;
        clk: in std_logic
    );
    end component;

    component prom
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic
    );
    end component;

    component reg32
    port (
        q: out std_logic_vector (31 downto 0);
        d: in std_logic_vector (31 downto 0);
        c: in std_logic;
        reset: in std_logic
    );
    end component;

    component opdecode
    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 component;

    component funcdecode
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end component;

    signal op: std_logic_vector (31 downto 0);

    signal aluop: std_logic_vector (1 downto 0);
    signal func: std_logic_vector (5 downto 0);
    signal aluoperation: std_logic_vector (2 downto 0);
    signal memtoreg: std_logic;
    signal memwrite: std_logic;
    signal branch: std_logic;
    signal alusrc: std_logic;
    signal regdst: std_logic;
    signal regwrite: std_logic;

    signal pcsrc: std_logic;

    signal regdest: std_logic_vector (4 downto 0);
    signal aALUOperandBus, bALUOperandBUS, cALUOperandBus: std_logic_vector (31 downto 0);
    signal signunitBUS: std_logic_vector (31 downto 0);
    signal memReadData: std_logic_vector (31 downto 0);
    signal destdata: std_logic_vector (31 downto 0);
    signal srcdata1: std_logic_vector (31 downto 0);
    signal srcdata2: std_logic_vector (31 downto 0);

    signal nulbit: std_logic;

    signal pcBUSplus: std_logic_vector (31 downto 0);
    signal pcBUS: std_logic_vector (31 downto 0);

    signal Value32_4: std_logic_vector (31 downto 0);

    signal add1cBus: std_logic_vector (31 downto 0);
    signal add2cBus: std_logic_vector (31 downto 0);

    signal Bit2ShiftBus: std_logic_vector (31 downto 0);

    signal Value1_0: std_logic;

    signal nullbit: std_logic;

    signal globalCPUC: std_logic;

    signal reset: std_logic;
begin
    funcdecode1: funcdecode PORT MAP (aluoperation=>aluoperation,func=>func,aluop=>aluop);
    opdecode1: opdecode PORT MAP (opcode=>op(31 downto 26), aluop=>aluop, memtoreg => memtoreg, memwrite => memwrite, branch => branch, alusrc => alusrc, regdst => regdst, regwrite => regwrite);


    mux1: MUX5_2_1 PORT MAP (a=>op (20 downto 16), b=> op (15 downto 11), c=>regdest, x=>regdst);
    mux2: MUX32_2_1 PORT MAP (a=>srcdata1, b=>signunitBUS, c=>bALUOperandBUS, x=>alusrc);
    mux3: MUX32_2_1 PORT MAP (a=>cALUOperandBus, b=>memReadData, c=>destdata, x=>memtoreg);
    mux4: MUX32_2_1 PORT MAP (b=>add2cBus, a=>add1cBus, c=>pcBUSplus, x=>pcsrc);

    signunit1: signunit PORT MAP (a=>op (15 downto 0), b=>signunitBUS);
    Bit2Shift1: Bit2Shift PORT MAP (a=>signunitBUS, b=>Bit2ShiftBUS);

    add1: ripplecarrychainadder32 PORT MAP (a=>pcBUS, b=>Value32_4, c=>add1cBus, s=>Value1_0);
    add2: ripplecarrychainadder32 PORT MAP (a=>Bit2ShiftBus, b=>add1cBUS, c=>add2cBUS, s=>Value1_0);

    pc: reg32 PORT MAP (q=>pcBUS, d=>pcBUSplus, c=>globalCPUC, reset=>reset);

    alu1: alu PORT MAP (a=>srcdata1, b=>bALUOperandBUS, c=>cALUOperandBus, s=>aluoperation, nul=>nullbit);
    regset1: registerset32_32 PORT MAP (regdest=>regdest, destdata=>destdata, srcdata1=>srcdata1, srcdata2=>srcdata2, en=>regwrite, regsrc1=>op (25 downto 21), regsrc2=>op (20 downto 16), reset=>reset, clk=>globalCPUC);

    sram1: sram PORT MAP (en=>memwrite, addrs=>cALUOperandBus, writedata=>srcdata2, readdata=>memReadData, clk=>globalCPUC, reset=>reset);
    prom1: prom PORT MAP (addrs=>pcBUS, readdata=>op, clk=>globalCPUC);

    pcsrc <= nullbit and branch;

    Value32_4 <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    Value1_0 <= '0';

    reset <= '1' after 0 ns, '0' after 2 ns;
    globalCPUC <= '1' after 0 ns, '0' after 1 ns, '1' after 2 ns, '0' after 3 ns, '1' after 4 ns, '0' after 5 ns, '1' after 6 ns, '0' after 7 ns, '1' after 8 ns, '0' after 9 ns, '1' after 10 ns;
end;
Attachments
Screenshot_20241205_073234.png
Screenshot_20241205_073234.png (53.2 KiB) Viewed 299 times
Screenshot_20241205_195813.png
Screenshot_20241205_195813.png (46.55 KiB) Viewed 299 times
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

-- (C) David Vajda
-- MIPS32 - minimal
-- 2024-12-04

library ieee;
use ieee.std_logic_1164.all;

entity rslatch is
port (
    r: in std_logic;
    s: in std_logic;
    q: inout std_logic;
    p: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of rslatch is
begin
    q   <=  (r nor p) and not reset;
    p   <=  (s nor q);
end;

library ieee;
use ieee.std_logic_1164.all;

entity clktriggeredrslatch is
port (
    r: in std_logic;
    s: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of clktriggeredrslatch is
    component rslatch
    port (
        r: in std_logic;
        s: in std_logic;
        q: inout std_logic;
        p: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, d: std_logic;
begin
    rs: rslatch PORT MAP (r=>e, s=>d, q=>q, reset=>reset);
    d <= c and s;
    e <= c and r;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dlatch is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dlatch is
    component clktriggeredrslatch
    port (
        r: in std_logic;
        s: in std_logic;
        c: in std_logic;
        q: inout std_logic;
        reset: in std_logic
    );
    end component;
    signal e, f: std_logic;
begin
    clkrs: clktriggeredrslatch PORT MAP (r=>f, s=>e, c=>c, q=>q, reset=>reset);

    e <= d;
    f <= not d;
end;

library ieee;
use ieee.std_logic_1164.all;

entity dff is
port (
    d: in std_logic;
    c: in std_logic;
    q: inout std_logic;
    reset: in std_logic
);
end;

architecture behaviour of dff is
    component dlatch
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal e, a, b: std_logic;
begin
    d1: dlatch PORT MAP (c=>a, d=>e, q=>q, reset=>reset);
    d2: dlatch PORT MAP (c=>b, d=>d, q=>e, reset=>reset);
    a <= not c;
    b <= c;
end;

library ieee;
use ieee.std_logic_1164.all;

entity reg32 is
port (
    c: in std_logic;
    d: in std_logic_vector (31 downto 0);
    q: out std_logic_vector (31 downto 0);
    reset: in std_logic
);
end;

architecture behaviour of reg32 is
    component dff
    port (
        q: inout std_logic;
        d: in std_logic;
        c: in std_logic;
        reset: in std_logic
    );
    end component;
    signal p: std_logic_vector (31 downto 0);
begin
    gen_reg: FOR i in 31 downto 0 generate
        dffx: dff PORT MAP (q=>p(i),d=>d(i),c=>c, reset=>reset);
        q(i) <= p (i);
    end generate;
end;

library ieee;
use ieee.std_logic_1164.all;

entity MUX32_2_1 is
port (
    c: out std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX32_2_1 is
begin
    MUX_generate: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity MUX5_2_1 is
port (
    c: out std_logic_vector (4 downto 0);
    b: in std_logic_vector (4 downto 0);
    a: in std_logic_vector (4 downto 0);
    x: in std_logic
);
end;

architecture behaviour of MUX5_2_1 is
begin
    MUX_generate: FOR i IN 4 DOWNTO 0 GENERATE
        c (i) <= (a (i) and not x) or (b (i) and x);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regsrc2: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    srcmux2: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata2, x=>regsrc2);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity registerset4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regsrc2: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regsrc2: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (1));
    reg1: registerset2_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    reg2: registerset2_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (0), regsrc2=>regsrc2 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity registerset8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regsrc2: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regsrc2: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (2));
    reg1: registerset4_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    reg2: registerset4_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (1 downto 0), regsrc2=>regsrc2 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity registerset16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regsrc2: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regsrc2: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (3));
    reg1: registerset8_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    reg2: registerset8_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (2 downto 0), regsrc2=>regsrc2 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity registerset32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    srcdata2: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regsrc2: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of registerset32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component registerset16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regsrc2: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
    signal srcdata2_1: std_logic_vector (31 downto 0);
    signal srcdata2_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    mux2: MUX32_2_1 PORT MAP (a=>srcdata2_1, b=>srcdata2_2, c=>srcdata2, x=>regsrc2 (4));
    reg1: registerset16_32 PORT MAP (srcdata1=>srcdata1_1, srcdata2=>srcdata2_1, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    reg2: registerset16_32 PORT MAP (srcdata1=>srcdata1_2, srcdata2=>srcdata2_2, regsrc1=>regsrc1 (3 downto 0), regsrc2=>regsrc2 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;





----------- SRAM

library ieee;
use ieee.std_logic_1164.all;

entity sram2_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic;
    regdest: in std_logic;
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram2_32 is
    component reg32
    port (
        c: in std_logic;
        d: in std_logic_vector (31 downto 0);
        q: out std_logic_vector (31 downto 0);
        reset: in std_logic
    );
    end component;
    component MUX32_2_1 is
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal q1: std_logic_vector (31 downto 0);
    signal q2: std_logic_vector (31 downto 0);
    signal c1, c2: std_logic;
begin
    reg1: reg32 PORT MAP (q=>q1,d=>destdata,c=>c1, reset=>reset);
    reg2: reg32 PORT MAP (q=>q2,d=>destdata,c=>c2, reset=>reset);
    srcmux1: MUX32_2_1 PORT MAP (a=>q1, b=>q2, c=>srcdata1, x=>regsrc1);
    c1 <= en and clk and not regdest;
    c2 <= en and clk and regdest;
end;


library ieee;
use ieee.std_logic_1164.all;


entity sram4_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (1 downto 0);
    regdest: in std_logic_vector (1 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram4_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram2_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic;
        regdest: in std_logic;
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (1));
    ram1: sram2_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (0), en=>en1, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    ram2: sram2_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (0), en=>en2, destdata=>destdata, regdest=>regdest (0), reset=>reset, clk=>clk);
    en2 <= regdest (1) and en;
    en1 <= not regdest (1) and en;
end;



library ieee;
use ieee.std_logic_1164.all;


entity sram8_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (2 downto 0);
    regdest: in std_logic_vector (2 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram8_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram4_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (1 downto 0);
        regdest: in std_logic_vector (1 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (2));
    ram1: sram4_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (1 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    ram2: sram4_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (1 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (1 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (2) and en;
    en1 <= not regdest (2) and en;
end;


library ieee;
use ieee.std_logic_1164.all;

entity sram16_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (3 downto 0);
    regdest: in std_logic_vector (3 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram16_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram8_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (2 downto 0);
        regdest: in std_logic_vector (2 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (3));
    ram1: sram8_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (2 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    ram2: sram8_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (2 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (2 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (3) and en;
    en1 <= not regdest (3) and en;
end;

library ieee;
use ieee.std_logic_1164.all;

entity sram32_32 is
port (
    srcdata1: out std_logic_vector (31 downto 0);
    destdata: in std_logic_vector (31 downto 0);
    regsrc1: in std_logic_vector (4 downto 0);
    regdest: in std_logic_vector (4 downto 0);
    en: in std_logic;
    reset: in std_logic;
    clk: in std_logic
);
end;

architecture behaviour of sram32_32 is
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    component sram16_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (3 downto 0);
        regdest: in std_logic_vector (3 downto 0);
        en: in std_logic;
        reset: in std_logic;
        clk: in std_logic
    );
    end component;
    signal c1, c2: std_logic;
    signal en1, en2: std_logic;
    signal srcdata1_1: std_logic_vector (31 downto 0);
    signal srcdata1_2: std_logic_vector (31 downto 0);
begin
    mux1: MUX32_2_1 PORT MAP (a=>srcdata1_1, b=>srcdata1_2, c=>srcdata1, x=>regsrc1 (4));
    ram1: sram16_32 PORT MAP (srcdata1=>srcdata1_1, regsrc1=>regsrc1 (3 downto 0), en=>en1, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    ram2: sram16_32 PORT MAP (srcdata1=>srcdata1_2, regsrc1=>regsrc1 (3 downto 0), en=>en2, destdata=>destdata, regdest=>regdest (3 downto 0), reset=>reset, clk=>clk);
    en2 <= regdest (4) and en;
    en1 <= not regdest (4) and en;
end;










-- (C) David Vajda
-- 32 Bit Ripple Carry Chain Adder / Subtrahierer / Volladdierer
-- 2024-12-02

library ieee;
use ieee.std_logic_1164.all;

entity fulladder is
port (
    a: in std_logic;
    b: in std_logic;
    c: out std_logic;
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of fulladder is
begin
    c <= a xor b xor s;
    t <= (a and b) or ((a or b) and s);
end;

library ieee;
use ieee.std_logic_1164.all;

entity ripplecarrychainadder32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic;
    t: out std_logic
);
end;

architecture behaviour of ripplecarrychainadder32 is
    component fulladder
    port (
        a: in std_logic;
        b: in std_logic;
        c: out std_logic;
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (32 downto 0);
begin
        fa_loop: FOR i IN 31 DOWNTO 0 GENERATE
            fa: fulladder PORT MAP (a=>a(i), b=>b(i), c=>c(i), s=>x(i), t=>x(i+1));
        END GENERATE;
        t <= x (32) ;
        x (0) <= s;
    --fa3: fulladder20241128 PORT MAP (a=>a3, b=>b3, c=>c3, s=>s3, t=>t);
    --fa2: fulladder20241128 PORT MAP (a=>a2, b=>b2, c=>c2, s=>s2, t=>s3);
    --fa1: fulladder20241128 PORT MAP (a=>a1, b=>b1, c=>c1, s=>s1, t=>s2);
    --fa0: fulladder20241128 PORT MAP (a=>a0, b=>b0, c=>c0, s=>s, t=>s1);
end;


library ieee;
use ieee.std_logic_1164.all;

entity com32 is
port (
    x: in std_logic_vector (31 downto 0);
    y: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of com32 is
begin
        com_connect: FOR i IN 31 DOWNTO 0 GENERATE
                y (i) <= not x (i);
        END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;

entity neg32 is
port (
    b: out std_logic_vector (31 downto 0);
    a: in std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of neg32 is
    component com32
    port (
        x: in std_logic_vector (31 downto 0);
        y: out std_logic_vector (31 downto 0)
    );
    end component;

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    signal c: std_logic_vector (31 downto 0);
    signal d: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg32_generate_1: FOR i IN 31 DOWNTO 0 GENERATE
        d (i) <= '0';
    END GENERATE;
    s <= '1';
    com: com32 PORT MAP (x=>a, y=>c);
    add: ripplecarrychainadder32 PORT MAP (b=>d, a=>c, s=>s, t=>t, c=>b);
end;

library ieee;
use ieee.std_logic_1164.all;

entity sub32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    t: out std_logic
);
end;

architecture behaviour of sub32 is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component neg32
    port (
        b: out std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    signal x: std_logic_vector (31 downto 0);
    signal s: std_logic;
begin
    neg: neg32 PORT MAP (a=>a, b=>x);
    add: ripplecarrychainadder32 PORT MAP (b=>b, a=>x, c=>c, s=>s, t=>t);
    s <= '0';
end;


library ieee;
use ieee.std_logic_1164.all;

entity or32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of or32 is
begin
    genor32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) or a (i);
    END GENERATE;
end;


library ieee;
use ieee.std_logic_1164.all;

entity and32 is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0)
);
end;

architecture behaviour of and32 is
begin
    genand32: FOR i IN 31 DOWNTO 0 GENERATE
        c (i) <= b (i) and a (i);
    END GENERATE;
end;

library ieee;
use ieee.std_logic_1164.all;


    entity sram is
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic;
        reset: in std_logic
    );
    end;

    architecture behaviour of sram is
        component sram32_32
        port (
            srcdata1: out std_logic_vector (31 downto 0);
            destdata: in std_logic_vector (31 downto 0);
            regsrc1: in std_logic_vector (4 downto 0);
            regdest: in std_logic_vector (4 downto 0);
            en: in std_logic;
            reset: in std_logic;
            clk: in std_logic
        );
        end component;
    begin
        sram1: sram32_32 PORT MAP (en=>en, clk=>clk, reset=>reset, srcdata1=>readdata, destdata=>writedata, regsrc1=>addrs  (4 downto 0), regdest=>addrs (4 downto 0));
    end;


library ieee;
use ieee.std_logic_1164.all;


    entity prom is
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic
    );
    end;

    architecture behaviour of prom is
    begin
        readdata <= ('0','0','1','0','0','0',   '0','0','0','0','0',  '0','0','0','0','0', '0','0','0','0','0','0','0','0','0','0','0','0','0','1','1','1') when addrs (4 downto 0) =  ('0','0','0','0','0') else ('0','0','1','0','0','0', '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1') when addrs (4 downto 0) =  ('0','0','1','0','0') else ('0','0','1','0','0','0', '0','0','0','0','0',  '0','0','0','0','0',  '0','0','0','0','0','0','0','0','0','0','1','1','1','1','1','1') when addrs (4 downto 0) =  ('0','1','0','0','0');
    end;


library ieee;
use ieee.std_logic_1164.all;

entity ALU is
port (
    a: in std_logic_vector (31 downto 0);
    b: in std_logic_vector (31 downto 0);
    c: out std_logic_vector (31 downto 0);
    s: in std_logic_vector (2 downto 0);
    t: out std_logic;
    nul: inout std_logic;
    globalcarryflag: out std_logic
);
end;

architecture behaviour of ALU is
    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;
    component sub32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        t: out std_logic
    );
    end component;
    component and32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component or32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0)
    );
    end component;
    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;
    signal z4, z3, z2, z1: std_logic;
    signal x3, x2, x1: std_logic;
    signal csub: std_logic_vector (31 downto 0);
    signal cor: std_logic_vector (31 downto 0);
    signal cmux1: std_logic_vector (31 downto 0);
    signal cmux2: std_logic_vector (31 downto 0);
    signal cadd: std_logic_vector (31 downto 0);
    signal cand:  std_logic_vector (31 downto 0);
    signal sadd: std_logic;
    signal d: std_logic_vector (31 downto 0);
begin
    -- 010 add
    -- 110 sub
    -- 000 and
    -- 001 or
    -- 111 slt set less than
    mux1: MUX32_2_1 PORT MAP (a=>cadd, b=>csub, c=>cmux1, x=>x1);
    mux2: MUX32_2_1 PORT MAP (a=>cand, b=>cor, c=>cmux2, x=>x2);
    mux3: MUX32_2_1 PORT MAP (a=>cmux1, b=>cmux2, c=>d, x=>x3);
    add1: ripplecarrychainadder32 PORT MAP (a=>a, b=>b, s=>sadd, t=>globalcarryflag, c=>cadd);
    sub1: sub32 PORT MAP (a=>a, b=>b, t=>globalcarryflag, c=>csub);
    and1: and32 PORT MAP (a=>a, b=>b, c=>cand);
    or1: or32 PORT MAP (a=>a, b=>b, c=>cor);

    z1 <= (not s (2) and s (1) and not s (0));
    z2 <= (s(2) and s(1) and not s(0));
    z3 <= (not s (2) and not s (1) and not s (0));
    z4 <= (not s (2) and not s (1) and s (0));

    --
    -- z4  z3  z2  z1       x3  x2  x1
    -- 0   0   0   1        0   x   0
    -- 0   0   1   0        0   x   1
    -- 0   1   0   0        1   0   x
    -- 1   0   0   0        1   1   x

    -- x3 <= z3 or z4
    -- x2 <= z3
    -- x1 <= z2

    x3 <= z3 or z4;
    x2 <= z4;
    x1 <= z2;
    sadd <= '0';
    c <= d;
    nul <= d (31);
    testnull: FOR i IN 30 DOWNTO 0 GENERATE
        nul <= d (i) nor nul;
    END GENERATE;
end;

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;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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 <= not opcode (5) and not opcode (4) and not opcode (3) and not opcode (2) and not opcode (1) and not opcode (0);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1; ---? Bei immidiate - 15:15 - ist aber x1
        regwrite <= x0 or x1 or x2;

        -- aluop
        -- 00 -- add
        -- 01 -- sub
        -- 10 -- nutze das func feld
        -- 11

        -- x1 x2    alup
        -- 0  0     xx
        -- 0  1     0
        -- 1  0     0
        -- 1  1     0

        aluop (1) <= not (x2 or x1);
        aluop (0) <= not (x2 or x1);
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
        signal x1, x0: std_logic;
    begin
        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';
        x1 <= (not aluop (1) and not aluop (0));
        aluoperation (2) <= x0;
        aluoperation (1) <= x0 or x1;
        aluoperation (0) <= x0;

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

    end;

library ieee;
use ieee.std_logic_1164.all;


    entity Bit2Shift is
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of Bit2Shift is
    begin
        b (31 downto 2)  <=  a (29 downto 0);
        b (1 downto 0) <= ('0', '0');
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity signunit is
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end;

    architecture behaviour of signunit is
    begin
        b (31 downto 16) <=   ('0','0','0','0',   '0','0','0','0',   '0','0','0','0',   '0','0','0','0');
        b (15 downto 0) <= a;
    end;


library ieee;
use ieee.std_logic_1164.all;

entity mips32 is
port (
    globalCPUCLK: in std_logic
);
end;

architecture behaviour of mips32 is
    component registerset32_32
    port (
        srcdata1: out std_logic_vector (31 downto 0);
        srcdata2: out std_logic_vector (31 downto 0);
        destdata: in std_logic_vector (31 downto 0);
        regsrc1: in std_logic_vector (4 downto 0);
        regsrc2: in std_logic_vector (4 downto 0);
        regdest: in std_logic_vector (4 downto 0);
        en: in std_logic;
        clk: in std_logic;
        reset: in std_logic
    );
    end component;

    component ALU
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic_vector (2 downto 0);
        t: out std_logic;
        nul: inout std_logic;
        globalcarryflag: out std_logic
    );
    end component;

    -- 4 x MUX

    component MUX32_2_1
    port (
        c: out std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        a: in std_logic_vector (31 downto 0);
        x: in std_logic
    );
    end component;

    component MUX5_2_1
    port (
        c: out std_logic_vector (4 downto 0);
        b: in std_logic_vector (4 downto 0);
        a: in std_logic_vector (4 downto 0);
        x: in std_logic
    );
    end component;

    -- befehlszaehler, addierer + 4 u Sprung 2x Addierer

    component ripplecarrychainadder32
    port (
        a: in std_logic_vector (31 downto 0);
        b: in std_logic_vector (31 downto 0);
        c: out std_logic_vector (31 downto 0);
        s: in std_logic;
        t: out std_logic
    );
    end component;

    component Bit2Shift
    port (
        a: in std_logic_vector (31 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component signunit
    port (
        a: in std_logic_vector (15 downto 0);
        b: out std_logic_vector (31 downto 0)
    );
    end component;

    component sram
    port (
        en: in std_logic;
        addrs: in std_logic_vector (31 downto 0);
        writedata: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        reset: in std_logic;
        clk: in std_logic
    );
    end component;

    component prom
    port (
        addrs: in std_logic_vector (31 downto 0);
        readdata: out std_logic_vector (31 downto 0);
        clk: in std_logic
    );
    end component;

    component reg32
    port (
        q: out std_logic_vector (31 downto 0);
        d: in std_logic_vector (31 downto 0);
        c: in std_logic;
        reset: in std_logic
    );
    end component;

    component opdecode
    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 component;

    component funcdecode
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (2 downto 0)
    );
    end component;

    signal op: std_logic_vector (31 downto 0);

    signal aluop: std_logic_vector (1 downto 0);
    signal func: std_logic_vector (5 downto 0);
    signal aluoperation: std_logic_vector (2 downto 0);
    signal memtoreg: std_logic;
    signal memwrite: std_logic;
    signal branch: std_logic;
    signal alusrc: std_logic;
    signal regdst: std_logic;
    signal regwrite: std_logic;

    signal pcsrc: std_logic;

    signal regdest: std_logic_vector (4 downto 0);
    signal aALUOperandBus, bALUOperandBUS, cALUOperandBus: std_logic_vector (31 downto 0);
    signal signunitBUS: std_logic_vector (31 downto 0);
    signal memReadData: std_logic_vector (31 downto 0);
    signal destdata: std_logic_vector (31 downto 0);
    signal srcdata1: std_logic_vector (31 downto 0);
    signal srcdata2: std_logic_vector (31 downto 0);

    signal nulbit: std_logic;

    signal pcBUSplus: std_logic_vector (31 downto 0);
    signal pcBUS: std_logic_vector (31 downto 0);

    signal Value32_4: std_logic_vector (31 downto 0);

    signal add1cBus: std_logic_vector (31 downto 0);
    signal add2cBus: std_logic_vector (31 downto 0);

    signal Bit2ShiftBus: std_logic_vector (31 downto 0);

    signal Value1_0: std_logic;

    signal nullbit: std_logic;

    signal globalCPUC: std_logic;

    signal reset: std_logic;
begin
    funcdecode1: funcdecode PORT MAP (aluoperation=>aluoperation,func=>func,aluop=>aluop);
    opdecode1: opdecode PORT MAP (opcode=>op(31 downto 26), aluop=>aluop, memtoreg => memtoreg, memwrite => memwrite, branch => branch, alusrc => alusrc, regdst => regdst, regwrite => regwrite);


    mux1: MUX5_2_1 PORT MAP (a=>op (20 downto 16), b=> op (15 downto 11), c=>regdest, x=>regdst);
    mux2: MUX32_2_1 PORT MAP (a=>srcdata1, b=>signunitBUS, c=>bALUOperandBUS, x=>alusrc);
    mux3: MUX32_2_1 PORT MAP (a=>cALUOperandBus, b=>memReadData, c=>destdata, x=>memtoreg);
    mux4: MUX32_2_1 PORT MAP (b=>add2cBus, a=>add1cBus, c=>pcBUSplus, x=>pcsrc);

    signunit1: signunit PORT MAP (a=>op (15 downto 0), b=>signunitBUS);
    Bit2Shift1: Bit2Shift PORT MAP (a=>signunitBUS, b=>Bit2ShiftBUS);

    add1: ripplecarrychainadder32 PORT MAP (a=>pcBUS, b=>Value32_4, c=>add1cBus, s=>Value1_0);
    add2: ripplecarrychainadder32 PORT MAP (a=>Bit2ShiftBus, b=>add1cBUS, c=>add2cBUS, s=>Value1_0);

    pc: reg32 PORT MAP (q=>pcBUS, d=>pcBUSplus, c=>globalCPUC, reset=>reset);

    alu1: alu PORT MAP (a=>srcdata1, b=>bALUOperandBUS, c=>cALUOperandBus, s=>aluoperation, nul=>nullbit);
    regset1: registerset32_32 PORT MAP (regdest=>regdest, destdata=>destdata, srcdata1=>srcdata1, srcdata2=>srcdata2, en=>regwrite, regsrc1=>op (25 downto 21), regsrc2=>op (20 downto 16), reset=>reset, clk=>globalCPUC);

    sram1: sram PORT MAP (en=>memwrite, addrs=>cALUOperandBus, writedata=>srcdata2, readdata=>memReadData, clk=>globalCPUC, reset=>reset);
    prom1: prom PORT MAP (addrs=>pcBUS, readdata=>op, clk=>globalCPUC);

    pcsrc <= nullbit and branch;

    Value32_4 <= ('0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0' ,'0','1','0','0');
    Value1_0 <= '0';

    reset <= '1' after 0 ns, '0' after 2 ns;
    globalCPUC <= '1' after 0 ns, '0' after 1 ns, '1' after 2 ns, '0' after 3 ns, '1' after 4 ns, '0' after 5 ns, '1' after 6 ns, '0' after 7 ns, '1' after 8 ns, '0' after 9 ns, '1' after 10 ns;
end;
Attachments
Screenshot_20241205_195813.png
Screenshot_20241205_195813.png (46.55 KiB) Viewed 299 times
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Vorzeichenerweiterungseinheit:

16 Bit relative Werte

16 Bit Zweierkomplement. Betrag: 15 Bit + 1 Bit Vorzeichen
15 Bit: 16384 = 16k

Vor und zurueck
oder positiv negativ immidiate

Aber 16 Bit Wert. wird zu 32, z.B. fuer Addition in ALU
Vorzeichenerweiterungseinheit: 16 bit unsigned kein problem zu 32 unsigned
aber 16 Bit zweierkomplement => vorzeichenerweiterungseinheit
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Befehle weiss ich auswendig

lb, lbu: laden eines bytes
lh, lhu: laden eines halbwortes
lw
ld*
la*
li*

sb
sh
sw
sd*

Lade und Speicherarchitektur

Laden - Load - Speicher-Register
Speichern - Store - Register-Speicher
MOVE - Register-Register
li, ldi, ... Laden eines direktwerts in ein Register, Konstante im Code

sb: Nicht speichern einer Konstante, sondern

rs, rt - immidiate

i-typ Befehl

R-Typ: rs, rt, rd - 2 x Quell Register, 1 x ziel
I-Typ: 1 Quellregister, 1 Zielregister, 1 zusaetzliche Konstante Rel Wert
J-Typ: J-Typ - Jump: Konstanter Langer Direktwert - Bei spruengen, nicht relativ vom aktuellen PC, sondern absoluter wert

I-Typ, bei lbu: nicht Konstante laden, - bu und b und ..., sondern Speicherstelle von der groesse byte, an der Stelle, rt - muss addressiert werden, rs - ziel Register, rt: Addresse im RAM von wo aus geladen und b - Speichergroesse, Konstante? Verschiebewert!
david
Site Admin
Posts: 27
Joined: Sat Sep 14, 2024 3:16 pm

Re: MIPS32 in VHDL

Post by david »

Code: Select all

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;
    begin
        --  addi
        --  001000 rs rt imm
        --  op5 op4 op3 op2 op1 op0
        --  0   0   1   0   0   0
        --  x0: nothing
        --  x1: addi
        --  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)
        --  memtoreg <= x0 or ...;
        --  memwrite <= x0 or ...;
        --  branch <= x0 or ...;
        --  ...
        --  (regdst: Bit 20 bis 16) immdiate - rs, rt, rd oder rs, rd/tr immidiate

        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 <= not opcode (5) and not opcode (4) and not opcode (3) and not opcode (2) and not opcode (1) and not opcode (0);
        memtoreg <= x0;
        memwrite <= x0;
        branch <= x0;
        alusrc <= x0 or x1;
        regdst <= x0 or not x1; ---? Bei immidiate - 15:15 - ist aber x1
        regwrite <= x0 or x1 or x2;

        -- aluop
        -- 00 -- add
        -- 01 -- sub
        -- 10 -- nutze das func feld
        -- 11

        -- x1 x2    alup
        -- 0  0     xx
        -- 0  1     0
        -- 1  0     0
        -- 1  1     0

        aluop (1) <= not (x2 or x1);
        aluop (0) <= not (x2 or x1);
    end;

library ieee;
use ieee.std_logic_1164.all;


    entity funcdecode is
    port (
        aluop: in std_logic_vector (1 downto 0);
        func: in std_logic_vector (5 downto 0);
        aluoperation: out std_logic_vector (3 downto 0)
    );
    end;

    architecture behaviour of funcdecode is
        signal x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12: std_logic;s
    begin

        -- 00 add
        -- 01 sub
        -- 10 nutze das func feld

        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- add
        x0 <= '0';

        -- x1 : add
        -- x2 : sub
        -- x3 : and
        -- x4 : or
        -- x5 : nor
        -- x6 : slt
        -- x7 : xor
        -- x8 : sll
        -- x9 : srl
        -- x10: sra
        -- x11: mult
        -- x12: div

        -- aluop: 10 ...
        -- ... func:
        -- 100 000 - add 4 0
        -- 100 010 - sub 4 2
        -- 100 100 - and 4 4
        -- 100 101 - or  4 5
        -- 100 111 - nor 4 7
        -- 101 010 - slt 5 2
        -- 100 110 - xor 4 6
        -- 000 000 - sll 0 0
        -- 000 011 - sra 0 3
        -- 000 010 - srl 0 2
        -- 011 000 - mult 3 0
        -- 011 010 - div 3 2


        x1 <= (not aluop (1) and not aluop (0)) or
                (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and not func (2) and not func (1) and not func (0); -- add
        x2 <= (not aluop (1) and aluop (0)) or
                (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and not func (2) and func (1) and not func (0); -- sub
        x3 <= (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and func (2) and not func (1) and not func (0); -- and
        x4 <= (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and func (2) and not func (1) and func (0); -- or
        x5 <= (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and not func (2) and func (1) and not func (0); -- slt
        x6 <= (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and func (2) and func (1) and func (0); -- nor
        x7 <= (alup (1) and not alup (0) and func (5) and not func (4) and not func (3) and func (2) and func (1) and not func (0); -- xor
        x8 <= (alup (1) and not alup (0) and not func (5) and not func (4) and not func (3) and not func (2) and not func (1) and not func (0); -- sll
        x9 <= (alup (1) and not alup (0) and not func (5) and not func (4) and not func (3) and not func (2) and func (1) and func (0); -- sra
        x10 <= (alup (1) and not alup (0) and not func (5) and not func (4) and not func (3) and not func (2) and func (1) and not func (0); -- srl
        x11 <= (alup (1) and not alup (0) and not func (5) and func (4) and func (3) and not func (2) and not func (1) and not func (0); -- mult
        x12 <= (alup (1) and not alup (0) and not func (5) and func (4) and func (3) and not func (2) and func (1) and not func (0); -- div

        -- also
        --  a1  a0      ao2     ao1     ao0
        --  0   0       0       1       0
        --  0   1       1       1       0
        -- ... func feld

        -- 010 - add
        -- 110 - sub
        -- 000 - and
        -- 001 - or
        -- 111 - slt

        -- vier bit
        -- 0010 - add
        -- 0110 - sub
        -- 0000 - and
        -- 0001 - or
        -- 1111 - slt

        -- selber erweitert:
        -- x
        -- 3    0 0 0 0     and
        -- 4    0 0 0 1     or
        -- 1    0 0 1 0     add
        -- 7    0 0 1 1     xor
        -- 12   0 1 0 0     div
        -- 6    0 1 0 1     nor
        -- 2    0 1 1 0     sub
        -- 8    0 1 1 1     sll
        -- 9    1 0 0 0     sra
        -- 10   1 0 0 1     srl
        -- 11   1 0 1 0     mult
        -- 5    1 1 1 1     slt

        aluoperation (3) <= x0 or x9 or x10 or x11 or x5
        aluoperation (2) <= x0 or x12 or x6 or x2 or x8 or x5
        aluoperation (1) <= x0 or x1 or x7 or x2 or x8 or x11 or x5
        aluoperation (0) <= x0 or x4 or x7 or x6 or x8 or x10 or x5

    end;
Post Reply