aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-12-26 23:59:28 +0800
committercrupest <crupest@outlook.com>2021-12-26 23:59:28 +0800
commitd122ab74ce2e7c3bf1e126e8b08d6b36d1cf0a83 (patch)
treefc5987a3b8c67062a4479ab64980023ad6ab10c9 /works/life
parent825afbb7774d5a507f198429b8999c6aae3f8592 (diff)
downloadcrupest-d122ab74ce2e7c3bf1e126e8b08d6b36d1cf0a83.tar.gz
crupest-d122ab74ce2e7c3bf1e126e8b08d6b36d1cf0a83.tar.bz2
crupest-d122ab74ce2e7c3bf1e126e8b08d6b36d1cf0a83.zip
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r--works/life/computer-organization-experiment/cpu.vhdl352
-rw-r--r--works/life/computer-organization-experiment/out.ghwbin4661248 -> 34000 bytes
-rw-r--r--works/life/computer-organization-experiment/out.vcd184
3 files changed, 165 insertions, 371 deletions
diff --git a/works/life/computer-organization-experiment/cpu.vhdl b/works/life/computer-organization-experiment/cpu.vhdl
index aca35cf..5a7c558 100644
--- a/works/life/computer-organization-experiment/cpu.vhdl
+++ b/works/life/computer-organization-experiment/cpu.vhdl
@@ -4,33 +4,29 @@ use ieee.std_logic_1164.all;
package cru is
subtype word is std_logic_vector(31 downto 0);
constant clock_time : time := 10 ns;
- constant ram_clock_time: time := 2.5 ns;
end package;
library ieee;
use ieee.std_logic_1164.all;
use work.cru.all;
-entity reg is
- port (
- CLK: in std_logic; -- Rising edge -> Read; Falling edge -> Write.
- ENABLE: in std_logic; -- If 1 then at falling edge of clock, W will be written.
- W: in word; -- The data to write.
- R: out word -- The data to read.
- );
+entity generic_clock is
+ generic(delay, interval: time);
+ port(CLK: out std_logic);
end entity;
-architecture Behavioral of reg is
- signal V: word := (others => '0');
+architecture Behavioral of generic_clock is
+ signal V : std_logic := '1';
begin
- process(CLK)
+ l: process is
begin
- if rising_edge(CLK) then
- R <= V;
- end if;
- if falling_edge(CLK) and ENABLE = '1' then
- V <= W;
- end if;
+ CLK <= '0';
+ wait for delay;
+ loop
+ CLK <= V;
+ V <= not V;
+ wait for interval;
+ end loop;
end process;
end architecture;
@@ -38,35 +34,38 @@ library ieee;
use ieee.std_logic_1164.all;
use work.cru.all;
-entity reg_file_clock is
- port(CLK: out std_logic);
+entity reg is
+ port (
+ CLK: in std_logic; -- Rising edge -> Read; Falling edge -> Write.
+ WRITE: in std_logic; -- If 1 then at falling edge of clock, W will be written.
+ W_DATA: in word; -- The data to write.
+ R_DATA: out word -- The data to read.
+ );
end entity;
-architecture Behavioral of reg_file_clock is
- signal V: std_logic := '1';
+architecture Behavioral of reg is
+ signal V: word := X"00000000";
begin
- l: process is
+ process(CLK)
begin
- CLK <= V;
- wait for 1 ns;
- loop
- V <= not V;
- wait for 1 ps;
- CLK <= V;
- wait for clock_time;
- end loop;
+ if rising_edge(CLK) then
+ R_DATA <= V;
+ end if;
+ if falling_edge(CLK) and WRITE = '1' then
+ V <= W_DATA;
+ end if;
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 (
- ENABLE: in std_logic;
+ 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)
@@ -74,19 +73,16 @@ entity register_file is
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 => (others => '0'));
- signal CLK : std_logic;
+ type reg_file_type is array (0 to 31) of word;
+ signal reg_file: reg_file_type := (others => X"00000000");
begin
- clock: entity work.reg_file_clock
- port map (CLK);
process (CLK)
begin
if rising_edge(CLK) then
RD1 <= reg_file(to_integer(unsigned(R1)));
RD2 <= reg_file(to_integer(unsigned(R2)));
end if;
- if falling_edge(CLK) and ENABLE = '1' then
+ if falling_edge(CLK) and WRITE = '1' then
reg_file(to_integer(unsigned(W))) <= WD;
end if;
end process;
@@ -123,54 +119,15 @@ end architecture;
library ieee;
use ieee.std_logic_1164.all;
-use work.cru.all;
-
-entity clock is
- port(CLK: out std_logic);
-end entity;
-
-architecture Behavioral of clock is
- signal V: std_logic := '0';
-begin
- V <= not V after clock_time;
- CLK <= V;
-end architecture;
-
-library ieee;
-use ieee.std_logic_1164.all;
-use work.cru.all;
-
-entity ram_clock is
- port(CLK: out std_logic);
-end entity;
-
-architecture Behavioral of ram_clock is
- signal V: std_logic := '0';
-begin
- l: process is
- begin
- CLK <= V;
- wait for 500 ps;
- loop
- V <= not V;
- wait for 1 ps;
- CLK <= V;
- wait for ram_clock_time;
- end loop;
- end process;
-end architecture;
-
-library ieee;
-use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.cru.all;
entity ram is
port(
+ CLK: in std_logic;
R_DATA: out word;
W_DATA: in word;
- R_ADDR: in word;
- W_ADDR: in word;
+ ADDR: in word;
READ: in std_logic;
WRITE: in std_logic
);
@@ -217,18 +174,14 @@ architecture Behavioral of ram is
X"00000115",
others => (others => '0')
);
- signal V: std_logic := '0';
- signal CLK: std_logic;
begin
- clock: entity work.ram_clock
- port map (CLK);
- b: process(CLK) is
+ l: process(CLK) is
begin
if rising_edge(CLK) and READ = '1' then
- R_DATA <= memory(to_integer(unsigned(R_ADDR)) / 4);
+ r_data <= memory(to_integer(unsigned(ADDR)) / 4);
end if;
if falling_edge(CLK) and WRITE = '1' then
- memory(to_integer(unsigned(W_ADDR)) / 4) <= W_DATA;
+ memory(to_integer(unsigned(ADDR)) / 4) <= w_data;
end if;
end process;
end architecture;
@@ -240,21 +193,21 @@ use ieee.std_logic_unsigned.all;
use work.cru.all;
entity cpu is
- port (
- CLK: in std_logic
- );
end entity;
architecture Behavioral of cpu is
+ signal pc_clk: std_logic := '0';
+ signal reg_clk: std_logic := '0';
+ signal mem_clk: std_logic := '0';
+
signal pc: word := X"00000000";
signal pc_to_write: word;
signal ins: word;
- signal mem_r_addr: word := X"00000000";
- signal mem_w_addr: word := X"00000000";
+ signal mem_addr: word;
signal mem_r_data: word;
- signal mem_w_data: word := X"00000000";
+ signal mem_w_data: word;
signal mem_read: std_logic := '0';
signal mem_write: std_logic := '0';
@@ -272,16 +225,30 @@ architecture Behavioral of cpu is
signal S: std_logic_vector(31 downto 0);
signal Z: std_logic;
begin
+ pc_clock: entity work.generic_clock
+ generic map (delay => 1 ps, interval => clock_time)
+ port map (CLK => pc_clk);
+
+ mem_clock: entity work.generic_clock
+ generic map (delay => 1 ns, interval => clock_time / 2)
+ port map (CLK => mem_clk);
+
+ reg_clock: entity work.generic_clock
+ generic map (delay => 2 ns, interval => clock_time)
+ port map (CLK => reg_clk);
+
pc_reg: entity work.reg
port map (
- CLK => CLK,
- ENABLE => '1',
- W => pc_to_write,
- R => pc
+ CLK => pc_clk,
+ WRITE => '1',
+ R_DATA => pc,
+ W_DATA => pc_to_write
);
- reg: entity work.register_file
+
+ reg_file: entity work.register_file
port map(
- ENABLE => WRITE_REG,
+ CLK => reg_clk,
+ WRITE => WRITE_REG,
R1 => R1,
R2 => R2,
W => W,
@@ -289,6 +256,7 @@ begin
RD1 => RD1,
RD2 => RD2
);
+
alu: entity work.alu
port map(
A => A,
@@ -300,109 +268,153 @@ begin
ram: entity work.ram
port map (
- R_DATA => mem_r_data,
- W_DATA => mem_w_data,
- R_ADDR => mem_r_addr,
- W_ADDR => mem_w_addr,
+ CLK => mem_clk,
+ r_data => mem_r_data,
+ w_data => mem_w_data,
+ addr => mem_addr,
READ => mem_read,
WRITE => mem_write
);
logic: process is
begin
- wait until rising_edge(CLK);
+ wait until rising_edge(pc_clk);
- wait for 250 ps;
+ wait for 100 ps;
mem_read <= '1';
- mem_r_addr <= pc;
+ mem_addr <= pc;
pc_to_write <= pc + 4;
- wait for 500 ps;
+ wait for 1 ns;
ins <= mem_r_data;
- mem_write <= '0';
-
- WRITE_REG <= '0';
-
wait for 100 ps;
if ins(31 downto 27) = B"00001" then -- j / jal, not read reg
- if ins(26) = '1' then -- jal
- W <= B"11111";
- WD <= pc + 4;
- WRITE_REG <= '1';
+ R1 <= (others => '0');
+ R2 <= (others => '0');
+ elsif ins(31 downto 26) = B"000000" then
+ if ins(5) = '1' then
+ R1 <= ins(25 downto 21);
+ R2 <= ins(20 downto 16);
+ elsif ins(3) = '0' then
+ R1 <= ins(20 downto 16);
+ R2 <= (others => '0');
+ else
+ R1 <= ins(25 downto 21);
+ R2 <= (others => '0');
+ end if;
+ else
+ if ins(31) = '1' then
+ R1 <= ins(25 downto 21);
+ R2 <= ins(20 downto 16);
+ elsif ins(29 downto 26) = B"1111" then
+ R1 <= (others => '0');
+ R2 <= (others => '0');
+ elsif ins(29) = '1' then
+ R1 <= ins(25 downto 21);
+ R2 <= (others => '0');
+ else
+ R1 <= ins(25 downto 21);
+ R2 <= ins(20 downto 16);
end if;
+ end if;
+
+ wait for 1 ns;
+
+ if ins(31 downto 27) = B"00001" then -- j / jal, not read reg
ALUC <= B"0011";
A <= (25 downto 0 => ins(25 downto 0), others => '0');
B <= X"00000002";
- wait for 100 ps;
- pc_to_write <= S;
elsif ins(31 downto 26) = B"000000" then
if ins(5) = '1' then
- R1 <= ins(25 downto 21);
- R2 <= ins(20 downto 16);
-
- wait for 500 ps;
-
ALUC <= ins(3 downto 0);
A <= RD1;
B <= RD2;
-
- wait for 100 ps;
-
- W <= ins(15 downto 11);
- WRITE_REG <= '1';
- WD <= S;
elsif ins(3) = '0' then
- R1 <= ins(20 downto 16);
-
- wait for 500 ps;
-
ALUC(3 downto 2) <= ins(1 downto 0);
ALUC(1 downto 0) <= B"11";
A <= RD1;
B <= (4 downto 0 => ins(10 downto 6), others => '0');
+ else
+ ALUC <= (others => '0');
+ A <= (others => '0');
+ B <= (others => '0');
+ end if;
+ else
+ if ins(31) = '1' then
+ ALUC <= B"0000";
+ A <= RD1;
+ B <= (15 downto 0 => ins(15 downto 0), others => '0' );
+ elsif ins(29 downto 26) = B"1111" then
+ ALUC <= (others => '0');
+ A <= (others => '0');
+ B <= (others => '0');
+ elsif ins(29) = '1' then
+ ALUC <= ins(29 downto 26);
+ A <= RD1;
+ B(15 downto 0) <= ins(15 downto 0);
+ if ins(15) = '0' then
+ B(31 downto 16) <= X"0000";
+ else
+ B(31 downto 16) <= X"FFFF";
+ end if;
+ else
+ ALUC <= B"0010";
+ A <= RD1;
+ B <= RD2;
+ end if;
+ end if;
- wait for 100 ps;
+ wait for 100 ps;
+ if ins(31 downto 27) = B"00001" then -- j / jal, not read reg
+ if ins(26) = '1' then -- jal
+ W <= B"11111";
+ WD <= pc + 4;
+ WRITE_REG <= '1';
+ else
+ WRITE_REG <= '0';
+ end if;
+ pc_to_write <= S;
+ elsif ins(31 downto 26) = B"000000" then
+ if ins(5) = '1' then
+ WRITE_REG <= '1';
W <= ins(15 downto 11);
+ WD <= S;
+ elsif ins(3) = '0' then
WRITE_REG <= '1';
+ W <= ins(15 downto 11);
WD <= S;
else
- R1 <= ins(25 downto 21);
-
- wait for 500 ps;
-
+ WRITE_REG <= '0';
pc_to_write <= RD1;
end if;
else
if ins(31) = '1' then
- R1 <= ins(25 downto 21);
- R2 <= ins(20 downto 16);
-
- wait for 500 ps;
-
- ALUC <= B"0000";
- A <= RD1;
- B <= (15 downto 0 => ins(15 downto 0), others => '0' );
-
- wait for 100 ps;
-
if ins(29) = '1' then
R2 <= ins(20 downto 16);
mem_write <= '1';
- mem_w_addr <= S;
+ mem_addr <= S;
mem_w_data <= RD2;
+ wait until falling_edge(mem_clk);
+
+ wait for 100 ps;
+
+ mem_write <= '0';
+
else
W <= ins(20 downto 16);
mem_read <= '1';
- mem_r_addr <= S;
+ mem_addr <= S;
- wait for ram_clock_time * 2;
+ wait until rising_edge(mem_clk);
+
+ wait for 100 ps;
WD <= mem_r_data;
WRITE_REG <= '1';
@@ -412,43 +424,16 @@ begin
W <= ins(20 downto 16);
WD(31 downto 16) <= ins(15 downto 0);
elsif ins(29) = '1' then
- R1 <= ins(25 downto 21);
-
- wait for 500 ps;
-
- ALUC <= ins(29 downto 26);
- A <= RD1;
- B(15 downto 0) <= ins(15 downto 0);
- if ins(15) = '0' then
- B(31 downto 16) <= X"0000";
- else
- B(31 downto 16) <= X"FFFF";
- end if;
-
- wait for 100 ps;
-
- W <= ins(20 downto 16);
WRITE_REG <= '1';
+ W <= ins(20 downto 16);
WD <= S;
else
- R1 <= ins(25 downto 21);
- R2 <= ins(20 downto 16);
-
- wait for 500 ps;
-
- ALUC <= B"0010";
- A <= RD1;
- B <= RD2;
-
- wait for 100 ps;
-
+ WRITE_REG <= '0';
if Z = '1' xor ins(26) = '1' then
pc_to_write <= pc_to_write + to_integer(signed(ins(15 downto 0)) * 4);
end if;
- WRITE_REG <= '0';
end if;
end if;
-
end process;
end architecture;
@@ -464,12 +449,5 @@ end entity;
architecture Behavioral of cpu_test_bench is
signal CLK: std_logic;
begin
- clock: entity work.clock
- port map (
- CLK
- );
- cpu : entity work.cpu
- port map (
- CLK
- );
+ cpu : entity work.cpu;
end architecture;
diff --git a/works/life/computer-organization-experiment/out.ghw b/works/life/computer-organization-experiment/out.ghw
index 81d1df7..23af3af 100644
--- a/works/life/computer-organization-experiment/out.ghw
+++ b/works/life/computer-organization-experiment/out.ghw
Binary files differ
diff --git a/works/life/computer-organization-experiment/out.vcd b/works/life/computer-organization-experiment/out.vcd
deleted file mode 100644
index a47fb22..0000000
--- a/works/life/computer-organization-experiment/out.vcd
+++ /dev/null
@@ -1,184 +0,0 @@
-$date
- Sun Dec 26 07:20:30 2021
-$end
-$version
- GHDL v0
-$end
-$timescale
- 1 fs
-$end
-$scope module standard $end
-$upscope $end
-$scope module textio $end
-$upscope $end
-$scope module std_logic_1164 $end
-$upscope $end
-$scope module numeric_std $end
-$upscope $end
-$scope module std_logic_arith $end
-$upscope $end
-$scope module std_logic_unsigned $end
-$upscope $end
-$scope module cru $end
-$upscope $end
-$scope module cpu_test_bench $end
-$var reg 1 ! clk $end
-$scope module clock $end
-$var reg 1 " clk $end
-$var reg 1 # v $end
-$upscope $end
-$scope module cpu $end
-$var reg 1 $ clk $end
-$var reg 32 % pc[31:0] $end
-$var reg 32 & pc_to_write[31:0] $end
-$var reg 32 ' ins[31:0] $end
-$var reg 32 ( mem_r_addr[31:0] $end
-$var reg 32 ) mem_w_addr[31:0] $end
-$var reg 32 * mem_r_data[31:0] $end
-$var reg 32 + mem_w_data[31:0] $end
-$var reg 1 , mem_read $end
-$var reg 1 - mem_write $end
-$var reg 1 . write_reg $end
-$var reg 5 / r1[4:0] $end
-$var reg 5 0 r2[4:0] $end
-$var reg 5 1 w[4:0] $end
-$var reg 32 2 wd[31:0] $end
-$var reg 32 3 rd1[31:0] $end
-$var reg 32 4 rd2[31:0] $end
-$var reg 32 5 a[31:0] $end
-$var reg 32 6 b[31:0] $end
-$var reg 4 7 aluc[3:0] $end
-$var reg 32 8 s[31:0] $end
-$var reg 1 9 z $end
-$scope module pc_reg $end
-$var reg 1 : clk $end
-$var reg 1 ; enable $end
-$var reg 32 < w[31:0] $end
-$var reg 32 = r[31:0] $end
-$var reg 32 > v[31:0] $end
-$upscope $end
-$scope module reg $end
-$var reg 1 ? clk $end
-$var reg 1 @ enable $end
-$var reg 5 A r1[4:0] $end
-$var reg 5 B r2[4:0] $end
-$var reg 5 C w[4:0] $end
-$var reg 32 D wd[31:0] $end
-$var reg 32 E rd1[31:0] $end
-$var reg 32 F rd2[31:0] $end
-$comment reg_file is not handled $end
-$upscope $end
-$scope module alu $end
-$var reg 32 G a[31:0] $end
-$var reg 32 H b[31:0] $end
-$var reg 4 I aluc[3:0] $end
-$var reg 32 J s[31:0] $end
-$var reg 1 K z $end
-$upscope $end
-$scope module ram $end
-$var reg 32 L r_data[31:0] $end
-$var reg 32 M w_data[31:0] $end
-$var reg 32 N r_addr[31:0] $end
-$var reg 32 O w_addr[31:0] $end
-$var reg 1 P read $end
-$var reg 1 Q write $end
-$comment memory is not handled $end
-$var reg 1 R v $end
-$var reg 1 S clk $end
-$scope module clock $end
-$var reg 1 T clk $end
-$var reg 1 U v $end
-$upscope $end
-$upscope $end
-$upscope $end
-$upscope $end
-$enddefinitions $end
-#0
-0!
-0"
-0#
-0$
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU %
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU &
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU '
-b00000000000000000000000000000000 (
-b00000000000000000000000000000000 )
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU *
-b00000000000000000000000000000000 +
-0,
-0-
-0.
-b00000 /
-b00000 0
-b00000 1
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU 2
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU 3
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU 4
-b00000000000000000000000000000000 5
-b00000000000000000000000000000000 6
-b0000 7
-b00000000000000000000000000000000 8
-19
-0:
-1;
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU <
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU =
-b00000000000000000000000000000000 >
-0?
-0@
-b00000 A
-b00000 B
-b00000 C
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU D
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU E
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU F
-b00000000000000000000000000000000 G
-b00000000000000000000000000000000 H
-b0000 I
-b00000000000000000000000000000000 J
-1K
-bUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU L
-b00000000000000000000000000000000 M
-b00000000000000000000000000000000 N
-b00000000000000000000000000000000 O
-0P
-0Q
-0R
-0S
-0T
-0U
-#200000
-#2700000
-1U
-#5200000
-1S
-1T
-0U
-#7700000
-0S
-0T
-1U
-#10000000
-1!
-1"
-1#
-1$
-b00000000000000000000000000000000 %
-b00000000000000000000000000000000 3
-b00000000000000000000000000000000 4
-1:
-b00000000000000000000000000000000 =
-1?
-b00000000000000000000000000000000 E
-b00000000000000000000000000000000 F
-#10100000
-b00000000000000000000000000000100 &
-1,
-b00000000000000000000000000000100 <
-1P
-#10200000
-b00111100000000010000000000000000 *
-b00111100000000010000000000000000 L
-1S
-1T
-0U