diff options
author | crupest <crupest@outlook.com> | 2021-12-26 23:59:28 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-12-26 23:59:28 +0800 |
commit | d122ab74ce2e7c3bf1e126e8b08d6b36d1cf0a83 (patch) | |
tree | fc5987a3b8c67062a4479ab64980023ad6ab10c9 /works/life | |
parent | 825afbb7774d5a507f198429b8999c6aae3f8592 (diff) | |
download | crupest-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.vhdl | 352 | ||||
-rw-r--r-- | works/life/computer-organization-experiment/out.ghw | bin | 4661248 -> 34000 bytes | |||
-rw-r--r-- | works/life/computer-organization-experiment/out.vcd | 184 |
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 Binary files differindex 81d1df7..23af3af 100644 --- a/works/life/computer-organization-experiment/out.ghw +++ b/works/life/computer-organization-experiment/out.ghw 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 |