Skip to content

Commit d9ee04b

Browse files
committed
adding cpu testbench
1 parent 5e46488 commit d9ee04b

File tree

7 files changed

+230
-7
lines changed

7 files changed

+230
-7
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library ieee;
2+
use ieee.std_logic_1164.all;
3+
4+
5+
entity adding_cpu is
6+
port(
7+
clk : in std_logic;
8+
rst : in std_logic;
9+
address_bus : out std_logic_vector(5 downto 0);
10+
read_mem : out std_logic;
11+
write_mem : out std_logic;
12+
data_bus : inout std_logic_vector(7 downto 0)
13+
);
14+
end entity;
15+
16+
17+
architecture structural of adding_cpu is
18+
signal ir_on_address : std_logic;
19+
signal pc_on_address : std_logic;
20+
signal dbus_on_data : std_logic;
21+
signal data_on_dbus : std_logic;
22+
signal load_ir : std_logic;
23+
signal load_ac : std_logic;
24+
signal load_pc : std_logic;
25+
signal inc_pc : std_logic;
26+
signal clear_pc : std_logic;
27+
signal pass : std_logic;
28+
signal add : std_logic;
29+
signal alu_on_dbus : std_logic;
30+
signal op_code : std_logic_vector(1 downto 0);
31+
begin
32+
contoller: entity work.controller
33+
port map(
34+
clk, rst, op_code, read_mem, write_mem, ir_on_address,
35+
pc_on_address, dbus_on_data, data_on_dbus, load_ir,
36+
load_ac, load_pc, inc_pc, clear_pc, pass, add, alu_on_dbus
37+
);
38+
datapath: entity work.datapath
39+
port map(
40+
clk, ir_on_address, pc_on_address, dbus_on_data, data_on_dbus,
41+
load_ir, load_ac, load_pc, inc_pc, clear_pc, pass, add,
42+
alu_on_dbus, address_bus, op_code, data_bus
43+
);
44+
end architecture;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
library ieee;
2+
library vunit_lib;
3+
4+
use ieee.std_logic_1164.all;
5+
use ieee.numeric_std.all;
6+
context vunit_lib.vunit_context;
7+
8+
9+
entity adding_cpu_tb is
10+
generic(runner_cfg : string);
11+
end entity;
12+
13+
14+
architecture tb of adding_cpu_tb is
15+
constant half_period : time := 1 ps;
16+
17+
signal clk : std_logic := '0';
18+
signal rst : std_logic := '1';
19+
signal read_mem, write_mem : std_logic;
20+
signal address_bus : std_logic_vector(5 downto 0);
21+
signal data_bus : std_logic_vector(7 downto 0);
22+
begin
23+
-- Device under test.
24+
dut: entity work.adding_cpu
25+
port map(clk, rst, address_bus, read_mem, write_mem, data_bus);
26+
27+
-- Generate clock.
28+
clk <= not clk after half_period;
29+
rst <= '0' after 2 ps;
30+
31+
main: process
32+
variable address_bus_result : std_logic_vector(address_bus'range);
33+
variable data_bus_result : std_logic_vector(data_bus'range);
34+
begin
35+
test_runner_setup(runner, runner_cfg);
36+
while test_suite loop
37+
if run("init_state_mem_signals") then
38+
check_equal(read_mem, '0');
39+
check_equal(read_mem, '0');
40+
wait until rst = '0';
41+
check_equal(read_mem, '0');
42+
check_equal(write_mem, '0');
43+
wait until rising_edge(clk);
44+
check_equal(read_mem, '0');
45+
check_equal(write_mem, '0');
46+
wait until rising_edge(clk);
47+
check_equal(read_mem, '1');
48+
check_equal(write_mem, '0');
49+
elsif run("init_state_address_bus") then
50+
address_bus_result := "ZZZZZZ";
51+
wait until read_mem = '1';
52+
check_equal(address_bus, address_bus_result);
53+
wait until rising_edge(clk); -- fetch
54+
address_bus_result := "000000";
55+
check_equal(address_bus, address_bus_result);
56+
elsif run("load_opcode") then
57+
data_bus <= "00111111"; -- load from 111111
58+
wait until read_mem = '1';
59+
wait until rising_edge(clk); -- fetch
60+
wait until rising_edge(clk); -- decode
61+
wait until rising_edge(clk); -- execute
62+
address_bus_result := "111111";
63+
64+
check_equal(address_bus, address_bus_result);
65+
check_equal(read_mem, '1');
66+
check_equal(write_mem, '0');
67+
elsif run("store_opcode") then
68+
data_bus <= "01011111"; -- store to 011111
69+
wait until read_mem = '1';
70+
wait until rising_edge(clk); -- fetch
71+
wait until rising_edge(clk); -- decode
72+
wait until rising_edge(clk); -- execute
73+
address_bus_result := "011111";
74+
75+
check_equal(address_bus, address_bus_result);
76+
check_equal(read_mem, '0');
77+
check_equal(write_mem, '1');
78+
elsif run("jump_opcode") then
79+
data_bus <= "10111111"; -- jump to 111111
80+
wait until read_mem = '1';
81+
wait until rising_edge(clk); -- fetch
82+
wait until rising_edge(clk); -- decode
83+
wait until rising_edge(clk); -- execute
84+
wait until rising_edge(clk); -- fetch
85+
address_bus_result := "111111";
86+
87+
check_equal(address_bus, address_bus_result);
88+
check_equal(read_mem, '1');
89+
check_equal(write_mem, '0');
90+
elsif run("add_opcode") then
91+
wait until read_mem = '1';
92+
data_bus <= "00000000"; -- load 00000000 to ac
93+
wait until rising_edge(clk); -- fetch
94+
wait until rising_edge(clk); -- decode
95+
wait until rising_edge(clk); -- execute
96+
data_bus <= "11011111"; -- add 011111
97+
wait until rising_edge(clk); -- fetch
98+
wait until rising_edge(clk); -- decode
99+
wait until rising_edge(clk); -- execute
100+
data_bus <= "01000000"; -- store result to 000000
101+
wait until rising_edge(clk); -- fetch
102+
wait until rising_edge(clk); -- decode
103+
-- set bus to Z state so dut can drive it.
104+
data_bus <= "ZZZZZZZZ";
105+
wait until rising_edge(clk); -- execute
106+
data_bus_result := "00011111";
107+
108+
check_equal(data_bus, data_bus_result);
109+
end if;
110+
end loop;
111+
test_runner_cleanup(runner);
112+
end process;
113+
end architecture;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
library ieee;
2+
library vunit_lib;
3+
4+
use ieee.std_logic_1164.all;
5+
use ieee.numeric_std.all;
6+
context vunit_lib.vunit_context;
7+
8+
9+
entity adding_cpu_tb is
10+
generic(runner_cfg : string);
11+
end entity;
12+
13+
14+
architecture tb of adding_cpu_tb is
15+
constant half_period : time := 1 ps;
16+
17+
signal clk : std_logic := '0';
18+
signal rst : std_logic := '1';
19+
signal read_mem, write_mem : std_logic;
20+
signal address_bus : std_logic_vector(5 downto 0);
21+
signal data_bus : std_logic_vector(7 downto 0);
22+
begin
23+
-- Device under test.
24+
dut: entity work.adding_cpu
25+
port map(clk, rst, address_bus, read_mem, write_mem, data_bus);
26+
27+
-- Generate clock.
28+
clk <= not clk after half_period;
29+
rst <= '0' after 2 ps;
30+
31+
main: process
32+
variable address_bus_result : std_logic_vector(address_bus'range);
33+
variable data_bus_result : std_logic_vector(data_bus'range);
34+
begin
35+
test_runner_setup(runner, runner_cfg);
36+
while test_suite loop
37+
if run("init_state_mem_signals") then
38+
check_equal(read_mem, '0');
39+
check_equal(read_mem, '0');
40+
wait until rst = '0';
41+
check_equal(read_mem, '0');
42+
check_equal(write_mem, '0');
43+
wait until rising_edge(clk);
44+
check_equal(read_mem, '0');
45+
check_equal(write_mem, '0');
46+
wait until rising_edge(clk);
47+
check_equal(read_mem, '1');
48+
check_equal(write_mem, '0');
49+
elsif run("load_opcode") then
50+
data_bus <= "00111111"; -- load from 111111
51+
wait until read_mem = '1';
52+
wait until rising_edge(clk); -- fetch
53+
address_bus_result := "000000";
54+
check_equal(address_bus, address_bus_result);
55+
wait until rising_edge(clk); -- decode
56+
wait until rising_edge(clk); -- execute
57+
address_bus_result := "111111";
58+
check_equal(address_bus, address_bus_result);
59+
check_equal(read_mem, '1');
60+
end if;
61+
end loop;
62+
test_runner_cleanup(runner);
63+
end process;
64+
end architecture;

components-and-cores/adding-cpu/controller.vhd

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use ieee.std_logic_1164.all;
44

55
entity controller is
66
port(
7-
rst : in std_logic;
87
clk : in std_logic;
8+
rst : in std_logic;
99
op_code : in std_logic_vector(1 downto 0);
1010
read_mem : out std_logic;
1111
write_mem : out std_logic;
@@ -77,20 +77,20 @@ begin
7777
when execute =>
7878
next_state <= fetch;
7979
case op_code is
80-
when "00" =>
80+
when "00" => -- load
8181
ir_on_address <= '1';
8282
read_mem <= '1';
8383
data_on_dbus <= '1';
8484
load_ac <= '1';
85-
when "01" =>
85+
when "01" => -- store
8686
dbus_on_data <= '1';
8787
alu_on_dbus <= '1';
8888
pass <= '1';
8989
write_mem <= '1';
9090
ir_on_address <= '1';
91-
when "10" =>
91+
when "10" => -- jump
9292
load_pc <= '1';
93-
when "11" =>
93+
when "11" => -- add
9494
add <= '1';
9595
alu_on_dbus <= '1';
9696
load_ac <= '1';

components-and-cores/adding-cpu/datapath.vhd

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ begin
4444

4545
-- Wire rest of the signals like data busses and their logic.
4646
b_side <= "00" & ir_out(5 downto 0);
47-
address_bus <= ir_out(5 downto 0)
48-
when ir_on_address = '1' else (others => 'Z');
47+
address_bus <= ir_out(5 downto 0) when ir_on_address = '1' else (others => 'Z');
4948
address_bus <= pc_out when pc_on_address = '1' else (others => 'Z');
5049
dbus <= alu_out when alu_on_dbus = '1' else (others => 'Z');
5150
dbus <= data_bus when data_on_dbus = '1' else (others => 'Z');

components-and-cores/adding-cpu/vimhdl.prj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ vhdl work program_counter.vhd -2008
77
vhdl work alu.vhd -2008
88
vhdl work datapath.vhd -2008
99
vhdl work controller.vhd -2008
10+
vhdl work adding_cpu.vhd -2008
11+
vhdl work adding_cpu_tb.vhd -2008

run.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
vu = VUnit.from_argv()
44
lib = vu.add_library('lib')
55
lib.add_source_files("components-and-cores/arithmetic/array-multiplier/*.vhd")
6+
lib.add_source_files("components-and-cores/adding-cpu/*.vhd")
67
vu.main()

0 commit comments

Comments
 (0)