diff options
Diffstat (limited to 'works/life/computer-organization-experiment')
15 files changed, 826 insertions, 0 deletions
diff --git a/works/life/computer-organization-experiment/.gitignore b/works/life/computer-organization-experiment/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/works/life/computer-organization-experiment/.gitignore @@ -0,0 +1 @@ +build
\ No newline at end of file diff --git a/works/life/computer-organization-experiment/Makefile b/works/life/computer-organization-experiment/Makefile new file mode 100644 index 0000000..0b4db7f --- /dev/null +++ b/works/life/computer-organization-experiment/Makefile @@ -0,0 +1,51 @@ +build/cpu_test_bench: build/cpu.o +	ghdl elaborate -g --std=08 --workdir=build -fsynopsys -o build/cpu_test_bench cpu_test_bench  + +build/cpu.o: build cpu.vhdl +	ghdl analyze -g --std=08 --workdir=build -fsynopsys cpu.vhdl + +all: build/test_bench + +build: +	mkdir -p build + +build/adder_1.o: build adder_1.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys adder_1.vhdl + +build/adder_8.o: build adder_8.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys adder_8.vhdl + +build/adder_32.o: build adder_32.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys adder_32.vhdl + +build/alu.o: build alu.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys alu.vhdl + +build/counter_4.o: build counter_4.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys counter_4.vhdl + +build/full_adder_1.o: build full_adder_1.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys full_adder_1.vhdl + +build/multiplexer_1_2.o: build multiplexer_1_2.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_1_2.vhdl + +build/multiplexer_8_2.o: build multiplexer_8_2.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_8_2.vhdl + +build/multiplexer_32_2.o: build multiplexer_32_2.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_32_2.vhdl + +build/shift_32.o: build shift_32.vhdl +	ghdl analyze --std=08 --workdir=build -fsynopsys shift_32.vhdl + +build/test_bench.o: build test_bench.vhdl build/counter_4.o build/full_adder_1.o build/multiplexer_1_2.o build/multiplexer_8_2.o build/multiplexer_32_2.o build/adder_1.o build/adder_8.o build/adder_32.o build/shift_32.o build/alu.o +	ghdl analyze --std=08 --workdir=build -fsynopsys test_bench.vhdl + +build/test_bench: build/test_bench.o +	ghdl elaborate --std=08 --workdir=build -fsynopsys -o build/test_bench test_bench  + +.PHONY: all clean + +clean: +	rm -r build diff --git a/works/life/computer-organization-experiment/adder_1.vhdl b/works/life/computer-organization-experiment/adder_1.vhdl new file mode 100644 index 0000000..625aae4 --- /dev/null +++ b/works/life/computer-organization-experiment/adder_1.vhdl @@ -0,0 +1,13 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_1 is +    port (A, B, CIN:in std_logic; S, COUT: out std_logic); +end adder_1; + +architecture behavior of adder_1 is +begin +    S <= (A XOR B) XOR CIN; +    COUT <= (A AND B) OR (B AND CIN) OR (CIN AND A); +end behavior; diff --git a/works/life/computer-organization-experiment/adder_32.vhdl b/works/life/computer-organization-experiment/adder_32.vhdl new file mode 100644 index 0000000..f573f3f --- /dev/null +++ b/works/life/computer-organization-experiment/adder_32.vhdl @@ -0,0 +1,20 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_32 is +    port (A, B:in std_logic_vector(31 downto 0);  CIN:in std_logic; S: out std_logic_vector(31 downto 0); COUT: out std_logic); +end adder_32; + +architecture behavior of adder_32 is +    signal C : std_logic_vector(2 downto 0); +begin +    c0: entity work.adder_8 +        port map (A=>A(7 downto 0), B=>B(7 downto 0), CIN=>CIN, S=>S(7 downto 0), COUT=>C(0)); +    c1: entity work.adder_8 +        port map (A=>A(15 downto 8), B=>B(15 downto 8), CIN=>C(0), S=>S(15 downto 8), COUT=>C(1)); +    c2: entity work.adder_8 +        port map (A=>A(23 downto 16), B=>B(23 downto 16), CIN=>C(1), S=>S(23 downto 16), COUT=>C(2)); +    c3: entity work.adder_8 +        port map (A=>A(31 downto 24), B=>B(31 downto 24), CIN=>C(2), S=>S(31 downto 24), COUT=>COUT); +end behavior; diff --git a/works/life/computer-organization-experiment/adder_8.vhdl b/works/life/computer-organization-experiment/adder_8.vhdl new file mode 100644 index 0000000..840ee0d --- /dev/null +++ b/works/life/computer-organization-experiment/adder_8.vhdl @@ -0,0 +1,28 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_8 is +    port (A, B:in std_logic_vector(7 downto 0);  CIN:in std_logic; S: out std_logic_vector(7 downto 0); COUT: out std_logic); +end adder_8; + +architecture behavior of adder_8 is +    signal C : std_logic_vector(6 downto 0); +begin +    b0: entity work.adder_1 +        port map (A=>A(0), B=>B(0), CIN=>CIN, S=>S(0), COUT=>C(0)); +    b1: entity work.adder_1 +        port map (A=>A(1), B=>B(1), CIN=>C(0), S=>S(1), COUT=>C(1)); +    b2: entity work.adder_1 +        port map (A=>A(2), B=>B(2), CIN=>C(1), S=>S(2), COUT=>C(2)); +    b3: entity work.adder_1 +        port map (A=>A(3), B=>B(3), CIN=>C(2), S=>S(3), COUT=>C(3)); +    b4: entity work.adder_1 +        port map (A=>A(4), B=>B(4), CIN=>C(3), S=>S(4), COUT=>C(4)); +    b5: entity work.adder_1 +        port map (A=>A(5), B=>B(5), CIN=>C(4), S=>S(5), COUT=>C(5)); +    b6: entity work.adder_1 +        port map (A=>A(6), B=>B(6), CIN=>C(5), S=>S(6), COUT=>C(6)); +    b7: entity work.adder_1 +        port map (A=>A(7), B=>B(7), CIN=>C(6), S=>S(7), COUT=>COUT); +end behavior; diff --git a/works/life/computer-organization-experiment/counter_4.vhdl b/works/life/computer-organization-experiment/counter_4.vhdl new file mode 100644 index 0000000..23c1807 --- /dev/null +++ b/works/life/computer-organization-experiment/counter_4.vhdl @@ -0,0 +1,19 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +ENTITY counter_4 IS +  PORT (CLK:IN STD_LOGIC; +    CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); +END counter_4; +ARCHITECTURE behavior OF counter_4 IS +BEGIN +  PROCESS(CLK) +    VARIABLE CQI:STD_LOGIC_VECTOR(3 DOWNTO 0) := B"0000"; +  BEGIN +    IF CLK'EVENT AND CLK='1' THEN +      CQI := CQI + 1; +    END IF; +    CQ<=CQI; +  END PROCESS; +END behavior; diff --git a/works/life/computer-organization-experiment/cpu.vhdl b/works/life/computer-organization-experiment/cpu.vhdl new file mode 100644 index 0000000..7ca6d9e --- /dev/null +++ b/works/life/computer-organization-experiment/cpu.vhdl @@ -0,0 +1,476 @@ +library ieee; +use ieee.std_logic_1164.all; + +package cru is +    subtype word is std_logic_vector(31 downto 0); +    constant clock_time : time := 10 ns; +end package; + +library ieee; +use ieee.std_logic_1164.all; +use work.cru.all; + +entity generic_clock is +    generic(delay, interval: time); +    port(CLK: out std_logic); +end entity; + +architecture Behavioral of generic_clock is +    signal V : std_logic := '1'; +begin +    l: process is +    begin +        CLK <= '0'; +        wait for delay; +        loop +            CLK <= V; +            V <= not V; +            wait for interval; +        end loop; +    end process; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use work.cru.all; + +entity reg is +    port ( +        CLK: in std_logic; -- Rising edge -> Read; Falling edge -> Write. +        WRITE: in std_logic; -- If 1 then at falling edge of clock, W will be written. +        W_DATA: in word; -- The data to write. +        R_DATA: out word -- The data to read. +    ); +end entity; + +architecture Behavioral of reg is +    signal V: word := X"00000000"; +begin +    process(CLK) +    begin +        if rising_edge(CLK) then +            R_DATA <= V; +        end if; +        if falling_edge(CLK) and WRITE = '1' then +            V <= W_DATA; +        end if; +    end process; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.cru.all; + +entity register_file is +    port ( +        CLK: in std_logic; +        WRITE: in std_logic; +        R1, R2, W: in std_logic_vector(4 downto 0); +        WD: in std_logic_vector(31 downto 0); +        RD1, RD2: out std_logic_vector(31 downto 0) +    ); +end entity; + +architecture Behavioral of register_file is +    type reg_file_type is array (0 to 31) of word; +    signal reg_file: reg_file_type := (others => X"00000000"); +begin +    process (CLK) +    begin +        if rising_edge(CLK) then +            RD1 <= reg_file(to_integer(unsigned(R1))); +            RD2 <= reg_file(to_integer(unsigned(R2))); +        end if; +        if falling_edge(CLK) and WRITE = '1' then +            reg_file(to_integer(unsigned(W))) <= WD; +        end if; +    end process; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.cru.all; + +entity alu is +    port ( +        A, B: in std_logic_vector(31 downto 0); +        ALUC: in std_logic_vector(3 downto 0); +        S: out std_logic_vector(31 downto 0); +        Z: out std_logic +    ); +end entity; + +architecture Behavioral of alu is +begin +    S <= A + B when ALUC(2 downto 0) ?= B"000" +         else A - B when ALUC(2 downto 0) ?= B"010" +         else A and B when ALUC(2 downto 0) ?= B"100" +         else A or B when ALUC(2 downto 0) ?= B"101" +         else A xor B when ALUC(2 downto 0) ?= B"110" +         else std_logic_vector(signed(A) sll 16) and X"FFFF0000" when ALUC(2 downto 0) ?= B"110" +         else std_logic_vector(signed(A) sll to_integer(unsigned(B))) when ALUC ?= B"0011" +         else std_logic_vector(signed(A) srl to_integer(unsigned(B))) when ALUC ?= B"1011" +         else std_logic_vector(signed(A) sra to_integer(unsigned(B))) when ALUC ?= B"1111"; +    Z <= S ?= X"00000000" after 10 ps; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.cru.all; + +entity ram is +    port( +        CLK: in std_logic; +        R_DATA: out word; +        W_DATA: in word; +        ADDR: in word; +        READ: in std_logic; +        WRITE: in std_logic +    ); +end entity; + +architecture Behavioral of ram is +    type memory_type is array (0 to 16#30#) of word; +    signal memory: memory_type := ( +/* +                X"3c010000", +                X"34240080", +                X"20050004", +                X"0c000018", +                X"ac820000", +                X"8c890000", +                X"01244022", +                X"20050003", +                X"20a5ffff", +                X"34a8ffff", +                X"39085555", +                X"2009ffff", +                X"312affff", +                X"01493025", +                X"01494026", +                X"01463824", +                X"10a00001", +                X"08000008", +                X"2005ffff", +                X"000543c0", +                X"00084400", +                X"00084403", +                X"000843c2", +                X"08000017", +                X"00004020", +                X"8c890000", +                X"20840004", +                X"01094020", +                X"20a5ffff", +                X"14a0fffb", +                X"00081000", +                X"03e00008", +                X"000000A3", +                X"00000027", +                X"00000079", +                X"00000115", +*/ +                X"3C010000", +                X"3421004C", +                X"8C240000", +                X"20210004", +                X"8C250000", +                X"20210004", +                X"0C000009", +                X"AC230000", +                X"08000008", +                X"20020010", +                X"00001820", +                X"30A60001", +                X"10060001", +                X"00641820", +                X"00042040", +                X"00052842", +                X"2042FFFF", +                X"1440FFF9", +                X"03e00008", +                X"0000C9AE", +                X"0000F6E5", +                others => (others => '0') +        ); +begin +    l: process(CLK) is  +    begin +        if rising_edge(CLK) and READ = '1' then +            r_data <= memory(to_integer(unsigned(ADDR)) / 4); +        end if; +        if falling_edge(CLK) and WRITE = '1' then +            memory(to_integer(unsigned(ADDR)) / 4) <= w_data; +        end if; +    end process; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.cru.all; + +entity cpu is +end entity; + +architecture Behavioral of cpu is +    signal pc_clk: std_logic := '0'; +    signal reg_clk: std_logic := '0'; +    signal mem_clk: std_logic := '0'; + +    signal pc: word := X"00000000"; +    signal pc_to_write: word; + +    signal ins: word; + +    signal mem_addr: word; +    signal mem_r_data: word; +    signal mem_w_data: word; +    signal mem_read: std_logic := '0'; +    signal mem_write: std_logic := '0'; + +    signal WRITE_REG: std_logic := '0'; +    signal R1: std_logic_vector(4 downto 0) := B"00000"; +    signal R2: std_logic_vector(4 downto 0)  := B"00000"; +    signal W: std_logic_vector(4 downto 0)  := B"00000"; +    signal WD: std_logic_vector(31 downto 0) := X"00000000"; +    signal RD1: std_logic_vector(31 downto 0) := X"00000000"; +    signal RD2: std_logic_vector(31 downto 0) := X"00000000"; + +    signal A: std_logic_vector(31 downto 0) := X"00000000"; +    signal B: std_logic_vector(31 downto 0) := X"00000000"; +    signal ALUC: std_logic_vector(3 downto 0) := B"0000"; +    signal S: std_logic_vector(31 downto 0); +    signal Z: std_logic; +begin +    pc_clock: entity work.generic_clock +        generic map (delay => 1 ps, interval => clock_time) +        port map (CLK => pc_clk); + +    mem_clock: entity work.generic_clock +        generic map (delay => 1 ns, interval => clock_time / 2) +        port map (CLK => mem_clk); + +    reg_clock: entity work.generic_clock +        generic map (delay => 2 ns, interval => clock_time) +        port map (CLK => reg_clk); + +    pc_reg: entity work.reg +        port map ( +            CLK => pc_clk, +            WRITE => '1', +            R_DATA => pc, +            W_DATA => pc_to_write +        ); +     +    reg_file: entity work.register_file +        port map( +            CLK => reg_clk, +            WRITE => WRITE_REG, +            R1 => R1, +            R2 => R2, +            W => W, +            WD => WD, +            RD1 => RD1, +            RD2 => RD2 +        ); + +    alu: entity work.alu +        port map( +            A => A, +            B => B, +            ALUC => ALUC, +            S => S, +            Z => Z +        ); + +    ram: entity work.ram +        port map ( +            CLK => mem_clk, +            r_data => mem_r_data, +            w_data => mem_w_data, +            addr => mem_addr, +            READ => mem_read, +            WRITE => mem_write +        ); + +    logic: process is +    begin +        wait until rising_edge(pc_clk); + +        wait for 100 ps; + +        mem_read <= '1'; +        mem_addr <= pc; +        pc_to_write <= pc + 4; + +        wait for 1 ns; + +        ins <= mem_r_data; + +        wait for 100 ps; + +        if ins(31 downto 27) = B"00001" then -- j / jal, not read reg +            R1 <= (others => '0'); +            R2 <= (others => '0'); +        elsif ins(31 downto 26) = B"000000" then +            if ins(5) = '1' then +                R1 <= ins(25 downto 21); +                R2 <= ins(20 downto 16); +            elsif ins(3) = '0' then +                R1 <= ins(20 downto 16); +                R2 <= (others => '0'); +            else +                R1 <= ins(25 downto 21); +                R2 <= (others => '0'); +            end if; +        else +            if ins(31) = '1' then +                R1 <= ins(25 downto 21); +                R2 <= ins(20 downto 16); +            elsif ins(29 downto 26) = B"1111" then +                R1 <= (others => '0'); +                R2 <= (others => '0'); +            elsif ins(29) = '1' then +                R1 <= ins(25 downto 21); +                R2 <= (others => '0'); +            else +                R1 <= ins(25 downto 21); +                R2 <= ins(20 downto 16); +            end if; +        end if; + +        wait for 1 ns; + +        if ins(31 downto 27) = B"00001" then -- j / jal, not read reg + +            ALUC <= B"0011"; +            A <= (25 downto 0 => ins(25 downto 0), others => '0'); +            B <= X"00000002"; +        elsif ins(31 downto 26) = B"000000" then +            if ins(5) = '1' then +                ALUC <= ins(3 downto 0); +                A <= RD1; +                B <= RD2; +            elsif ins(3) = '0' then +                ALUC(3 downto 2) <= ins(1 downto 0); +                ALUC(1 downto 0) <= B"11"; +                A <= RD1; +                B <= (4 downto 0 => ins(10 downto 6), others => '0'); +            else +                ALUC <= (others => '0'); +                A <= (others => '0'); +                B <= (others => '0'); +            end if; +        else +            if ins(31) = '1' then +                ALUC <= B"0000"; +                A <= RD1; +                B <= (15 downto 0 => ins(15 downto 0), others => '0' ); +            elsif ins(29 downto 26) = B"1111" then +                ALUC <= (others => '0'); +                A <= (others => '0'); +                B <= (others => '0'); +            elsif ins(29) = '1' then +                ALUC <= ins(29 downto 26); +                A <= RD1; +                B(15 downto 0) <= ins(15 downto 0); +                if ins(15) = '0' then +                    B(31 downto 16) <= X"0000"; +                else +                    B(31 downto 16) <= X"FFFF"; +                end if; +            else +                ALUC <= B"0010"; +                A <= RD1; +                B <= RD2; +            end if; +        end if; + +        wait for 100 ps; + +        if ins(31 downto 27) = B"00001" then -- j / jal, not read reg +            if ins(26) = '1' then -- jal +                W <= B"11111"; +                WD <= pc + 4; +                WRITE_REG <= '1'; +            else +                WRITE_REG <= '0'; +            end if; +            pc_to_write <= S;  +        elsif ins(31 downto 26) = B"000000" then +            if ins(5) = '1' then +                WRITE_REG <= '1'; +                W <= ins(15 downto 11); +                WD <= S; +            elsif ins(3) = '0' then +                WRITE_REG <= '1'; +                W <= ins(15 downto 11); +                WD <= S; +            else +                WRITE_REG <= '0'; +                pc_to_write <= RD1; +            end if; +        else +            if ins(31) = '1' then +                if ins(29) = '1' then +                    R2 <= ins(20 downto 16); +                    mem_write <= '1'; +                    mem_addr <= S; +                    mem_w_data <= RD2; + +                    wait until falling_edge(mem_clk); + +                    wait for 100 ps; + +                    mem_write <= '0'; + +                else +                    W <= ins(20 downto 16); +                    mem_read <= '1'; +                    mem_addr <= S; + +                    wait until rising_edge(mem_clk); +                     +                    wait for 100 ps; + +                    WD <= mem_r_data; +                    WRITE_REG <= '1'; +                end if; +            elsif ins(29 downto 26) = B"1111" then +                WRITE_REG <= '1'; +                W <= ins(20 downto 16); +                WD(31 downto 16) <= ins(15 downto 0); +            elsif ins(29) = '1' then +                WRITE_REG <= '1'; +                W <= ins(20 downto 16); +                WD <= S; +            else +                WRITE_REG <= '0'; +                if Z = '1' xor ins(26) = '1' then +                    pc_to_write <= pc_to_write + to_integer(signed(ins(15 downto 0)) * 4); +                end if; +            end if; +        end if; +    end process; +end architecture; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.cru.all; + +entity cpu_test_bench is +end entity; + +architecture Behavioral of cpu_test_bench is +    signal CLK: std_logic; +begin +    cpu : entity work.cpu; +end architecture; diff --git a/works/life/computer-organization-experiment/full_adder_1.vhdl b/works/life/computer-organization-experiment/full_adder_1.vhdl new file mode 100644 index 0000000..9b269bf --- /dev/null +++ b/works/life/computer-organization-experiment/full_adder_1.vhdl @@ -0,0 +1,13 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity full_adder_1 is +    port (A, B, CI:in std_logic; S, CO: out std_logic); +end full_adder_1; + +architecture behavior of full_adder_1 is +begin +    S <= (A XOR B) XOR CI; +    CO <= (A AND B) OR (B AND CI) OR (CI AND A); +end architecture; diff --git a/works/life/computer-organization-experiment/multiplexer_1_2.vhdl b/works/life/computer-organization-experiment/multiplexer_1_2.vhdl new file mode 100644 index 0000000..1fdeb0f --- /dev/null +++ b/works/life/computer-organization-experiment/multiplexer_1_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_1_2 is +  port (A0, A1, S : in std_logic; Y: out std_logic); +end multiplexer_1_2; + +architecture behaviour of multiplexer_1_2 is +begin +  Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/works/life/computer-organization-experiment/multiplexer_32_2.vhdl b/works/life/computer-organization-experiment/multiplexer_32_2.vhdl new file mode 100644 index 0000000..1c7d626 --- /dev/null +++ b/works/life/computer-organization-experiment/multiplexer_32_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_32_2 is +  port (A0, A1 : in std_logic_vector(31 downto 0); S : in std_logic; Y : out std_logic_vector(31 downto 0)); +end multiplexer_32_2; + +architecture behaviour of multiplexer_32_2 is +begin +  Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/works/life/computer-organization-experiment/multiplexer_8_2.vhdl b/works/life/computer-organization-experiment/multiplexer_8_2.vhdl new file mode 100644 index 0000000..6be0bd2 --- /dev/null +++ b/works/life/computer-organization-experiment/multiplexer_8_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_8_2 is +  port (A0, A1 : in std_logic_vector(7 downto 0); S : in std_logic; Y : out std_logic_vector(7 downto 0)); +end multiplexer_8_2; + +architecture behaviour of multiplexer_8_2 is +begin +  Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/works/life/computer-organization-experiment/out.ghw b/works/life/computer-organization-experiment/out.ghw Binary files differnew file mode 100644 index 0000000..23af3af --- /dev/null +++ b/works/life/computer-organization-experiment/out.ghw diff --git a/works/life/computer-organization-experiment/out2.ghw b/works/life/computer-organization-experiment/out2.ghw Binary files differnew file mode 100644 index 0000000..8a5e9f8 --- /dev/null +++ b/works/life/computer-organization-experiment/out2.ghw diff --git a/works/life/computer-organization-experiment/shift_32.vhdl b/works/life/computer-organization-experiment/shift_32.vhdl new file mode 100644 index 0000000..5cb8425 --- /dev/null +++ b/works/life/computer-organization-experiment/shift_32.vhdl @@ -0,0 +1,23 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.numeric_std.all; + +entity shift_32 is +  port( +    D: in std_logic_vector(31 downto 0); +    SA: in std_logic_vector(4 downto 0); +    Right: in std_logic; +    Arith: in std_logic; +    SH: out std_logic_vector(31 downto 0) +  ); +end entity; + +architecture behavioral of shift_32 is +begin +  SH <=  +         std_logic_vector(signed(D) srl to_integer(unsigned(SA))) when Right = '1' and Arith = '0' +    else std_logic_vector(signed(D) sll to_integer(unsigned(SA))) when Right = '0' and Arith = '0' +    else std_logic_vector(signed(D) sra to_integer(unsigned(SA)))  when Right = '1' and Arith = '1' +    else std_logic_vector(signed(D) sla to_integer(unsigned(SA))) when Right = '0' and Arith = '1'; +end behavioral; diff --git a/works/life/computer-organization-experiment/test_bench.vhdl b/works/life/computer-organization-experiment/test_bench.vhdl new file mode 100644 index 0000000..d2910d7 --- /dev/null +++ b/works/life/computer-organization-experiment/test_bench.vhdl @@ -0,0 +1,146 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity test_bench is +end test_bench; + +architecture test_counter_4 of test_bench is +  signal CLK : STD_LOGIC; +  signal CQ: STD_LOGIC_VECTOR(3 DOWNTO 0); +begin +  counter: entity work.counter_4(behavior) +      port map (CLK, CQ); +  stimulus: process is +  begin +    for count_value in 0 to 2 ** 4 - 1 loop +      if count_value mod 2 = 0 then +        CLK <= '1'; +        wait for 5 ns; +      else +        CLK <= '0'; +        wait for 5 ns; +      end if; +    end loop; +  end process stimulus; +end architecture test_counter_4; + + +architecture test_full_adder_1 of test_bench is +  subtype v3 is std_logic_vector(2 downto 0); +  signal I: v3 := B"000"; +  signal S, CO : STD_LOGIC; +begin +  adder: entity work.full_adder_1(behavior) +      port map (I(2), I(1), I(0), S, CO); +  stimulus: process is +    variable ii : v3 := B"000"; +  begin +    loop +      ii := ii + 1; +      I <= ii; +      wait for 5 ns; +    end loop; +  end process stimulus; +end architecture test_full_adder_1; + +architecture test_multiplexer_32_2 of test_bench is +  signal A0: std_logic_vector(31 downto 0) := B"11111111111111111111111111111111"; +  signal A1: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; +  signal S: std_logic; +  signal Y: std_logic_vector(31 downto 0); +begin +  multiplexer: entity work.multiplexer_32_2(behaviour) +      port map (A0, A1, S, Y); +  stimulus: process is +  begin +    loop +      S <= '0'; +      wait for 5 ns; +      S <= '1'; +      wait for 5 ns; +    end loop; +  end process stimulus; +end architecture test_multiplexer_32_2; + +architecture test_adder_32 of test_bench is +  signal A: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; +  signal B: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; +  signal CIN: std_logic; +  signal S: std_logic_vector(31 downto 0); +  signal COUT: std_logic; +begin +  adder: entity work.adder_32(behavior) +      port map (A, B, CIN, S, COUT); +  stimulus: process is +  begin +    loop +      A <= A + 1; +      B <= B + 2; +      CIN <= '0'; +      wait for 5 ns; +      CIN <= '1'; +      wait for 5 ns; +    end loop; +  end process stimulus; +end architecture test_adder_32; + +architecture test_shift_32 of test_bench is +  signal D: std_logic_vector(31 downto 0) := B"00000000000000000000000000000011"; +  signal SA: std_logic_vector(4 downto 0) := B"00000"; +  signal Right: std_logic; +  signal Arith: std_logic; +  signal SH: std_logic_vector(31 downto 0); +begin +  shift: entity work.shift_32(behavioral) +      port map (D, SA, Right, Arith, SH); +  stimulus: process is +  begin +    loop +      D <= B"00000000000000000000000000000011" and D; +      Right <= '0'; +      Arith <= '0'; +      wait for 5 ns; +      Arith <= '1'; +      wait for 5 ns; +      Right <= '1'; +      Arith <= '0'; +      wait for 5 ns; +      Arith <= '1'; +      wait for 5 ns; +      D <= B"10000000000000000000000000000000" or D; +      Right <= '0'; +      Arith <= '0'; +      wait for 5 ns; +      Arith <= '1'; +      wait for 5 ns; +      Right <= '1'; +      Arith <= '0'; +      wait for 5 ns; +      Arith <= '1'; +      wait for 5 ns; + +      SA <= SA + 1; +    end loop; +  end process stimulus; +end architecture test_shift_32; + + +architecture test_alu of test_bench is + signal A: std_logic_vector(31 downto 0) := "00000000000000000000000000000011"; + signal B: std_logic_vector(31 downto 0) := "00000000000000000000000000000011"; + signal S: std_logic_vector(31 downto 0); + signal ALUC: std_logic_vector(3 downto 0) := "0000"; + signal Z: std_logic; +begin +  alu: entity work.alu(Behavioral) +      port map (A, B, ALUC, S, Z); +  stimulus: process is +  begin +    loop +      wait for 5 ns; +      ALUC <= ALUC + 1; +    end loop; +     +  end process stimulus; +end architecture test_alu;
\ No newline at end of file  | 
