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 /works/life | |
parent | 246028dd6c23b5fc1efb3dc53c2fddd79ba865de (diff) | |
download | crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.gz crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.bz2 crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.zip |
import(life): ...
Diffstat (limited to 'works/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; |