diff options
Diffstat (limited to 'store/works/life/computer-organization-experiment')
15 files changed, 826 insertions, 0 deletions
diff --git a/store/works/life/computer-organization-experiment/.gitignore b/store/works/life/computer-organization-experiment/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/store/works/life/computer-organization-experiment/.gitignore @@ -0,0 +1 @@ +build
\ No newline at end of file diff --git a/store/works/life/computer-organization-experiment/Makefile b/store/works/life/computer-organization-experiment/Makefile new file mode 100644 index 0000000..0b4db7f --- /dev/null +++ b/store/works/life/computer-organization-experiment/Makefile @@ -0,0 +1,51 @@ +build/cpu_test_bench: build/cpu.o + ghdl elaborate -g --std=08 --workdir=build -fsynopsys -o build/cpu_test_bench cpu_test_bench + +build/cpu.o: build cpu.vhdl + ghdl analyze -g --std=08 --workdir=build -fsynopsys cpu.vhdl + +all: build/test_bench + +build: + mkdir -p build + +build/adder_1.o: build adder_1.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys adder_1.vhdl + +build/adder_8.o: build adder_8.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys adder_8.vhdl + +build/adder_32.o: build adder_32.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys adder_32.vhdl + +build/alu.o: build alu.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys alu.vhdl + +build/counter_4.o: build counter_4.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys counter_4.vhdl + +build/full_adder_1.o: build full_adder_1.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys full_adder_1.vhdl + +build/multiplexer_1_2.o: build multiplexer_1_2.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_1_2.vhdl + +build/multiplexer_8_2.o: build multiplexer_8_2.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_8_2.vhdl + +build/multiplexer_32_2.o: build multiplexer_32_2.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys multiplexer_32_2.vhdl + +build/shift_32.o: build shift_32.vhdl + ghdl analyze --std=08 --workdir=build -fsynopsys shift_32.vhdl + +build/test_bench.o: build test_bench.vhdl build/counter_4.o build/full_adder_1.o build/multiplexer_1_2.o build/multiplexer_8_2.o build/multiplexer_32_2.o build/adder_1.o build/adder_8.o build/adder_32.o build/shift_32.o build/alu.o + ghdl analyze --std=08 --workdir=build -fsynopsys test_bench.vhdl + +build/test_bench: build/test_bench.o + ghdl elaborate --std=08 --workdir=build -fsynopsys -o build/test_bench test_bench + +.PHONY: all clean + +clean: + rm -r build diff --git a/store/works/life/computer-organization-experiment/adder_1.vhdl b/store/works/life/computer-organization-experiment/adder_1.vhdl new file mode 100644 index 0000000..625aae4 --- /dev/null +++ b/store/works/life/computer-organization-experiment/adder_1.vhdl @@ -0,0 +1,13 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_1 is + port (A, B, CIN:in std_logic; S, COUT: out std_logic); +end adder_1; + +architecture behavior of adder_1 is +begin + S <= (A XOR B) XOR CIN; + COUT <= (A AND B) OR (B AND CIN) OR (CIN AND A); +end behavior; diff --git a/store/works/life/computer-organization-experiment/adder_32.vhdl b/store/works/life/computer-organization-experiment/adder_32.vhdl new file mode 100644 index 0000000..f573f3f --- /dev/null +++ b/store/works/life/computer-organization-experiment/adder_32.vhdl @@ -0,0 +1,20 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_32 is + port (A, B:in std_logic_vector(31 downto 0); CIN:in std_logic; S: out std_logic_vector(31 downto 0); COUT: out std_logic); +end adder_32; + +architecture behavior of adder_32 is + signal C : std_logic_vector(2 downto 0); +begin + c0: entity work.adder_8 + port map (A=>A(7 downto 0), B=>B(7 downto 0), CIN=>CIN, S=>S(7 downto 0), COUT=>C(0)); + c1: entity work.adder_8 + port map (A=>A(15 downto 8), B=>B(15 downto 8), CIN=>C(0), S=>S(15 downto 8), COUT=>C(1)); + c2: entity work.adder_8 + port map (A=>A(23 downto 16), B=>B(23 downto 16), CIN=>C(1), S=>S(23 downto 16), COUT=>C(2)); + c3: entity work.adder_8 + port map (A=>A(31 downto 24), B=>B(31 downto 24), CIN=>C(2), S=>S(31 downto 24), COUT=>COUT); +end behavior; diff --git a/store/works/life/computer-organization-experiment/adder_8.vhdl b/store/works/life/computer-organization-experiment/adder_8.vhdl new file mode 100644 index 0000000..840ee0d --- /dev/null +++ b/store/works/life/computer-organization-experiment/adder_8.vhdl @@ -0,0 +1,28 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity adder_8 is + port (A, B:in std_logic_vector(7 downto 0); CIN:in std_logic; S: out std_logic_vector(7 downto 0); COUT: out std_logic); +end adder_8; + +architecture behavior of adder_8 is + signal C : std_logic_vector(6 downto 0); +begin + b0: entity work.adder_1 + port map (A=>A(0), B=>B(0), CIN=>CIN, S=>S(0), COUT=>C(0)); + b1: entity work.adder_1 + port map (A=>A(1), B=>B(1), CIN=>C(0), S=>S(1), COUT=>C(1)); + b2: entity work.adder_1 + port map (A=>A(2), B=>B(2), CIN=>C(1), S=>S(2), COUT=>C(2)); + b3: entity work.adder_1 + port map (A=>A(3), B=>B(3), CIN=>C(2), S=>S(3), COUT=>C(3)); + b4: entity work.adder_1 + port map (A=>A(4), B=>B(4), CIN=>C(3), S=>S(4), COUT=>C(4)); + b5: entity work.adder_1 + port map (A=>A(5), B=>B(5), CIN=>C(4), S=>S(5), COUT=>C(5)); + b6: entity work.adder_1 + port map (A=>A(6), B=>B(6), CIN=>C(5), S=>S(6), COUT=>C(6)); + b7: entity work.adder_1 + port map (A=>A(7), B=>B(7), CIN=>C(6), S=>S(7), COUT=>COUT); +end behavior; diff --git a/store/works/life/computer-organization-experiment/counter_4.vhdl b/store/works/life/computer-organization-experiment/counter_4.vhdl new file mode 100644 index 0000000..23c1807 --- /dev/null +++ b/store/works/life/computer-organization-experiment/counter_4.vhdl @@ -0,0 +1,19 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +ENTITY counter_4 IS + PORT (CLK:IN STD_LOGIC; + CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); +END counter_4; +ARCHITECTURE behavior OF counter_4 IS +BEGIN + PROCESS(CLK) + VARIABLE CQI:STD_LOGIC_VECTOR(3 DOWNTO 0) := B"0000"; + BEGIN + IF CLK'EVENT AND CLK='1' THEN + CQI := CQI + 1; + END IF; + CQ<=CQI; + END PROCESS; +END behavior; diff --git a/store/works/life/computer-organization-experiment/cpu.vhdl b/store/works/life/computer-organization-experiment/cpu.vhdl new file mode 100644 index 0000000..7ca6d9e --- /dev/null +++ b/store/works/life/computer-organization-experiment/cpu.vhdl @@ -0,0 +1,476 @@ +library ieee; +use ieee.std_logic_1164.all; + +package cru is + subtype word is std_logic_vector(31 downto 0); + constant clock_time : time := 10 ns; +end package; + +library ieee; +use ieee.std_logic_1164.all; +use work.cru.all; + +entity generic_clock is + generic(delay, interval: time); + port(CLK: out std_logic); +end entity; + +architecture Behavioral of generic_clock is + signal V : std_logic := '1'; +begin + l: process is + begin + CLK <= '0'; + wait for delay; + loop + CLK <= V; + V <= not V; + wait for interval; + end loop; + end process; +end architecture; + +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. + 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 is + signal V: word := X"00000000"; +begin + process(CLK) + begin + 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 work.cru.all; + +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 word; + signal reg_file: reg_file_type := (others => X"00000000"); +begin + 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 WRITE = '1' then + reg_file(to_integer(unsigned(W))) <= WD; + 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 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 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"1011" + else std_logic_vector(signed(A) sra to_integer(unsigned(B))) when ALUC ?= B"1111"; + Z <= S ?= X"00000000" after 10 ps; +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; + ADDR: in word; + READ: in std_logic; + WRITE: in std_logic + ); +end entity; + +architecture Behavioral of ram is + type memory_type is array (0 to 16#30#) of word; + signal memory: memory_type := ( +/* + X"3c010000", + X"34240080", + X"20050004", + X"0c000018", + X"ac820000", + X"8c890000", + X"01244022", + X"20050003", + X"20a5ffff", + X"34a8ffff", + X"39085555", + X"2009ffff", + X"312affff", + X"01493025", + X"01494026", + X"01463824", + X"10a00001", + X"08000008", + X"2005ffff", + X"000543c0", + X"00084400", + X"00084403", + X"000843c2", + X"08000017", + X"00004020", + X"8c890000", + X"20840004", + X"01094020", + X"20a5ffff", + X"14a0fffb", + X"00081000", + X"03e00008", + X"000000A3", + X"00000027", + X"00000079", + X"00000115", +*/ + X"3C010000", + X"3421004C", + X"8C240000", + X"20210004", + X"8C250000", + X"20210004", + X"0C000009", + X"AC230000", + X"08000008", + X"20020010", + X"00001820", + X"30A60001", + X"10060001", + X"00641820", + X"00042040", + X"00052842", + X"2042FFFF", + X"1440FFF9", + X"03e00008", + X"0000C9AE", + X"0000F6E5", + others => (others => '0') + ); +begin + l: process(CLK) is + begin + if rising_edge(CLK) and READ = '1' then + r_data <= memory(to_integer(unsigned(ADDR)) / 4); + end if; + if falling_edge(CLK) and WRITE = '1' then + memory(to_integer(unsigned(ADDR)) / 4) <= 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 cpu is +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_addr: word; + signal mem_r_data: word; + signal mem_w_data: word; + signal mem_read: std_logic := '0'; + signal mem_write: std_logic := '0'; + + signal WRITE_REG: std_logic := '0'; + signal R1: std_logic_vector(4 downto 0) := B"00000"; + signal R2: std_logic_vector(4 downto 0) := B"00000"; + signal W: std_logic_vector(4 downto 0) := B"00000"; + signal WD: std_logic_vector(31 downto 0) := X"00000000"; + signal RD1: std_logic_vector(31 downto 0) := X"00000000"; + signal RD2: std_logic_vector(31 downto 0) := X"00000000"; + + signal A: std_logic_vector(31 downto 0) := X"00000000"; + signal B: std_logic_vector(31 downto 0) := X"00000000"; + signal ALUC: std_logic_vector(3 downto 0) := B"0000"; + 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 => pc_clk, + WRITE => '1', + R_DATA => pc, + W_DATA => pc_to_write + ); + + reg_file: entity work.register_file + port map( + CLK => reg_clk, + WRITE => WRITE_REG, + R1 => R1, + R2 => R2, + W => W, + WD => WD, + RD1 => RD1, + RD2 => RD2 + ); + + alu: entity work.alu + port map( + A => A, + B => B, + ALUC => ALUC, + S => S, + Z => Z + ); + + ram: entity work.ram + port map ( + 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(pc_clk); + + wait for 100 ps; + + mem_read <= '1'; + mem_addr <= pc; + pc_to_write <= pc + 4; + + wait for 1 ns; + + ins <= mem_r_data; + + wait for 100 ps; + + if ins(31 downto 27) = B"00001" then -- j / jal, not read reg + 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"; + elsif ins(31 downto 26) = B"000000" then + if ins(5) = '1' then + ALUC <= ins(3 downto 0); + A <= RD1; + B <= RD2; + elsif ins(3) = '0' then + 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; + + 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 + WRITE_REG <= '0'; + pc_to_write <= RD1; + end if; + else + if ins(31) = '1' then + if ins(29) = '1' then + R2 <= ins(20 downto 16); + mem_write <= '1'; + 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_addr <= S; + + wait until rising_edge(mem_clk); + + wait for 100 ps; + + WD <= mem_r_data; + WRITE_REG <= '1'; + end if; + elsif ins(29 downto 26) = B"1111" then + WRITE_REG <= '1'; + W <= ins(20 downto 16); + WD(31 downto 16) <= ins(15 downto 0); + elsif ins(29) = '1' then + WRITE_REG <= '1'; + W <= ins(20 downto 16); + WD <= S; + else + 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; + end if; + 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 cpu_test_bench is +end entity; + +architecture Behavioral of cpu_test_bench is + signal CLK: std_logic; +begin + cpu : entity work.cpu; +end architecture; diff --git a/store/works/life/computer-organization-experiment/full_adder_1.vhdl b/store/works/life/computer-organization-experiment/full_adder_1.vhdl new file mode 100644 index 0000000..9b269bf --- /dev/null +++ b/store/works/life/computer-organization-experiment/full_adder_1.vhdl @@ -0,0 +1,13 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity full_adder_1 is + port (A, B, CI:in std_logic; S, CO: out std_logic); +end full_adder_1; + +architecture behavior of full_adder_1 is +begin + S <= (A XOR B) XOR CI; + CO <= (A AND B) OR (B AND CI) OR (CI AND A); +end architecture; diff --git a/store/works/life/computer-organization-experiment/multiplexer_1_2.vhdl b/store/works/life/computer-organization-experiment/multiplexer_1_2.vhdl new file mode 100644 index 0000000..1fdeb0f --- /dev/null +++ b/store/works/life/computer-organization-experiment/multiplexer_1_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_1_2 is + port (A0, A1, S : in std_logic; Y: out std_logic); +end multiplexer_1_2; + +architecture behaviour of multiplexer_1_2 is +begin + Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/store/works/life/computer-organization-experiment/multiplexer_32_2.vhdl b/store/works/life/computer-organization-experiment/multiplexer_32_2.vhdl new file mode 100644 index 0000000..1c7d626 --- /dev/null +++ b/store/works/life/computer-organization-experiment/multiplexer_32_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_32_2 is + port (A0, A1 : in std_logic_vector(31 downto 0); S : in std_logic; Y : out std_logic_vector(31 downto 0)); +end multiplexer_32_2; + +architecture behaviour of multiplexer_32_2 is +begin + Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/store/works/life/computer-organization-experiment/multiplexer_8_2.vhdl b/store/works/life/computer-organization-experiment/multiplexer_8_2.vhdl new file mode 100644 index 0000000..6be0bd2 --- /dev/null +++ b/store/works/life/computer-organization-experiment/multiplexer_8_2.vhdl @@ -0,0 +1,12 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity multiplexer_8_2 is + port (A0, A1 : in std_logic_vector(7 downto 0); S : in std_logic; Y : out std_logic_vector(7 downto 0)); +end multiplexer_8_2; + +architecture behaviour of multiplexer_8_2 is +begin + Y <= A0 when S = '0' else A1; +end behaviour; diff --git a/store/works/life/computer-organization-experiment/out.ghw b/store/works/life/computer-organization-experiment/out.ghw Binary files differnew file mode 100644 index 0000000..23af3af --- /dev/null +++ b/store/works/life/computer-organization-experiment/out.ghw diff --git a/store/works/life/computer-organization-experiment/out2.ghw b/store/works/life/computer-organization-experiment/out2.ghw Binary files differnew file mode 100644 index 0000000..8a5e9f8 --- /dev/null +++ b/store/works/life/computer-organization-experiment/out2.ghw diff --git a/store/works/life/computer-organization-experiment/shift_32.vhdl b/store/works/life/computer-organization-experiment/shift_32.vhdl new file mode 100644 index 0000000..5cb8425 --- /dev/null +++ b/store/works/life/computer-organization-experiment/shift_32.vhdl @@ -0,0 +1,23 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.numeric_std.all; + +entity shift_32 is + port( + D: in std_logic_vector(31 downto 0); + SA: in std_logic_vector(4 downto 0); + Right: in std_logic; + Arith: in std_logic; + SH: out std_logic_vector(31 downto 0) + ); +end entity; + +architecture behavioral of shift_32 is +begin + SH <= + std_logic_vector(signed(D) srl to_integer(unsigned(SA))) when Right = '1' and Arith = '0' + else std_logic_vector(signed(D) sll to_integer(unsigned(SA))) when Right = '0' and Arith = '0' + else std_logic_vector(signed(D) sra to_integer(unsigned(SA))) when Right = '1' and Arith = '1' + else std_logic_vector(signed(D) sla to_integer(unsigned(SA))) when Right = '0' and Arith = '1'; +end behavioral; diff --git a/store/works/life/computer-organization-experiment/test_bench.vhdl b/store/works/life/computer-organization-experiment/test_bench.vhdl new file mode 100644 index 0000000..d2910d7 --- /dev/null +++ b/store/works/life/computer-organization-experiment/test_bench.vhdl @@ -0,0 +1,146 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity test_bench is +end test_bench; + +architecture test_counter_4 of test_bench is + signal CLK : STD_LOGIC; + signal CQ: STD_LOGIC_VECTOR(3 DOWNTO 0); +begin + counter: entity work.counter_4(behavior) + port map (CLK, CQ); + stimulus: process is + begin + for count_value in 0 to 2 ** 4 - 1 loop + if count_value mod 2 = 0 then + CLK <= '1'; + wait for 5 ns; + else + CLK <= '0'; + wait for 5 ns; + end if; + end loop; + end process stimulus; +end architecture test_counter_4; + + +architecture test_full_adder_1 of test_bench is + subtype v3 is std_logic_vector(2 downto 0); + signal I: v3 := B"000"; + signal S, CO : STD_LOGIC; +begin + adder: entity work.full_adder_1(behavior) + port map (I(2), I(1), I(0), S, CO); + stimulus: process is + variable ii : v3 := B"000"; + begin + loop + ii := ii + 1; + I <= ii; + wait for 5 ns; + end loop; + end process stimulus; +end architecture test_full_adder_1; + +architecture test_multiplexer_32_2 of test_bench is + signal A0: std_logic_vector(31 downto 0) := B"11111111111111111111111111111111"; + signal A1: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; + signal S: std_logic; + signal Y: std_logic_vector(31 downto 0); +begin + multiplexer: entity work.multiplexer_32_2(behaviour) + port map (A0, A1, S, Y); + stimulus: process is + begin + loop + S <= '0'; + wait for 5 ns; + S <= '1'; + wait for 5 ns; + end loop; + end process stimulus; +end architecture test_multiplexer_32_2; + +architecture test_adder_32 of test_bench is + signal A: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; + signal B: std_logic_vector(31 downto 0) := B"00000000000000000000000000000000"; + signal CIN: std_logic; + signal S: std_logic_vector(31 downto 0); + signal COUT: std_logic; +begin + adder: entity work.adder_32(behavior) + port map (A, B, CIN, S, COUT); + stimulus: process is + begin + loop + A <= A + 1; + B <= B + 2; + CIN <= '0'; + wait for 5 ns; + CIN <= '1'; + wait for 5 ns; + end loop; + end process stimulus; +end architecture test_adder_32; + +architecture test_shift_32 of test_bench is + signal D: std_logic_vector(31 downto 0) := B"00000000000000000000000000000011"; + signal SA: std_logic_vector(4 downto 0) := B"00000"; + signal Right: std_logic; + signal Arith: std_logic; + signal SH: std_logic_vector(31 downto 0); +begin + shift: entity work.shift_32(behavioral) + port map (D, SA, Right, Arith, SH); + stimulus: process is + begin + loop + D <= B"00000000000000000000000000000011" and D; + Right <= '0'; + Arith <= '0'; + wait for 5 ns; + Arith <= '1'; + wait for 5 ns; + Right <= '1'; + Arith <= '0'; + wait for 5 ns; + Arith <= '1'; + wait for 5 ns; + D <= B"10000000000000000000000000000000" or D; + Right <= '0'; + Arith <= '0'; + wait for 5 ns; + Arith <= '1'; + wait for 5 ns; + Right <= '1'; + Arith <= '0'; + wait for 5 ns; + Arith <= '1'; + wait for 5 ns; + + SA <= SA + 1; + end loop; + end process stimulus; +end architecture test_shift_32; + + +architecture test_alu of test_bench is + signal A: std_logic_vector(31 downto 0) := "00000000000000000000000000000011"; + signal B: std_logic_vector(31 downto 0) := "00000000000000000000000000000011"; + signal S: std_logic_vector(31 downto 0); + signal ALUC: std_logic_vector(3 downto 0) := "0000"; + signal Z: std_logic; +begin + alu: entity work.alu(Behavioral) + port map (A, B, ALUC, S, Z); + stimulus: process is + begin + loop + wait for 5 ns; + ALUC <= ALUC + 1; + end loop; + + end process stimulus; +end architecture test_alu;
\ No newline at end of file |