-
Notifications
You must be signed in to change notification settings - Fork 101
/
icache_tb.vhdl
162 lines (134 loc) · 4.21 KB
/
icache_tb.vhdl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.common.all;
use work.wishbone_types.all;
entity icache_tb is
end icache_tb;
architecture behave of icache_tb is
signal clk : std_ulogic;
signal rst : std_ulogic;
signal i_out : Fetch1ToIcacheType;
signal i_in : IcacheToDecode1Type;
signal wb_bram_in : wishbone_master_out;
signal wb_bram_out : wishbone_slave_out;
constant clk_period : time := 10 ns;
begin
icache0: entity work.icache
generic map(
LINE_SIZE => 64,
NUM_LINES => 4
)
port map(
clk => clk,
rst => rst,
i_in => i_out,
i_out => i_in,
stall_in => '0',
flush_in => '0',
inval_in => '0',
wishbone_out => wb_bram_in,
wishbone_in => wb_bram_out
);
-- BRAM Memory slave
bram0: entity work.wishbone_bram_wrapper
generic map(
MEMORY_SIZE => 1024,
RAM_INIT_FILE => "icache_test.bin"
)
port map(
clk => clk,
rst => rst,
wishbone_in => wb_bram_in,
wishbone_out => wb_bram_out
);
clk_process: process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
rst_process: process
begin
rst <= '1';
wait for 2*clk_period;
rst <= '0';
wait;
end process;
stim: process
begin
i_out.req <= '0';
i_out.nia <= (others => '0');
i_out.stop_mark <= '0';
i_out.priv_mode <= '1';
i_out.virt_mode <= '0';
i_out.big_endian <= '0';
i_out.fetch_fail <= '0';
i_out.predicted <= '0';
i_out.pred_ntaken <= '0';
wait until rising_edge(clk);
wait until rising_edge(clk);
wait until rising_edge(clk);
i_out.next_nia <= x"0000000000000004";
i_out.next_rpn <= (others => '0');
wait until rising_edge(clk);
i_out.req <= '1';
i_out.nia <= x"0000000000000004";
i_out.rpn <= (others => '0');
wait for 30*clk_period;
wait until rising_edge(clk);
assert i_in.valid = '1' severity failure;
assert i_in.insn = x"00000001"
report "insn @" & to_hstring(i_out.nia) &
"=" & to_hstring(i_in.insn) &
" expected 00000001"
severity failure;
i_out.req <= '0';
i_out.next_nia <= x"0000000000000008";
wait until rising_edge(clk);
-- hit
i_out.req <= '1';
i_out.nia <= x"0000000000000008";
wait until rising_edge(clk);
wait until rising_edge(clk);
assert i_in.valid = '1' severity failure;
assert i_in.insn = x"00000002"
report "insn @" & to_hstring(i_out.nia) &
"=" & to_hstring(i_in.insn) &
" expected 00000002"
severity failure;
i_out.next_nia <= x"0000000000000040";
wait until rising_edge(clk);
-- another miss
i_out.req <= '1';
i_out.nia <= x"0000000000000040";
wait for 30*clk_period;
wait until rising_edge(clk);
assert i_in.valid = '1' severity failure;
assert i_in.insn = x"00000010"
report "insn @" & to_hstring(i_out.nia) &
"=" & to_hstring(i_in.insn) &
" expected 00000010"
severity failure;
-- test something that aliases
i_out.next_nia <= x"0000000000000100";
wait until rising_edge(clk);
i_out.req <= '1';
i_out.nia <= x"0000000000000100";
wait until rising_edge(clk);
wait until rising_edge(clk);
assert i_in.valid = '0' severity failure;
wait until rising_edge(clk);
wait for 30*clk_period;
wait until rising_edge(clk);
assert i_in.valid = '1' severity failure;
assert i_in.insn = x"00000040"
report "insn @" & to_hstring(i_out.nia) &
"=" & to_hstring(i_in.insn) &
" expected 00000040"
severity failure;
i_out.req <= '0';
std.env.finish;
end process;
end;