aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-12-25 10:43:27 +0800
committercrupest <crupest@outlook.com>2021-12-25 10:43:27 +0800
commit9af60bca5cb83866cba9f04aba7e71ac1f83dd16 (patch)
tree97f4588af155fa984dcf4747a3dbd8e65a53f6e6 /works/life
parentad065403bf97561b07171fac03a5e72a45d85caf (diff)
downloadcrupest-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/Makefile3
-rw-r--r--works/life/computer-organization-experiment/cpu.vhdl131
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;