1 |
2 |
wfjm |
-- $Id: tb_rri.vhd 314 2010-07-09 17:38:41Z mueller $
|
2 |
|
|
--
|
3 |
|
|
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
4 |
|
|
--
|
5 |
|
|
-- This program is free software; you may redistribute and/or modify it under
|
6 |
|
|
-- the terms of the GNU General Public License as published by the Free
|
7 |
|
|
-- Software Foundation, either version 2, or at your option any later version.
|
8 |
|
|
--
|
9 |
|
|
-- This program is distributed in the hope that it will be useful, but
|
10 |
|
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
11 |
|
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
12 |
|
|
-- for complete details.
|
13 |
|
|
--
|
14 |
|
|
------------------------------------------------------------------------------
|
15 |
|
|
-- Module Name: tb_rri - sim
|
16 |
|
|
-- Description: Test bench for rri_core
|
17 |
|
|
--
|
18 |
|
|
-- Dependencies: simlib/simclk
|
19 |
|
|
-- genlib/clkdivce
|
20 |
|
|
-- tbd_rri_gen [UUT]
|
21 |
|
|
--
|
22 |
|
|
-- To test: rri_core
|
23 |
|
|
-- rri_serport
|
24 |
|
|
--
|
25 |
|
|
-- Target Devices: generic
|
26 |
|
|
-- Tool versions: xst 8.1, 8.2, 9.1, 9.2, 11.4; ghdl 0.18-0.26
|
27 |
|
|
-- Revision History:
|
28 |
|
|
-- Date Rev Version Comment
|
29 |
|
|
-- 2010-06-06 302 2.5 use sop/eop framing instead of soc+chaining
|
30 |
|
|
-- 2010-06-03 299 2.2.2 new init encoding (WE=0/1 int/ext);use sv_ prefix
|
31 |
|
|
-- for shared variables
|
32 |
|
|
-- 2010-05-02 287 2.2.1 ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
|
33 |
|
|
-- drop RP_IINT signal from interfaces
|
34 |
|
|
-- 2010-04-03 274 2.2 add CE_USEC in tbd_rri_gen interface
|
35 |
|
|
-- 2009-03-14 197 2.1 remove records in interface to allow _ssim usage
|
36 |
|
|
-- 2008-08-24 162 2.0 with new rb_mreq/rb_sres interface
|
37 |
|
|
-- 2008-03-24 129 1.1.2 CLK_CYCLE now 31 bits
|
38 |
|
|
-- 2008-01-20 112 1.1.1 rename clkgen->clkdivce
|
39 |
|
|
-- 2007-11-24 98 1.1 add RP_IINT support, add checkmiss_tx to test
|
40 |
|
|
-- for missing responses
|
41 |
|
|
-- 2007-10-26 92 1.0.2 add DONE timestamp at end of execution
|
42 |
|
|
-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
|
43 |
|
|
-- 2007-09-09 81 1.0 Initial version
|
44 |
|
|
------------------------------------------------------------------------------
|
45 |
|
|
|
46 |
|
|
library ieee;
|
47 |
|
|
use ieee.std_logic_1164.all;
|
48 |
|
|
use ieee.std_logic_arith.all;
|
49 |
|
|
use ieee.std_logic_textio.all;
|
50 |
|
|
use std.textio.all;
|
51 |
|
|
|
52 |
|
|
use work.slvtypes.all;
|
53 |
|
|
use work.genlib.all;
|
54 |
|
|
use work.comlib.all;
|
55 |
|
|
use work.rrilib.all;
|
56 |
|
|
use work.simlib.all;
|
57 |
|
|
|
58 |
|
|
entity tb_rri is
|
59 |
|
|
end tb_rri;
|
60 |
|
|
|
61 |
|
|
architecture sim of tb_rri is
|
62 |
|
|
|
63 |
|
|
signal CLK : slbit := '0';
|
64 |
|
|
signal CE_USEC : slbit := '0';
|
65 |
|
|
signal CE_MSEC : slbit := '0';
|
66 |
|
|
signal RESET : slbit := '0';
|
67 |
|
|
signal CP_DI : slv9 := (others=>'0');
|
68 |
|
|
signal CP_ENA : slbit := '0';
|
69 |
|
|
signal CP_BUSY : slbit := '0';
|
70 |
|
|
signal CP_DO : slv9 := (others=>'0');
|
71 |
|
|
signal CP_VAL : slbit := '0';
|
72 |
|
|
signal CP_HOLD : slbit := '0';
|
73 |
|
|
signal RB_MREQ_req : slbit := '0';
|
74 |
|
|
signal RB_MREQ_we : slbit := '0';
|
75 |
|
|
signal RB_MREQ_initt: slbit := '0';
|
76 |
|
|
signal RB_MREQ_addr : slv8 := (others=>'0');
|
77 |
|
|
signal RB_MREQ_din : slv16 := (others=>'0');
|
78 |
|
|
signal RB_SRES_ack : slbit := '0';
|
79 |
|
|
signal RB_SRES_busy : slbit := '0';
|
80 |
|
|
signal RB_SRES_err : slbit := '0';
|
81 |
|
|
signal RB_SRES_dout : slv16 := (others=>'0');
|
82 |
|
|
signal RB_LAM : slv16 := (others=>'0');
|
83 |
|
|
signal RB_STAT : slv3 := (others=>'0');
|
84 |
|
|
signal TXRXACT : slbit := '0';
|
85 |
|
|
|
86 |
|
|
signal CLK_STOP : slbit := '0';
|
87 |
|
|
signal CLK_CYCLE : slv31 := (others=>'0');
|
88 |
|
|
|
89 |
|
|
constant slv9_zero : slv9 := (others=>'0');
|
90 |
|
|
constant slv16_zero : slv16 := (others=>'0');
|
91 |
|
|
|
92 |
|
|
type slv9_array_type is array (0 to 255) of slv9;
|
93 |
|
|
type slv16_array_type is array (0 to 255) of slv16;
|
94 |
|
|
|
95 |
|
|
shared variable sv_rxlist : slv9_array_type := (others=>slv9_zero);
|
96 |
|
|
shared variable sv_nrxlist : natural := 0;
|
97 |
|
|
shared variable sv_rxind : natural := 0;
|
98 |
|
|
|
99 |
|
|
constant clock_period : time := 20 ns;
|
100 |
|
|
constant clock_offset : time := 200 ns;
|
101 |
|
|
constant setup_time : time := 5 ns;
|
102 |
|
|
constant c2out_time : time := 10 ns;
|
103 |
|
|
|
104 |
|
|
component tbd_rri_gen is -- rri, generic tb design interface
|
105 |
|
|
port (
|
106 |
|
|
CLK : in slbit; -- clock
|
107 |
|
|
CE_INT : in slbit; -- rri ito time unit clock enable
|
108 |
|
|
CE_USEC : in slbit; -- 1 usec clock enable
|
109 |
|
|
RESET : in slbit; -- reset
|
110 |
|
|
CP_DI : in slv9; -- comm port: data in
|
111 |
|
|
CP_ENA : in slbit; -- comm port: data enable
|
112 |
|
|
CP_BUSY : out slbit; -- comm port: data busy
|
113 |
|
|
CP_DO : out slv9; -- comm port: data out
|
114 |
|
|
CP_VAL : out slbit; -- comm port: data valid
|
115 |
|
|
CP_HOLD : in slbit; -- comm port: data hold
|
116 |
|
|
RB_MREQ_req : out slbit; -- rbus: request - req
|
117 |
|
|
RB_MREQ_we : out slbit; -- rbus: request - we
|
118 |
|
|
RB_MREQ_initt: out slbit; -- rbus: request - init; avoid name coll
|
119 |
|
|
RB_MREQ_addr : out slv8; -- rbus: request - addr
|
120 |
|
|
RB_MREQ_din : out slv16; -- rbus: request - din
|
121 |
|
|
RB_SRES_ack : in slbit; -- rbus: response - ack
|
122 |
|
|
RB_SRES_busy : in slbit; -- rbus: response - busy
|
123 |
|
|
RB_SRES_err : in slbit; -- rbus: response - err
|
124 |
|
|
RB_SRES_dout : in slv16; -- rbus: response - dout
|
125 |
|
|
RB_LAM : in slv16; -- rbus: look at me
|
126 |
|
|
RB_STAT : in slv3; -- rbus: status flags
|
127 |
|
|
TXRXACT : out slbit -- txrx active flag
|
128 |
|
|
);
|
129 |
|
|
end component;
|
130 |
|
|
|
131 |
|
|
begin
|
132 |
|
|
|
133 |
|
|
SYSCLK : simclk
|
134 |
|
|
generic map (
|
135 |
|
|
PERIOD => clock_period,
|
136 |
|
|
OFFSET => clock_offset)
|
137 |
|
|
port map (
|
138 |
|
|
CLK => CLK,
|
139 |
|
|
CLK_CYCLE => CLK_CYCLE,
|
140 |
|
|
CLK_STOP => CLK_STOP
|
141 |
|
|
);
|
142 |
|
|
|
143 |
|
|
CLKDIV : clkdivce
|
144 |
|
|
generic map (
|
145 |
|
|
CDUWIDTH => 6,
|
146 |
|
|
USECDIV => 4,
|
147 |
|
|
MSECDIV => 5
|
148 |
|
|
)
|
149 |
|
|
port map (
|
150 |
|
|
CLK => CLK,
|
151 |
|
|
CE_USEC => CE_USEC,
|
152 |
|
|
CE_MSEC => CE_MSEC
|
153 |
|
|
);
|
154 |
|
|
|
155 |
|
|
UUT : tbd_rri_gen
|
156 |
|
|
port map (
|
157 |
|
|
CLK => CLK,
|
158 |
|
|
CE_INT => CE_MSEC,
|
159 |
|
|
CE_USEC => CE_USEC,
|
160 |
|
|
RESET => RESET,
|
161 |
|
|
CP_DI => CP_DI,
|
162 |
|
|
CP_ENA => CP_ENA,
|
163 |
|
|
CP_BUSY => CP_BUSY,
|
164 |
|
|
CP_DO => CP_DO,
|
165 |
|
|
CP_VAL => CP_VAL,
|
166 |
|
|
CP_HOLD => CP_HOLD,
|
167 |
|
|
RB_MREQ_req => RB_MREQ_req,
|
168 |
|
|
RB_MREQ_we => RB_MREQ_we,
|
169 |
|
|
RB_MREQ_initt=> RB_MREQ_initt,
|
170 |
|
|
RB_MREQ_addr => RB_MREQ_addr,
|
171 |
|
|
RB_MREQ_din => RB_MREQ_din,
|
172 |
|
|
RB_SRES_ack => RB_SRES_ack,
|
173 |
|
|
RB_SRES_busy => RB_SRES_busy,
|
174 |
|
|
RB_SRES_err => RB_SRES_err,
|
175 |
|
|
RB_SRES_dout => RB_SRES_dout,
|
176 |
|
|
RB_LAM => RB_LAM,
|
177 |
|
|
RB_STAT => RB_STAT,
|
178 |
|
|
TXRXACT => TXRXACT
|
179 |
|
|
);
|
180 |
|
|
|
181 |
|
|
|
182 |
|
|
proc_stim: process
|
183 |
|
|
file fstim : text open read_mode is "tb_rri_stim";
|
184 |
|
|
variable iline : line;
|
185 |
|
|
variable oline : line;
|
186 |
|
|
variable icmd : slv8 := (others=>'0');
|
187 |
|
|
variable iaddr : slv8 := (others=>'0');
|
188 |
|
|
variable icnt : slv8 := (others=>'0');
|
189 |
|
|
variable istat : slv3 := (others=>'0');
|
190 |
|
|
variable iattn : slv8 := (others=>'0');
|
191 |
|
|
variable idata : slv16 := (others=>'0');
|
192 |
|
|
variable ioob : slv9 := (others=>'0');
|
193 |
|
|
variable ok : boolean;
|
194 |
|
|
variable dname : string(1 to 6) := (others=>' ');
|
195 |
|
|
variable idelta : integer := 0;
|
196 |
|
|
variable iowait : integer := 0;
|
197 |
|
|
variable txcrc,rxcrc : slv8 := (others=>'0');
|
198 |
|
|
variable txlist : slv9_array_type := (others=>slv9_zero);
|
199 |
|
|
variable ntxlist : natural := 0;
|
200 |
|
|
|
201 |
|
|
procedure do_tx8 (data : inout slv8) is
|
202 |
|
|
begin
|
203 |
|
|
txlist(ntxlist) := '0' & data;
|
204 |
|
|
ntxlist := ntxlist + 1;
|
205 |
|
|
crc8_update_tbl(txcrc, data);
|
206 |
|
|
end procedure do_tx8;
|
207 |
|
|
|
208 |
|
|
procedure do_tx16 (data : inout slv16) is
|
209 |
|
|
begin
|
210 |
|
|
do_tx8(data( 7 downto 0));
|
211 |
|
|
do_tx8(data(15 downto 8));
|
212 |
|
|
end procedure do_tx16;
|
213 |
|
|
|
214 |
|
|
procedure do_rx8 (data : inout slv8) is
|
215 |
|
|
begin
|
216 |
|
|
sv_rxlist(sv_nrxlist) := '0' & data;
|
217 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
218 |
|
|
crc8_update_tbl(rxcrc, data);
|
219 |
|
|
end procedure do_rx8;
|
220 |
|
|
|
221 |
|
|
procedure do_rx16 (data : inout slv16) is
|
222 |
|
|
begin
|
223 |
|
|
do_rx8(data( 7 downto 0));
|
224 |
|
|
do_rx8(data(15 downto 8));
|
225 |
|
|
end procedure do_rx16;
|
226 |
|
|
|
227 |
|
|
procedure checkmiss_rx is
|
228 |
|
|
begin
|
229 |
|
|
if sv_rxind < sv_nrxlist then
|
230 |
|
|
for i in sv_rxind to sv_nrxlist-1 loop
|
231 |
|
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
232 |
|
|
write(oline, string'(" FAIL MISSING DATA="));
|
233 |
|
|
write(oline, sv_rxlist(i)(8));
|
234 |
|
|
write(oline, string'(" "));
|
235 |
|
|
write(oline, sv_rxlist(i)(7 downto 0));
|
236 |
|
|
writeline(output, oline);
|
237 |
|
|
end loop;
|
238 |
|
|
|
239 |
|
|
end if;
|
240 |
|
|
end procedure checkmiss_rx;
|
241 |
|
|
|
242 |
|
|
begin
|
243 |
|
|
|
244 |
|
|
wait for clock_offset - setup_time;
|
245 |
|
|
|
246 |
|
|
file_loop: while not endfile(fstim) loop
|
247 |
|
|
|
248 |
|
|
readline (fstim, iline);
|
249 |
|
|
|
250 |
|
|
readcomment(iline, ok);
|
251 |
|
|
next file_loop when ok;
|
252 |
|
|
|
253 |
|
|
readcommand(iline, dname, ok);
|
254 |
|
|
if ok then
|
255 |
|
|
case dname is
|
256 |
|
|
when ".reset" => -- .reset
|
257 |
|
|
write(oline, string'(".reset"));
|
258 |
|
|
writeline(output, oline);
|
259 |
|
|
RESET <= '1';
|
260 |
|
|
wait for clock_period;
|
261 |
|
|
RESET <= '0';
|
262 |
|
|
wait for 9*clock_period;
|
263 |
|
|
|
264 |
|
|
when ".wait " => -- .wait
|
265 |
|
|
read_ea(iline, idelta);
|
266 |
|
|
wait for idelta*clock_period;
|
267 |
|
|
|
268 |
|
|
when ".iowt " => -- .iowt
|
269 |
|
|
read_ea(iline, iowait);
|
270 |
|
|
idelta := iowait;
|
271 |
|
|
while idelta > 0 loop -- until time has expired
|
272 |
|
|
if TXRXACT = '1' then -- if any io activity
|
273 |
|
|
idelta := iowait; -- restart timer
|
274 |
|
|
else
|
275 |
|
|
idelta := idelta - 1; -- otherwise count down time
|
276 |
|
|
end if;
|
277 |
|
|
wait for clock_period;
|
278 |
|
|
end loop;
|
279 |
|
|
|
280 |
|
|
when ".stat " => -- .stat
|
281 |
|
|
read_ea(iline, istat);
|
282 |
|
|
RB_STAT <= istat; -- set ext. status lines
|
283 |
|
|
wait for clock_period; -- ensure some setling
|
284 |
|
|
|
285 |
|
|
when ".attn " => -- .attn
|
286 |
|
|
read_ea(iline, iattn);
|
287 |
|
|
RB_LAM(7 downto 0) <= iattn; -- pulse lsb attn lines
|
288 |
|
|
wait for clock_period; -- for 1 clock
|
289 |
|
|
RB_LAM(7 downto 0) <= (others=>'0');
|
290 |
|
|
|
291 |
|
|
when ".txsop" => -- .txsop send sop
|
292 |
|
|
txlist(0) := c_rri_dat_sop;
|
293 |
|
|
ntxlist := 1;
|
294 |
|
|
txcrc := (others=>'0');
|
295 |
|
|
when ".txeop" => -- .txeop send eop
|
296 |
|
|
txlist(0) := c_rri_dat_eop;
|
297 |
|
|
ntxlist := 1;
|
298 |
|
|
txcrc := (others=>'0');
|
299 |
|
|
when ".txnak" => -- .txnak send nak
|
300 |
|
|
txlist(0) := c_rri_dat_nak;
|
301 |
|
|
ntxlist := 1;
|
302 |
|
|
txcrc := (others=>'0');
|
303 |
|
|
when ".tx8 " => -- .tx8 send 8 bit value
|
304 |
|
|
read_ea(iline, iaddr);
|
305 |
|
|
ntxlist := 0;
|
306 |
|
|
do_tx8(iaddr);
|
307 |
|
|
when ".tx16 " => -- .tx16 send 16 bit value
|
308 |
|
|
read_ea(iline, idata);
|
309 |
|
|
ntxlist := 0;
|
310 |
|
|
do_tx16(idata);
|
311 |
|
|
when ".txcrc" => -- .txcrc send crc
|
312 |
|
|
txlist(0) := '0' & txcrc;
|
313 |
|
|
ntxlist := 1;
|
314 |
|
|
|
315 |
|
|
when ".txc " => -- .txc send: cmd crc
|
316 |
|
|
read_ea(iline, icmd);
|
317 |
|
|
ntxlist := 0;
|
318 |
|
|
do_tx8(icmd);
|
319 |
|
|
txlist(ntxlist) := '0' & txcrc;
|
320 |
|
|
ntxlist := ntxlist + 1;
|
321 |
|
|
|
322 |
|
|
when ".txca " => -- .txc send: cmd addr crc
|
323 |
|
|
read_ea(iline, icmd);
|
324 |
|
|
read_ea(iline, iaddr);
|
325 |
|
|
ntxlist := 0;
|
326 |
|
|
do_tx8(icmd);
|
327 |
|
|
do_tx8(iaddr);
|
328 |
|
|
txlist(ntxlist) := '0' & txcrc;
|
329 |
|
|
ntxlist := ntxlist + 1;
|
330 |
|
|
|
331 |
|
|
when ".txcad" => -- .txc send: cmd addr data crc
|
332 |
|
|
read_ea(iline, icmd);
|
333 |
|
|
read_ea(iline, iaddr);
|
334 |
|
|
read_ea(iline, idata);
|
335 |
|
|
ntxlist := 0;
|
336 |
|
|
do_tx8(icmd);
|
337 |
|
|
do_tx8(iaddr);
|
338 |
|
|
do_tx16(idata);
|
339 |
|
|
txlist(ntxlist) := '0' & txcrc;
|
340 |
|
|
ntxlist := ntxlist + 1;
|
341 |
|
|
|
342 |
|
|
when ".txcac" => -- .txc send: cmd addr cnt crc
|
343 |
|
|
read_ea(iline, icmd);
|
344 |
|
|
read_ea(iline, iaddr);
|
345 |
|
|
read_ea(iline, icnt);
|
346 |
|
|
ntxlist := 0;
|
347 |
|
|
do_tx8(icmd);
|
348 |
|
|
do_tx8(iaddr);
|
349 |
|
|
do_tx8(icnt);
|
350 |
|
|
txlist(ntxlist) := '0' & txcrc;
|
351 |
|
|
ntxlist := ntxlist + 1;
|
352 |
|
|
|
353 |
|
|
when ".rxsop" => -- .rxsop expect sop
|
354 |
|
|
checkmiss_rx;
|
355 |
|
|
sv_rxlist(0) := c_rri_dat_sop;
|
356 |
|
|
sv_nrxlist := 1;
|
357 |
|
|
sv_rxind := 0;
|
358 |
|
|
rxcrc := (others=>'0');
|
359 |
|
|
when ".rxeop" => -- .rxeop expect eop
|
360 |
|
|
sv_rxlist(sv_nrxlist) := c_rri_dat_eop;
|
361 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
362 |
|
|
when ".rxnak" => -- .rxnak expect nak
|
363 |
|
|
sv_rxlist(sv_nrxlist) := c_rri_dat_nak;
|
364 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
365 |
|
|
when ".rx8 " => -- .rx8 expect 8 bit value
|
366 |
|
|
read_ea(iline, iaddr);
|
367 |
|
|
do_rx8(iaddr);
|
368 |
|
|
when ".rx16 " => -- .rx16 expect 16 bit value
|
369 |
|
|
read_ea(iline, idata);
|
370 |
|
|
do_rx16(idata);
|
371 |
|
|
when ".rxcrc" => -- .rxcrc expect crc
|
372 |
|
|
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
|
373 |
|
|
sv_nrxlist := sv_nrxlist+1;
|
374 |
|
|
|
375 |
|
|
when ".rxcs " => -- .rxcs expect: cmd stat crc
|
376 |
|
|
read_ea(iline, icmd);
|
377 |
|
|
read_ea(iline, iaddr);
|
378 |
|
|
do_rx8(icmd);
|
379 |
|
|
do_rx8(iaddr);
|
380 |
|
|
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
|
381 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
382 |
|
|
|
383 |
|
|
when ".rxcds" => -- .rxcsd expect: cmd data stat crc
|
384 |
|
|
read_ea(iline, icmd);
|
385 |
|
|
read_ea(iline, idata);
|
386 |
|
|
read_ea(iline, iaddr);
|
387 |
|
|
do_rx8(icmd);
|
388 |
|
|
do_rx16(idata);
|
389 |
|
|
do_rx8(iaddr);
|
390 |
|
|
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
|
391 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
392 |
|
|
|
393 |
|
|
when ".rxccd" => -- .rxccd expect: cmd ccmd dat stat crc
|
394 |
|
|
read_ea(iline, icmd);
|
395 |
|
|
read_ea(iline, icnt);
|
396 |
|
|
read_ea(iline, idata);
|
397 |
|
|
read_ea(iline, iaddr);
|
398 |
|
|
do_rx8(icmd);
|
399 |
|
|
do_rx8(icnt);
|
400 |
|
|
do_rx16(idata);
|
401 |
|
|
do_rx8(iaddr);
|
402 |
|
|
sv_rxlist(sv_nrxlist) := '0' & rxcrc;
|
403 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
404 |
|
|
|
405 |
|
|
when ".rxoob" => -- .rxoob expect: out-of-band symbol
|
406 |
|
|
read_ea(iline, ioob);
|
407 |
|
|
sv_rxlist(sv_nrxlist) := ioob;
|
408 |
|
|
sv_nrxlist := sv_nrxlist + 1;
|
409 |
|
|
|
410 |
|
|
when others => -- bad directive
|
411 |
|
|
write(oline, string'("?? unknown directive: "));
|
412 |
|
|
write(oline, dname);
|
413 |
|
|
writeline(output, oline);
|
414 |
|
|
report "aborting" severity failure;
|
415 |
|
|
end case;
|
416 |
|
|
|
417 |
|
|
else
|
418 |
|
|
read_ea(iline, txlist(0));
|
419 |
|
|
ntxlist := 1;
|
420 |
|
|
|
421 |
|
|
end if;
|
422 |
|
|
|
423 |
|
|
next file_loop when ntxlist=0;
|
424 |
|
|
|
425 |
|
|
for i in 0 to ntxlist-1 loop
|
426 |
|
|
|
427 |
|
|
CP_DI <= txlist(i);
|
428 |
|
|
CP_ENA <= '1';
|
429 |
|
|
|
430 |
|
|
writetimestamp(oline, CLK_CYCLE, ": stim ");
|
431 |
|
|
write(oline, txlist(i)(8), right, 3);
|
432 |
|
|
write(oline, txlist(i)(7 downto 0), right, 9);
|
433 |
|
|
if txlist(i)(8) = '1' then
|
434 |
|
|
case txlist(i) is
|
435 |
|
|
when c_rri_dat_idle =>
|
436 |
|
|
write(oline, string'(" (idle)"));
|
437 |
|
|
when c_rri_dat_sop =>
|
438 |
|
|
write(oline, string'(" (sop) "));
|
439 |
|
|
when c_rri_dat_eop =>
|
440 |
|
|
write(oline, string'(" (eop) "));
|
441 |
|
|
when c_rri_dat_nak =>
|
442 |
|
|
write(oline, string'(" (nak) "));
|
443 |
|
|
when c_rri_dat_attn =>
|
444 |
|
|
write(oline, string'(" (attn)"));
|
445 |
|
|
when others =>
|
446 |
|
|
write(oline, string'(" (????)"));
|
447 |
|
|
end case;
|
448 |
|
|
end if;
|
449 |
|
|
writeline(output, oline);
|
450 |
|
|
|
451 |
|
|
wait for clock_period;
|
452 |
|
|
while CP_BUSY = '1' loop
|
453 |
|
|
wait for clock_period;
|
454 |
|
|
end loop;
|
455 |
|
|
CP_ENA <= '0';
|
456 |
|
|
|
457 |
|
|
end loop; -- i
|
458 |
|
|
|
459 |
|
|
ntxlist := 0;
|
460 |
|
|
|
461 |
|
|
end loop; -- file fstim
|
462 |
|
|
|
463 |
|
|
wait for 50*clock_period;
|
464 |
|
|
|
465 |
|
|
checkmiss_rx;
|
466 |
|
|
writetimestamp(oline, CLK_CYCLE, ": DONE ");
|
467 |
|
|
writeline(output, oline);
|
468 |
|
|
|
469 |
|
|
CLK_STOP <= '1';
|
470 |
|
|
|
471 |
|
|
wait; -- suspend proc_stim forever
|
472 |
|
|
-- clock is stopped, sim will end
|
473 |
|
|
|
474 |
|
|
end process proc_stim;
|
475 |
|
|
|
476 |
|
|
|
477 |
|
|
proc_moni: process
|
478 |
|
|
variable oline : line;
|
479 |
|
|
begin
|
480 |
|
|
|
481 |
|
|
loop
|
482 |
|
|
wait until CLK'event and CLK='1';
|
483 |
|
|
wait for c2out_time;
|
484 |
|
|
|
485 |
|
|
if CP_VAL = '1' then
|
486 |
|
|
writetimestamp(oline, CLK_CYCLE, ": moni ");
|
487 |
|
|
write(oline, CP_DO(8), right, 3);
|
488 |
|
|
write(oline, CP_DO(7 downto 0), right, 9);
|
489 |
|
|
if CP_DO(8) = '1' then
|
490 |
|
|
case CP_DO is
|
491 |
|
|
when c_rri_dat_idle =>
|
492 |
|
|
write(oline, string'(" (idle)"));
|
493 |
|
|
when c_rri_dat_sop =>
|
494 |
|
|
write(oline, string'(" (sop) "));
|
495 |
|
|
when c_rri_dat_eop =>
|
496 |
|
|
write(oline, string'(" (eop) "));
|
497 |
|
|
when c_rri_dat_nak =>
|
498 |
|
|
write(oline, string'(" (nak) "));
|
499 |
|
|
when c_rri_dat_attn =>
|
500 |
|
|
write(oline, string'(" (attn)"));
|
501 |
|
|
when others =>
|
502 |
|
|
write(oline, string'(" (????)"));
|
503 |
|
|
end case;
|
504 |
|
|
end if;
|
505 |
|
|
if sv_nrxlist > 0 then
|
506 |
|
|
write(oline, string'(" CHECK"));
|
507 |
|
|
if sv_rxind < sv_nrxlist then
|
508 |
|
|
if CP_DO = sv_rxlist(sv_rxind) then
|
509 |
|
|
write(oline, string'(" OK"));
|
510 |
|
|
else
|
511 |
|
|
write(oline, string'(" FAIL, exp="));
|
512 |
|
|
write(oline, sv_rxlist(sv_rxind)(8), right, 2);
|
513 |
|
|
write(oline, sv_rxlist(sv_rxind)(7 downto 0), right, 9);
|
514 |
|
|
end if;
|
515 |
|
|
sv_rxind := sv_rxind + 1;
|
516 |
|
|
else
|
517 |
|
|
write(oline, string'(" FAIL, UNEXPECTED"));
|
518 |
|
|
end if;
|
519 |
|
|
end if;
|
520 |
|
|
writeline(output, oline);
|
521 |
|
|
end if;
|
522 |
|
|
|
523 |
|
|
end loop;
|
524 |
|
|
|
525 |
|
|
end process proc_moni;
|
526 |
|
|
|
527 |
|
|
|
528 |
|
|
-- simulated target:
|
529 |
|
|
-- 00000000 ... 00111111: 64 registers, no wait states
|
530 |
|
|
-- 00010000 : (16) pointer register for mem 0
|
531 |
|
|
-- 00010001 : (17) pointer register for mem 1
|
532 |
|
|
-- 00010010 : (18) counter for init's
|
533 |
|
|
-- 01000000 ... 01111111: 64 registers, addr(5 downto 0)+1 wait states
|
534 |
|
|
-- 10000000 : 256 word memory, addressed by reg(00010000)
|
535 |
|
|
-- 10000001 : 256 word memory, addressed by reg(00010001)
|
536 |
|
|
-- 10000010 : ping RB_LAM(15 downto 8) on WE access
|
537 |
|
|
-- 11000000 : signal err, write noop, read 10101010
|
538 |
|
|
-- others : no ack
|
539 |
|
|
--
|
540 |
|
|
|
541 |
|
|
proc_targ: process
|
542 |
|
|
variable reg0 : slv16_array_type := (others=>slv16_zero);
|
543 |
|
|
variable reg1 : slv16_array_type := (others=>slv16_zero);
|
544 |
|
|
variable mem0 : slv16_array_type := (others=>slv16_zero);
|
545 |
|
|
variable mem1 : slv16_array_type := (others=>slv16_zero);
|
546 |
|
|
variable iack : slbit := '0';
|
547 |
|
|
variable ierr : slbit := '0';
|
548 |
|
|
variable nhold : integer := 0;
|
549 |
|
|
variable addr : slv8 := (others=>'0');
|
550 |
|
|
variable idout : slv16 := (others=>'0');
|
551 |
|
|
variable ind : integer := 0;
|
552 |
|
|
variable oline : line;
|
553 |
|
|
|
554 |
|
|
constant c2out_setup : time := clock_period-c2out_time-setup_time;
|
555 |
|
|
|
556 |
|
|
type acc_type is (acc_reg0, acc_reg1, acc_mem0, acc_mem1, acc_lam,
|
557 |
|
|
acc_err, acc_bad);
|
558 |
|
|
variable acc : acc_type := acc_bad;
|
559 |
|
|
|
560 |
|
|
procedure write_data (pref : in string;
|
561 |
|
|
data : in slv16;
|
562 |
|
|
iack : in slbit;
|
563 |
|
|
ierr : in slbit;
|
564 |
|
|
nhold : in integer) is
|
565 |
|
|
variable oline : line;
|
566 |
|
|
begin
|
567 |
|
|
writetimestamp(oline, CLK_CYCLE, pref);
|
568 |
|
|
write(oline, RB_MREQ_addr, right, 10);
|
569 |
|
|
write(oline, data, right, 18);
|
570 |
|
|
if nhold > 0 then
|
571 |
|
|
write(oline, string'(" nhold="));
|
572 |
|
|
write(oline, nhold, right, 2);
|
573 |
|
|
end if;
|
574 |
|
|
if iack = '0' then
|
575 |
|
|
write(oline, string'(" ACK=0"));
|
576 |
|
|
end if;
|
577 |
|
|
if ierr = '1' then
|
578 |
|
|
write(oline, string'(" ERR=1"));
|
579 |
|
|
end if;
|
580 |
|
|
writeline(output, oline);
|
581 |
|
|
end procedure write_data;
|
582 |
|
|
|
583 |
|
|
begin
|
584 |
|
|
|
585 |
|
|
-- assert c2out_setup>0 report "assert(x>0)" severity FAILURE;
|
586 |
|
|
|
587 |
|
|
wait until CLK'event and CLK='1';
|
588 |
|
|
wait for c2out_time;
|
589 |
|
|
|
590 |
|
|
RB_SRES_ack <= '0';
|
591 |
|
|
RB_SRES_busy <= '0';
|
592 |
|
|
RB_SRES_err <= '0';
|
593 |
|
|
RB_SRES_dout <= (others=>'1');
|
594 |
|
|
|
595 |
|
|
addr := RB_MREQ_addr;
|
596 |
|
|
idout := (others=>'0');
|
597 |
|
|
nhold := 0;
|
598 |
|
|
|
599 |
|
|
acc := acc_bad;
|
600 |
|
|
if unsigned(addr) <= 2#00111111# then
|
601 |
|
|
acc := acc_reg0;
|
602 |
|
|
elsif unsigned(addr) <= 2#01111111# then
|
603 |
|
|
acc := acc_reg1;
|
604 |
|
|
nhold := conv_integer(unsigned(addr and "00111111")) + 1;
|
605 |
|
|
elsif unsigned(addr) = 2#10000000# then
|
606 |
|
|
acc := acc_mem0;
|
607 |
|
|
elsif unsigned(addr) = 2#10000001# then
|
608 |
|
|
acc := acc_mem1;
|
609 |
|
|
elsif unsigned(addr) = 2#10000010# then
|
610 |
|
|
acc := acc_lam;
|
611 |
|
|
elsif unsigned(addr) = 2#11000000# then
|
612 |
|
|
acc := acc_err;
|
613 |
|
|
end if;
|
614 |
|
|
|
615 |
|
|
iack := '1';
|
616 |
|
|
ierr := '0';
|
617 |
|
|
|
618 |
|
|
if acc = acc_bad then -- if bad address
|
619 |
|
|
iack := '0'; -- don't acknowledge
|
620 |
|
|
end if;
|
621 |
|
|
|
622 |
|
|
RB_SRES_ack <= iack;
|
623 |
|
|
|
624 |
|
|
RB_LAM(15 downto 8) <= (others=>'0');
|
625 |
|
|
|
626 |
|
|
if RB_MREQ_req = '1' then
|
627 |
|
|
|
628 |
|
|
-- handle WE transactions
|
629 |
|
|
if RB_MREQ_we ='1' then
|
630 |
|
|
case acc is
|
631 |
|
|
when acc_reg0 =>
|
632 |
|
|
reg0(conv_integer(unsigned(addr))) := RB_MREQ_din;
|
633 |
|
|
when acc_reg1 =>
|
634 |
|
|
reg1(conv_integer(unsigned(addr))) := RB_MREQ_din;
|
635 |
|
|
when acc_mem0 =>
|
636 |
|
|
ind := conv_integer(unsigned(reg0(16) and X"00ff"));
|
637 |
|
|
mem0(ind) := RB_MREQ_din;
|
638 |
|
|
reg0(16) := unsigned(reg0(16)) + 1;
|
639 |
|
|
when acc_mem1 =>
|
640 |
|
|
ind := conv_integer(unsigned(reg0(17) and X"00ff"));
|
641 |
|
|
mem1(ind) := RB_MREQ_din;
|
642 |
|
|
reg0(17) := unsigned(reg0(17)) + 1;
|
643 |
|
|
when acc_lam =>
|
644 |
|
|
RB_LAM(15 downto 8) <= RB_MREQ_din(15 downto 8);
|
645 |
|
|
writetimestamp(oline, CLK_CYCLE,
|
646 |
|
|
": targ w ap_lam(15 downto 8) pinged");
|
647 |
|
|
writeline(output, oline);
|
648 |
|
|
when acc_err =>
|
649 |
|
|
ierr := '1';
|
650 |
|
|
when others => null;
|
651 |
|
|
end case;
|
652 |
|
|
|
653 |
|
|
write_data(": targ w ", RB_MREQ_din, iack, ierr, nhold);
|
654 |
|
|
|
655 |
|
|
while nhold>0 and RB_MREQ_req='1' loop
|
656 |
|
|
RB_SRES_busy <= '1';
|
657 |
|
|
wait for clock_period;
|
658 |
|
|
nhold := nhold - 1;
|
659 |
|
|
end loop;
|
660 |
|
|
RB_SRES_ack <= iack;
|
661 |
|
|
RB_SRES_err <= ierr;
|
662 |
|
|
RB_SRES_busy <= '0';
|
663 |
|
|
|
664 |
|
|
-- handle RE transactions
|
665 |
|
|
else
|
666 |
|
|
case acc is
|
667 |
|
|
when acc_reg0 =>
|
668 |
|
|
idout := reg0(conv_integer(unsigned(addr)));
|
669 |
|
|
when acc_reg1 =>
|
670 |
|
|
idout := reg1(conv_integer(unsigned(addr)));
|
671 |
|
|
when acc_mem0 =>
|
672 |
|
|
ind := conv_integer(unsigned(reg0(16) and X"00ff"));
|
673 |
|
|
idout := mem0(ind);
|
674 |
|
|
reg0(16) := unsigned(reg0(16)) + 1;
|
675 |
|
|
when acc_mem1 =>
|
676 |
|
|
ind := conv_integer(unsigned(reg0(17) and X"00ff"));
|
677 |
|
|
idout := mem1(ind);
|
678 |
|
|
reg0(17) := unsigned(reg0(17)) + 1;
|
679 |
|
|
when acc_err =>
|
680 |
|
|
ierr := '1';
|
681 |
|
|
idout := "1010101010101010";
|
682 |
|
|
when acc_bad =>
|
683 |
|
|
idout := "1010101010101010";
|
684 |
|
|
when others => null;
|
685 |
|
|
end case;
|
686 |
|
|
|
687 |
|
|
write_data(": targ r ", idout, iack, ierr, nhold);
|
688 |
|
|
|
689 |
|
|
RB_SRES_dout <= "0101010101010101";
|
690 |
|
|
wait for c2out_setup;
|
691 |
|
|
|
692 |
|
|
while nhold>0 and RB_MREQ_req='1' loop
|
693 |
|
|
RB_SRES_busy <= '1';
|
694 |
|
|
wait for clock_period;
|
695 |
|
|
nhold := nhold - 1;
|
696 |
|
|
end loop;
|
697 |
|
|
RB_SRES_ack <= iack;
|
698 |
|
|
RB_SRES_err <= ierr;
|
699 |
|
|
RB_SRES_busy <= '0';
|
700 |
|
|
|
701 |
|
|
RB_SRES_dout <= idout;
|
702 |
|
|
|
703 |
|
|
end if;
|
704 |
|
|
end if;
|
705 |
|
|
|
706 |
|
|
-- handle INIT transactions (ext and int) (just for monitoring...)
|
707 |
|
|
|
708 |
|
|
if RB_MREQ_initt = '1' then
|
709 |
|
|
if RB_MREQ_we = '1' then -- ext init
|
710 |
|
|
write_data(": targ i ", RB_MREQ_din, '1', '0', 0);
|
711 |
|
|
reg0(18) := unsigned(reg0(18)) + 1;
|
712 |
|
|
else -- int init
|
713 |
|
|
write_data(": iint ", RB_MREQ_din, '1', '0', 0);
|
714 |
|
|
end if;
|
715 |
|
|
end if;
|
716 |
|
|
|
717 |
|
|
end process proc_targ;
|
718 |
|
|
|
719 |
|
|
|
720 |
|
|
end sim;
|