Add Tercel PHY reset synchronization
[microwatt.git] / dram_tb.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.common.all;
7 use work.wishbone_types.all;
8
9 entity dram_tb is
10 generic (
11 DRAM_INIT_FILE : string := "";
12 DRAM_INIT_SIZE : natural := 0
13 );
14 end dram_tb;
15
16 architecture behave of dram_tb is
17 signal clk, rst: std_logic;
18 signal clk_in, soc_rst : std_ulogic;
19
20 -- testbench signals
21 constant clk_period : time := 10 ns;
22
23 -- Sim DRAM
24 signal wb_in : wishbone_master_out;
25 signal wb_out : wishbone_slave_out;
26 signal wb_ctrl_in : wb_io_master_out;
27
28 subtype addr_t is std_ulogic_vector(wb_in.adr'left downto 0);
29 subtype data_t is std_ulogic_vector(wb_in.dat'left downto 0);
30 subtype sel_t is std_ulogic_vector(wb_in.sel'left downto 0);
31
32 -- Counter for acks
33 signal acks : integer := 0;
34 signal reset_acks : std_ulogic;
35
36 -- Read data fifo
37 signal rd_ready : std_ulogic := '0';
38 signal rd_valid : std_ulogic;
39 signal rd_data : data_t;
40 begin
41
42 dram: entity work.litedram_wrapper
43 generic map(
44 DRAM_ABITS => 24,
45 DRAM_ALINES => 1,
46 DRAM_DLINES => 16,
47 DRAM_CKLINES => 1,
48 DRAM_PORT_WIDTH => 128,
49 PAYLOAD_FILE => DRAM_INIT_FILE,
50 PAYLOAD_SIZE => DRAM_INIT_SIZE
51 )
52 port map(
53 clk_in => clk_in,
54 rst => rst,
55 system_clk => clk,
56 system_reset => soc_rst,
57 core_alt_reset => open,
58 pll_locked => open,
59
60 wb_in => wb_in,
61 wb_out => wb_out,
62 wb_ctrl_in => wb_ctrl_in,
63 wb_ctrl_out => open,
64 wb_ctrl_is_csr => '0',
65 wb_ctrl_is_init => '0',
66
67 init_done => open,
68 init_error => open,
69
70 ddram_a => open,
71 ddram_ba => open,
72 ddram_ras_n => open,
73 ddram_cas_n => open,
74 ddram_we_n => open,
75 ddram_cs_n => open,
76 ddram_dm => open,
77 ddram_dq => open,
78 ddram_dqs_p => open,
79 ddram_dqs_n => open,
80 ddram_clk_p => open,
81 ddram_clk_n => open,
82 ddram_cke => open,
83 ddram_odt => open,
84 ddram_reset_n => open
85 );
86
87 clk_process: process
88 begin
89 clk_in <= '0';
90 wait for clk_period/2;
91 clk_in <= '1';
92 wait for clk_period/2;
93 end process;
94
95 rst_process: process
96 begin
97 rst <= '1';
98 wait for 10*clk_period;
99 rst <= '0';
100 wait;
101 end process;
102
103 wb_ctrl_in.cyc <= '0';
104 wb_ctrl_in.stb <= '0';
105
106 -- Read data receive queue
107 data_queue: entity work.sync_fifo
108 generic map (
109 DEPTH => 16,
110 WIDTH => rd_data'length
111 )
112 port map (
113 clk => clk,
114 reset => soc_rst or reset_acks,
115 rd_ready => rd_ready,
116 rd_valid => rd_valid,
117 rd_data => rd_data,
118 wr_ready => open,
119 wr_valid => wb_out.ack,
120 wr_data => wb_out.dat
121 );
122
123 recv_acks: process(clk)
124 begin
125 if rising_edge(clk) then
126 if rst = '1' or reset_acks = '1' then
127 acks <= 0;
128 elsif wb_out.ack = '1' then
129 acks <= acks + 1;
130 -- report "WB ACK ! DATA=" & to_hstring(wb_out.dat);
131 end if;
132 end if;
133 end process;
134
135 sim: process
136 procedure wb_write(addr: addr_t; data: data_t; sel: sel_t) is
137 begin
138 wb_in.adr <= addr;
139 wb_in.sel <= sel;
140 wb_in.dat <= data;
141 wb_in.we <= '1';
142 wb_in.stb <= '1';
143 wb_in.cyc <= '1';
144 loop
145 wait until rising_edge(clk);
146 if wb_out.stall = '0' then
147 wb_in.stb <= '0';
148 exit;
149 end if;
150 end loop;
151 end procedure;
152
153 procedure wb_read(addr: addr_t) is
154 begin
155 wb_in.adr <= addr;
156 wb_in.sel <= x"ff";
157 wb_in.we <= '0';
158 wb_in.stb <= '1';
159 wb_in.cyc <= '1';
160 loop
161 wait until rising_edge(clk);
162 if wb_out.stall = '0' then
163 wb_in.stb <= '0';
164 exit;
165 end if;
166 end loop;
167 end procedure;
168
169 procedure wait_acks(count: integer) is
170 begin
171 wait until acks = count;
172 wait until rising_edge(clk);
173 end procedure;
174
175 procedure clr_acks is
176 begin
177 reset_acks <= '1';
178 wait until rising_edge(clk);
179 reset_acks <= '0';
180 end procedure;
181
182 procedure read_data(data: out data_t) is
183 begin
184 assert rd_valid = '1' report "No data to read" severity failure;
185 rd_ready <= '1';
186 wait until rising_edge(clk);
187 rd_ready <= '0';
188 data := rd_data;
189 end procedure;
190
191 function add_off(a: addr_t; off: integer) return addr_t is
192 begin
193 return addr_t(unsigned(a) + off);
194 end function;
195
196 function make_pattern(num : integer) return data_t is
197 variable r : data_t;
198 variable t,b : integer;
199 begin
200 for i in 0 to (data_t'length/8)-1 loop
201 t := (i+1)*8-1;
202 b := i*8;
203 r(t downto b) := std_ulogic_vector(to_unsigned(num+1, 8));
204 end loop;
205 return r;
206 end function;
207
208 procedure check_data(p: data_t) is
209 variable d : data_t;
210 begin
211 read_data(d);
212 assert d = p report "bad data, want " & to_hstring(p) &
213 " got " & to_hstring(d) severity failure;
214 end procedure;
215
216 variable a : addr_t := (others => '0');
217 variable d : data_t := (others => '0');
218 variable d1 : data_t := (others => '0');
219 begin
220 reset_acks <= '0';
221 rst <= '1';
222 wait until rising_edge(clk_in);
223 wait until rising_edge(clk_in);
224 wait until rising_edge(clk_in);
225 wait until rising_edge(clk_in);
226 wait until rising_edge(clk_in);
227 rst <= '0';
228 wait until rising_edge(clk_in);
229 wait until soc_rst = '0';
230 wait until rising_edge(clk);
231
232 report "Simple write miss...";
233 clr_acks;
234 wb_write(a, x"0123456789abcdef", x"ff");
235 wait_acks(1);
236
237 report "Simple read miss...";
238 clr_acks;
239 wb_read(a);
240 wait_acks(1);
241 read_data(d);
242 assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
243
244 report "Simple read hit...";
245 clr_acks;
246 wb_read(a);
247 wait_acks(1);
248 read_data(d);
249 assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
250
251 report "Back to back 4 stores 4 reads on hit...";
252 clr_acks;
253 for i in 0 to 3 loop
254 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
255 end loop;
256 for i in 0 to 3 loop
257 wb_read(add_off(a, i*8));
258 end loop;
259 wait_acks(8);
260 for i in 0 to 7 loop
261 if i < 4 then
262 read_data(d);
263 else
264 check_data(make_pattern(i-4));
265 end if;
266 end loop;
267
268 report "Back to back 4 stores 4 reads on miss...";
269 a(10) := '1';
270 clr_acks;
271 for i in 0 to 3 loop
272 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
273 end loop;
274 for i in 0 to 3 loop
275 wb_read(add_off(a, i*8));
276 end loop;
277 wait_acks(8);
278 for i in 0 to 7 loop
279 if i < 4 then
280 read_data(d);
281 else
282 check_data(make_pattern(i-4));
283 end if;
284 end loop;
285
286 report "Back to back interleaved 4 stores 4 reads on hit...";
287 a(10) := '1';
288 clr_acks;
289 for i in 0 to 3 loop
290 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
291 wb_read(add_off(a, i*8));
292 end loop;
293 wait_acks(8);
294 for i in 0 to 3 loop
295 read_data(d);
296 check_data(make_pattern(i));
297 end loop;
298
299 report "Pre-fill a line";
300 a(11) := '1';
301 clr_acks;
302 wb_write(add_off(a, 0), x"1111111100000000", x"ff");
303 wb_write(add_off(a, 8), x"3333333322222222", x"ff");
304 wb_write(add_off(a, 16), x"5555555544444444", x"ff");
305 wb_write(add_off(a, 24), x"7777777766666666", x"ff");
306 wb_write(add_off(a, 32), x"9999999988888888", x"ff");
307 wb_write(add_off(a, 40), x"bbbbbbbbaaaaaaaa", x"ff");
308 wb_write(add_off(a, 48), x"ddddddddcccccccc", x"ff");
309 wb_write(add_off(a, 56), x"ffffffffeeeeeeee", x"ff");
310 wb_write(add_off(a, 64), x"1111111100000000", x"ff");
311 wb_write(add_off(a, 72), x"3333333322222222", x"ff");
312 wb_write(add_off(a, 80), x"5555555544444444", x"ff");
313 wb_write(add_off(a, 88), x"7777777766666666", x"ff");
314 wb_write(add_off(a, 96), x"9999999988888888", x"ff");
315 wb_write(add_off(a,104), x"bbbbbbbbaaaaaaaa", x"ff");
316 wb_write(add_off(a,112), x"ddddddddcccccccc", x"ff");
317 wb_write(add_off(a,120), x"ffffffffeeeeeeee", x"ff");
318 wait_acks(16);
319
320 report "Scattered from middle of line...";
321 clr_acks;
322 wb_read(add_off(a,24));
323 wb_read(add_off(a,32));
324 wb_read(add_off(a, 0));
325 wb_read(add_off(a,16));
326 wait_acks(4);
327 read_data(d);
328 assert d = x"7777777766666666" report "bad data (24), got " & to_hstring(d) severity failure;
329 read_data(d);
330 assert d = x"9999999988888888" report "bad data (32), got " & to_hstring(d) severity failure;
331 read_data(d);
332 assert d = x"1111111100000000" report "bad data (0), got " & to_hstring(d) severity failure;
333 read_data(d);
334 assert d = x"5555555544444444" report "bad data (16), got " & to_hstring(d) severity failure;
335
336 std.env.finish;
337 end process;
338 end architecture;