Newer
Older
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
-------------------------------------------------------------------------------
-- Project ELE8304 : Circuits intégrés à très grande échelle
-------------------------------------------------------------------------------
-- File riscv_decode_tb.vhd
-- Authors Titouan Luard <luardtitouan@gmail.com>
-- Yann Roberge <yann.roberge@polymtl.ca>
-- Lab ELE8304-9
-- Date 2021-11-28
-------------------------------------------------------------------------------
-- Brief RISC-V Register file
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
library work;
use work.riscv_pkg.all;
entity riscv_decode_tb is
end riscv_decode_tb;
architecture tb of riscv_decode_tb is
-- Entrées/Sorties du DUT
-- Write to a register, no checking of what's coming out
-- TODO: Adapter
procedure write_reg (
signal rstn : out std_logic;
signal addr_ra : out std_logic_vector(REG_WIDTH-1 downto 0);
signal addr_rb : out std_logic_vector(REG_WIDTH-1 downto 0);
signal addr_w : out std_logic_vector(REG_WIDTH-1 downto 0);
signal data_w : out std_logic_vector(XLEN-1 downto 0);
signal we : out std_logic;
constant test_addr_w : in std_logic_vector(REG_WIDTH-1 downto 0);
constant test_data_w : in std_logic_vector(XLEN-1 downto 0);
constant period : in time) is
begin
rstn <= '1';
addr_ra <= (others => '-');
addr_rb <= (others => '-');
addr_w <= test_addr_w;
data_w <= test_data_w;
we <= '1';
wait for period;
report "Wrote " & to_string(data_w) & " to reg " & to_string(addr_w);
addr_w <= (others => '-');
data_w <= (others => '-');
we <= '0';
wait for period;
end procedure write_reg;
-- Procédure pour un vecteur de test
-- TODO: Adapter
procedure test_vector (
constant period : in time) is
begin
wait for period;
assert data_ra = expected_ra
report "REGISTER A DIFFERS FROM EXPECTED" severity error;
assert data_rb = expected_rb
report "REGISTER B DIFFERS FROM EXPECTED" severity error;
end procedure test_vector;
constant PERIOD : time := 10 ns;
begin
-- Instanciation du DUT
--dut: entity work.riscv_rf
-- port map (
-- i_clk => clk,
-- i_rstn => rstn,
-- i_we => we,
-- i_addr_ra => addr_ra,
-- o_data_ra => data_ra,
-- i_addr_rb => addr_rb,
-- o_data_rb => data_rb,
-- i_addr_w => addr_w,
-- i_data_w => data_w
-- );
-- Drive clock
drive_clk : process is
begin
clk <= '0';
wait for PERIOD/2;
clk <= '1';
wait for PERIOD/2;
end process drive_clk;
-- Main TB process
p_main : process is
constant DUMMY_DATA : std_logic_vector(XLEN-1 downto 0) := (3 downto 0 => "1010", others => '1');
begin
-- Tests des cas représentatif
report "BEGIN SIMULATION";
--rstn <= '0';
--addr_ra <= (others => '-');
--addr_rb <= (others => '-');
--addr_w <= (others => '-');
--data_w <= (others => '-');
--we <= '-';
wait for PERIOD;
rstn <= '1';
wait for 2*PERIOD;
-- Write all registers
-- TODO: Adapter mais le laisser faire la même chose
report "Write all registers except 0x00";
for i in 1 to 2**(REG_WIDTH)-1 loop
write_reg(
rstn => rstn,
addr_ra => addr_ra,
addr_rb => addr_rb,
addr_w => addr_w,
data_w => data_w,
we => we,
test_addr_w => std_logic_vector(to_unsigned(i, REG_WIDTH)),
test_data_w => std_logic_vector(to_unsigned(i + 3, XLEN)),
period => PERIOD
);
end loop;
-- Read back all registers
-- TODO: Adapter mais le laisser faire la même chose
report "Read back all registers";
test_vector( -- special case for register 0
rstn => rstn,
addr_ra => addr_ra,
addr_rb => addr_rb,
addr_w => addr_w,
data_w => data_w,
we => we,
data_ra => data_ra,
data_rb => data_rb,
test_addr_ra => std_logic_vector(to_unsigned(0, addr_ra'length)),
test_addr_rb => std_logic_vector(to_unsigned(0, addr_rb'length)),
test_addr_w => (others => '-'),
test_data_w => (others => '-'),
test_we => '0',
expected_ra => (others => '0'),
expected_rb => (others => '0'),
period => PERIOD
);
for i in 1 to 2**(REG_WIDTH)-2 loop
test_vector(
rstn => rstn,
addr_ra => addr_ra,
addr_rb => addr_rb,
addr_w => addr_w,
data_w => data_w,
we => we,
data_ra => data_ra,
data_rb => data_rb,
test_addr_ra => std_logic_vector(to_unsigned(i, addr_ra'length)),
test_addr_rb => std_logic_vector(to_unsigned(i+1, addr_rb'length)),
test_addr_w => (others => '-'),
test_data_w => (others => '-'),
test_we => '0',
expected_ra => std_logic_vector(to_unsigned(i+3, data_ra'length)),
expected_rb => std_logic_vector(to_unsigned(i+4, data_rb'length)),
period => PERIOD
);
end loop;
report "Test every instruction in supported ISA";
-- LUI: registre 0x03 <- pattern 0101 répété sur 20 bits
-- JAL
-- JALR
-- BEQ
-- LW
-- SW
-- ADDI
-- SLTI
-- SLTUI
-- XORI
-- ORI
-- ANDI
-- SLLI
-- SRLI
-- SRAI
-- ADD
-- SUB
-- SLL
-- SLT
-- SLTU
-- XOR
-- SRL
-- SRA
-- OR
-- AND
-- Flush pipeline
-- Reset entire stage
report "Reset";
rstn <= '0';
wait for PERIOD;
rstn <= '1';
wait for PERIOD;
report "SIMULATION DONE";
wait;
end process p_main;
end architecture tb;