aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-12-24 19:35:16 +0800
committercrupest <crupest@outlook.com>2021-12-24 19:35:16 +0800
commit496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6 (patch)
tree211679b30c1d2dd393ba4e7a549dc997cc814bfc /works/life
parent246028dd6c23b5fc1efb3dc53c2fddd79ba865de (diff)
downloadcrupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.gz
crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.tar.bz2
crupest-496f67d0c03a1b61153b565f67ffbfcc9f6ed3a6.zip
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r--works/life/computer-organization-experiment/alu.vhdl11
-rw-r--r--works/life/computer-organization-experiment/cpu.vhdl184
-rw-r--r--works/life/computer-organization-experiment/hdl-prj.json34
-rw-r--r--works/life/computer-organization-experiment/register.vhdl21
-rw-r--r--works/life/computer-organization-experiment/register_file.vhdl28
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;