2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
7 use work.wishbone_types.all;
11 DRAM_INIT_FILE : string := "";
12 DRAM_INIT_SIZE : natural := 0
16 architecture behave of dram_tb is
17 signal clk, rst: std_logic;
18 signal clk_in, soc_rst : std_ulogic;
21 constant clk_period : time := 10 ns;
24 signal wb_in : wishbone_master_out;
25 signal wb_out : wishbone_slave_out;
26 signal wb_ctrl_in : wb_io_master_out;
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);
33 signal acks : integer := 0;
34 signal reset_acks : std_ulogic;
37 signal rd_ready : std_ulogic := '0';
38 signal rd_valid : std_ulogic;
39 signal rd_data : data_t;
42 dram: entity work.litedram_wrapper
46 PAYLOAD_FILE => DRAM_INIT_FILE,
47 PAYLOAD_SIZE => DRAM_INIT_SIZE
53 system_reset => soc_rst,
54 core_alt_reset => open,
59 wb_ctrl_in => wb_ctrl_in,
61 wb_ctrl_is_csr => '0',
62 wb_ctrl_is_init => '0',
87 wait for clk_period/2;
89 wait for clk_period/2;
95 wait for 10*clk_period;
100 wb_ctrl_in.cyc <= '0';
101 wb_ctrl_in.stb <= '0';
103 -- Read data receive queue
104 data_queue: entity work.sync_fifo
107 WIDTH => rd_data'length
111 reset => soc_rst or reset_acks,
112 rd_ready => rd_ready,
113 rd_valid => rd_valid,
116 wr_valid => wb_out.ack,
117 wr_data => wb_out.dat
120 recv_acks: process(clk)
122 if rising_edge(clk) then
123 if rst = '1' or reset_acks = '1' then
125 elsif wb_out.ack = '1' then
127 -- report "WB ACK ! DATA=" & to_hstring(wb_out.dat);
133 procedure wb_write(addr: addr_t; data: data_t; sel: sel_t) is
142 wait until rising_edge(clk);
143 if wb_out.stall = '0' then
150 procedure wb_read(addr: addr_t) is
158 wait until rising_edge(clk);
159 if wb_out.stall = '0' then
166 procedure wait_acks(count: integer) is
168 wait until acks = count;
169 wait until rising_edge(clk);
172 procedure clr_acks is
175 wait until rising_edge(clk);
179 procedure read_data(data: out data_t) is
181 assert rd_valid = '1' report "No data to read" severity failure;
183 wait until rising_edge(clk);
188 function add_off(a: addr_t; off: integer) return addr_t is
190 return addr_t(unsigned(a) + off);
193 function make_pattern(num : integer) return data_t is
195 variable t,b : integer;
197 for i in 0 to (data_t'length/8)-1 loop
200 r(t downto b) := std_ulogic_vector(to_unsigned(num+1, 8));
205 procedure check_data(p: data_t) is
209 assert d = p report "bad data, want " & to_hstring(p) &
210 " got " & to_hstring(d) severity failure;
213 variable a : addr_t := (others => '0');
214 variable d : data_t := (others => '0');
215 variable d1 : data_t := (others => '0');
219 wait until rising_edge(clk_in);
220 wait until rising_edge(clk_in);
221 wait until rising_edge(clk_in);
222 wait until rising_edge(clk_in);
223 wait until rising_edge(clk_in);
225 wait until rising_edge(clk_in);
226 wait until soc_rst = '0';
227 wait until rising_edge(clk);
229 report "Simple write miss...";
231 wb_write(a, x"0123456789abcdef", x"ff");
234 report "Simple read miss...";
239 assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
241 report "Simple read hit...";
246 assert d = x"0123456789abcdef" report "bad data, got " & to_hstring(d) severity failure;
248 report "Back to back 4 stores 4 reads on hit...";
251 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
254 wb_read(add_off(a, i*8));
261 check_data(make_pattern(i-4));
265 report "Back to back 4 stores 4 reads on miss...";
269 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
272 wb_read(add_off(a, i*8));
279 check_data(make_pattern(i-4));
283 report "Back to back interleaved 4 stores 4 reads on hit...";
287 wb_write(add_off(a, i*8), make_pattern(i), x"ff");
288 wb_read(add_off(a, i*8));
293 check_data(make_pattern(i));