diff options
| author | crupest <crupest@outlook.com> | 2021-12-24 19:35:16 +0800 | 
|---|---|---|
| committer | crupest <crupest@outlook.com> | 2021-12-24 19:35:16 +0800 | 
| commit | 496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6 (patch) | |
| tree | 211679b30c1d2dd393ba4e7a549dc997cc814bfc | |
| parent | 246028dd6c23b5fc1efb3dc53c2fddd79ba865de (diff) | |
| download | crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.gz crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.bz2 crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.zip  | |
import(life): ...
5 files changed, 240 insertions, 38 deletions
diff --git a/works/life/computer-organization-experiment/alu.vhdl b/works/life/computer-organization-experiment/alu.vhdl index 0bb743c..75a9961 100644 --- a/works/life/computer-organization-experiment/alu.vhdl +++ b/works/life/computer-organization-experiment/alu.vhdl @@ -1,10 +1,13 @@  LIBRARY IEEE;  USE IEEE.STD_LOGIC_1164.ALL; -USE IEEE.STD_LOGIC_UNSIGNED.ALL;  use ieee.numeric_std.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); +    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 @@ -14,9 +17,9 @@ begin           else A - 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"010" -         else std_logic_vector(signed(A) sll 16) and B"11111111111111110000000000000000" when ALUC(2 downto 0) ?= B"110" +         else std_logic_vector(signed(A) sll 16) and H"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"0111"           else std_logic_vector(signed(A) sra to_integer(unsigned(B))) when ALUC ?= B"1111"; -    Z <= S ?= "00000000000000000000000000000000"; +    Z <= S ?= H"00000000";  end architecture; diff --git a/works/life/computer-organization-experiment/cpu.vhdl b/works/life/computer-organization-experiment/cpu.vhdl new file mode 100644 index 0000000..fb4b45f --- /dev/null +++ b/works/life/computer-organization-experiment/cpu.vhdl @@ -0,0 +1,184 @@ +library ieee; + +subtype word of std_logic_vector(31 downto 0); +constant clock_time : time := 10 ns; + +entity register is +    port ( +        CLK: in std_logic; -- Rising edge -> Read; Falling edge -> Write. +        W: in word; -- The data to write. +        ENABLE: in std_logic; -- If 1 then at falling edge of clock, W will be written. +        ZERO: in std_logic; -- If 1 then at rising edge of clock, 0 will be output to R. +        R: out word; -- The data to read. +    ) +end entity; + +architecture Behavioral of register is +    signal V: word; +begin +    process(CLK) +    begin +        if rising_edge(CLK) then +            if ZERO = '1' then +                R <= (others => '0'); +            else +                R <= V; +            end if; +        end if; +        if falling_edge(CLK) and ENABLE = '1' then +            V <= W; +        end if; +    end process; +end architecture; + +entity register_file is +    port ( +        CLK: in std_logic; +        ENABLE: in std_logic; +        ZERO1, ZERO2: 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 std_logic_vector(31 downto 0); +    signal reg_file: reg_file_type := (others => '0'); +begin +    process (CLK) +    begin +        if rising_edge(CLK) then +            if ZERO1 = '1' then +                RD1 <= (others => '0'); +            else +                RD1 <= reg_file(to_integer(R1)); +            end if; +            if ZERO2 = '1' then +                RD2 <= (others => '0'); +            else +                RD2 <= reg_file(to_integer(R2)); +            end if; +        end if; +        if falling_edge(CLK) and ENABLE = '1' then +            reg_file(to_integer(W)) <= WD; +        end if; +    end; +end architecture; + +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 H"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"0111" +         else std_logic_vector(signed(A) sra to_integer(unsigned(B))) when ALUC ?= B"1111"; +    Z <= S ?= H"00000000"; +end architecture; + +entity clock is +    port(CLK: out std_logic) +end entity; + +architecture Behavioral of clock is +begin +    CLK <= not CLK after clock_time; +end architecture; + +type memory_type = array (0 to 1023) of std_logic_vector(31 downto 0); + +entity cpu is +    port (memory: in memory_type) +end entity; + +architecture Behavioral of cpu is +    signal pc: std_logic_vector(31 downto 0); +    signal pc_to_write: std_logic_vector(31 downto 0); + +    signal CLK: in std_logic; +    signal WRITE_REG: in std_logic; +    signal R1, R2, W: in std_logic_vector(4 downto 0); +    signal WD: in std_logic_vector(31 downto 0); +    signal RD1, RD2: out std_logic_vector(31 downto 0); + +    signal A, B: in std_logic_vector(31 downto 0); +    signal ALUC: in std_logic_vector(3 downto 0); +    signal S: out std_logic_vector(31 downto 0); +    signal Z: out std_logic); +begin +    pc_reg: register +        port map ( +            CLK => CLK, +            ENABLE => '1', +            ZERO => '0', +            W => pc_to_write, +            R => pc +        ); +    reg: register_file +        port map( +            CLK => CLK, +            ENABLE => WRITE_REG, +            R1 => R1, +            R2 => R2, +            W => W, +            WD => WD, +            RD1 => RD1, +            RD2 => RD2 +        ); +    alu: alu +        port map( +            A => A, +            B => B, +            ALUC => ALUC, +            S => S, +            Z => Z +        ); +    logic: process is +        variable ins: std_logic_vector(31 downto 0); +    begin +        ins <= memory(to_integer(pc)); +        pc_to_write <= pc + H"00000001"; + +        if ins(31 downto 26) = B"000000" then +            if ins(5) = '1' then +                R1 <= ins(25 downto 21); +                R2 <= ins(20 downto 16); +                ALUC <= ins(3 downto 0); +                A <= RD1; +                B <= RD2; +                W <= ins(15 downto 11); +                WRITE_REG <= '1'; +                WD <= S; +            else if ins(3) = '0' then +                R1 <= ins(20 downto 16); +                ALUC(3 downto 2) <= ins(1 downto 0); +                ALUC(1 downto 0) <= B"11"; +                A <= RD1; +                B(31 downto 5) <= (others => '0'); +                B(4 downto 0) <= ins(10 downto 6); +                W <= ins(15 downto 11); +                WRITE_REG <= '1'; +                WD <= S; +            else +                R1 <= ins(25 downto 16) +                WRITE_REG <= '0'; +                pc_to_write <= RD1; +            end if; +        else +            -- TODO: Implement this. +        end if; +         +    end process; +end architecture; diff --git a/works/life/computer-organization-experiment/hdl-prj.json b/works/life/computer-organization-experiment/hdl-prj.json deleted file mode 100644 index 1d997bb..0000000 --- a/works/life/computer-organization-experiment/hdl-prj.json +++ /dev/null @@ -1,34 +0,0 @@ -{ -    "options": { -        "ghdl_analysis": [ -            "-fsynopsys", -            "--workdir=build" -        ] -    }, -    "files": [ -        { -            "file": "counter_4.vhdl", -            "language": "vhdl" -        }, -        { -            "file": "full_adder_1.vhdl", -            "language": "vhdl" -        }, -        { -            "file": "test_bench.vhdl", -            "language": "vhdl" -        }, -        { -            "file": "multiplexer_1_2.vhdl", -            "language": "vhdl" -        }, -        { -            "file": "multiplexer_8_2.vhdl", -            "language": "vhdl" -        }, -        { -            "file": "multiplexer_32_2.vhdl", -            "language": "vhdl" -        } -    ] -}
\ No newline at end of file diff --git a/works/life/computer-organization-experiment/register.vhdl b/works/life/computer-organization-experiment/register.vhdl new file mode 100644 index 0000000..8d24bd6 --- /dev/null +++ b/works/life/computer-organization-experiment/register.vhdl @@ -0,0 +1,21 @@ +library ieee; + +entity register is +    port ( +        D : in std_logic_vector(31 downto 0); +        CLK, EN, CLRN: in std_logic; +        Q: out std_logic_vector(31 downto 0) +    ) +end register; + +architecture Behavioral of register is +begin +    storage: process is +    begin +        if CLRN = '0' then +            Q <= H"00000000"; +        elsif rising_edge(CLK) and EN = '1' then +            Q <= D; +        end if; +    end process; +end Behavioral; diff --git a/works/life/computer-organization-experiment/register_file.vhdl b/works/life/computer-organization-experiment/register_file.vhdl new file mode 100644 index 0000000..ab1056f --- /dev/null +++ b/works/life/computer-organization-experiment/register_file.vhdl @@ -0,0 +1,28 @@ +library ieee; + +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 std_logic_vector(31 downto 0); +    signal reg_file: reg_file_type := (others => '0'); +begin +    process (CLK) +    begin +        if rising_edge(CLK) then +        begin +            if WRITE then +                reg_file(W) <= WD; +            end; +            RD1 <= reg_file(R1); +            RD2 <= reg_file(R2); +        end; +    end; +end architecture;  | 
