diff options
author | crupest <crupest@outlook.com> | 2021-12-25 10:43:27 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-12-25 10:43:27 +0800 |
commit | 9af60bca5cb83866cba9f04aba7e71ac1f83dd16 (patch) | |
tree | 97f4588af155fa984dcf4747a3dbd8e65a53f6e6 /works/life | |
parent | ad065403bf97561b07171fac03a5e72a45d85caf (diff) | |
download | crupest-9af60bca5cb83866cba9f04aba7e71ac1f83dd16.tar.gz crupest-9af60bca5cb83866cba9f04aba7e71ac1f83dd16.tar.bz2 crupest-9af60bca5cb83866cba9f04aba7e71ac1f83dd16.zip |
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r-- | works/life/computer-organization-experiment/Makefile | 3 | ||||
-rw-r--r-- | works/life/computer-organization-experiment/cpu.vhdl | 131 |
2 files changed, 88 insertions, 46 deletions
diff --git a/works/life/computer-organization-experiment/Makefile b/works/life/computer-organization-experiment/Makefile index 215a4e5..fe68a53 100644 --- a/works/life/computer-organization-experiment/Makefile +++ b/works/life/computer-organization-experiment/Makefile @@ -1,3 +1,6 @@ +build/cpu.o: build + ghdl analyze --std=08 --workdir=build -fsynopsys cpu.vhdl + all: build/test_bench build: diff --git a/works/life/computer-organization-experiment/cpu.vhdl b/works/life/computer-organization-experiment/cpu.vhdl index 2110436..4334c42 100644 --- a/works/life/computer-organization-experiment/cpu.vhdl +++ b/works/life/computer-organization-experiment/cpu.vhdl @@ -1,19 +1,31 @@ library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; -subtype word of std_logic_vector(31 downto 0); -constant clock_time : time := 10 ns; +package cru is + subtype word is std_logic_vector(31 downto 0); + constant clock_time : time := 10 ns; + type memory_type is array (0 to 1023) of std_logic_vector(31 downto 0); +end package; -entity register is +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all; +use work.cru.all; + +entity reg 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. - ) + R: out word -- The data to read. + ); end entity; -architecture Behavioral of register is +architecture Behavioral of reg is signal V: word; begin process(CLK) @@ -31,6 +43,12 @@ begin 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 register_file is port ( CLK: in std_logic; @@ -38,13 +56,13 @@ entity register_file is 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); - ) + 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'); + signal reg_file: reg_file_type := (others => (others => '0')); begin process (CLK) begin @@ -52,20 +70,26 @@ begin if ZERO1 = '1' then RD1 <= (others => '0'); else - RD1 <= reg_file(to_integer(R1)); + RD1 <= reg_file(to_integer(unsigned(R1))); end if; if ZERO2 = '1' then RD2 <= (others => '0'); else - RD2 <= reg_file(to_integer(R2)); + RD2 <= reg_file(to_integer(unsigned(R2))); end if; end if; if falling_edge(CLK) and ENABLE = '1' then - reg_file(to_integer(W)) <= WD; + reg_file(to_integer(unsigned(W))) <= WD; end if; - end; + 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); @@ -82,15 +106,21 @@ begin 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 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"0111" else std_logic_vector(signed(A) sra to_integer(unsigned(B))) when ALUC ?= B"1111"; - Z <= S ?= H"00000000"; + Z <= S ?= X"00000000"; 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 clock is - port(CLK: out std_logic) + port(CLK: out std_logic); end entity; architecture Behavioral of clock is @@ -98,10 +128,14 @@ begin CLK <= not CLK after clock_time; end architecture; -type memory_type = array (0 to 1023) of std_logic_vector(31 downto 0); +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 - port (memory: in memory_type) + port (memory: inout memory_type); end entity; architecture Behavioral of cpu is @@ -111,18 +145,19 @@ architecture Behavioral of cpu is signal enable_mem: std_logic; signal write_mem: std_logic; - 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 CLK: std_logic; + signal WRITE_REG: std_logic; + signal ZERO1, ZERO2: std_logic; + signal R1, R2, W: std_logic_vector(4 downto 0); + signal WD: std_logic_vector(31 downto 0); + signal RD1, RD2: 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); + signal A, B: std_logic_vector(31 downto 0); + signal ALUC: std_logic_vector(3 downto 0); + signal S: std_logic_vector(31 downto 0); + signal Z: std_logic; begin - pc_reg: register + pc_reg: entity work.reg port map ( CLK => CLK, ENABLE => '1', @@ -130,10 +165,12 @@ begin W => pc_to_write, R => pc ); - reg: register_file + reg: entity work.register_file port map( CLK => CLK, ENABLE => WRITE_REG, + ZERO1 => ZERO1, + ZERO2 => ZERO2, R1 => R1, R2 => R2, W => W, @@ -141,7 +178,7 @@ begin RD1 => RD1, RD2 => RD2 ); - alu: alu + alu: entity work.alu port map( A => A, B => B, @@ -152,8 +189,8 @@ begin logic: process is variable ins: std_logic_vector(31 downto 0); begin - ins <= memory(to_integer(pc)); - pc_to_write <= pc + H"00000001"; + ins := memory(to_integer(unsigned(pc))); + pc_to_write <= pc + B"1"; WRITE_REG <= '0'; enable_mem <= '0'; @@ -162,13 +199,13 @@ begin if ins(31 downto 16) = B"000010" then pc_to_write(25 downto 0) <= ins(25 downto 0); pc_to_write(31 downto 26) <= (others => '0'); - else if ins(31 downto 16) = B"000011" then - W <= 1; + elsif ins(31 downto 16) = B"000011" then + W <= B"00001"; WD <= pc_to_write; WRITE_REG <= '1'; pc_to_write(25 downto 0) <= ins(25 downto 0); pc_to_write(31 downto 26) <= (others => '0'); - else if ins(31 downto 26) = B"000000" then + elsif ins(31 downto 26) = B"000000" then if ins(5) = '1' then R1 <= ins(25 downto 21); R2 <= ins(20 downto 16); @@ -178,7 +215,7 @@ begin W <= ins(15 downto 11); WRITE_REG <= '1'; WD <= S; - else if ins(3) = '0' then + elsif ins(3) = '0' then R1 <= ins(20 downto 16); ALUC(3 downto 2) <= ins(1 downto 0); ALUC(1 downto 0) <= B"11"; @@ -189,7 +226,7 @@ begin WRITE_REG <= '1'; WD <= S; else - R1 <= ins(25 downto 16) + R1 <= ins(25 downto 21); WRITE_REG <= '0'; pc_to_write <= RD1; end if; @@ -200,7 +237,7 @@ begin ALUC <= B"0000"; A <= RD1; B(15 downto 0) <= ins(15 downto 0); - B(31 downto 16) <= H"0000"; + B(31 downto 16) <= X"0000"; if ins(29) = '1' then W <= ins(20 downto 16); write_mem <= '0'; @@ -208,16 +245,16 @@ begin R2 <= ins(20 downto 16); write_mem <= '1'; end if; - else if ins(29 downto 26) = B"1111" then + elsif ins(29 downto 26) = B"1111" then WRITE_REG <= '1'; W <= ins(20 downto 16); WD(31 downto 16) <= ins(15 downto 0); - else if ins(29) = '1' then + elsif ins(29) = '1' then R1 <= ins(25 downto 21); ALUC <= ins(29 downto 26); A <= RD1; B(15 downto 0) <= ins(15 downto 0); - B(31 downto 16) <= H"0000"; + B(31 downto 16) <= X"0000"; W <= ins(20 downto 16); WRITE_REG <= '1'; WD <= S; @@ -225,10 +262,10 @@ begin R1 <= ins(25 downto 21); R2 <= ins(20 downto 16); ALUC <= B"0010"; - A <= R1; - B <= R2; + A <= RD1; + B <= RD2; if Z = '1' then - pc_to_write <= pc_to_write + to_integer(ins(15 downto 0)); + pc_to_write <= pc_to_write + ins(15 downto 0); end if; WRITE_REG <= '0'; end if; @@ -237,12 +274,14 @@ begin if enable_mem then if write_mem then WRITE_REG <= '0'; - memory(S) <= RD2; + memory(to_integer(unsigned(S))) <= RD2; else WRITE_REG <= '1'; - WD <= memory(S); + WD <= memory(to_integer(unsigned(S))); end if; end if; + + wait for 1ns; end process; end architecture; |