w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
rbd_tester.vhd
Go to the documentation of this file.
1-- $Id: rbd_tester.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2010-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: rbd_tester - syn
7-- Description: rbus dev: rbus tester
8--
9-- Dependencies: memlib/fifo_simple_dram
10--
11-- Test bench: rlink/tb/tb_rlink (used as test target)
12--
13-- Target Devices: generic
14-- Tool versions: xst 12.1-14.7; viv 2014.4-2019.1; ghdl 0.29-0.35
15--
16-- Synthesized (xst):
17-- Date Rev ise Target flop lutl lutm slic t peri
18-- 2014-08-31 590 14.7 131013 xc6slx16-2 74 162 16 73 s 5.8 ver 4.1
19-- 2010-12-12 344 12.1 M53d xc3s1000-4 78 204 32 133 s 8.0
20-- 2010-12-04 343 12.1 M53d xc3s1000-4 75 214 32 136 s 9.3
21--
22-- Revision History:
23-- Date Rev Version Comment
24-- 2019-06-02 1159 4.2.1 use rbaddr_ constants
25-- 2019-02-09 1109 4.2 use fifo_simple_dram (instead of _1c_dram_raw)
26-- 2014-09-05 591 4.1 use new iface with 8 regs
27-- 2014-08-30 589 4.0 use new rlink v4 iface and 4 bit STAT
28-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit
29-- 2011-11-19 427 1.0.4 now numeric_std clean
30-- 2010-12-31 352 1.0.3 simplify irb_ack logic
31-- 2010-12-29 351 1.0.2 default addr 111101xx->111100xx
32-- 2010-12-12 344 1.0.1 send 0101.. on busy or err; fix init and busy logic
33-- 2010-12-04 343 1.0 Initial version
34------------------------------------------------------------------------------
35--
36-- rbus registers:
37--
38-- Addr Bits Name r/w/f Function
39-- 000 cntl r/w/- Control register
40-- 15 wchk r/w/- write check seen (cleared on data write)
41-- 09:00 nbusy r/w/- busy cycles (for data,dinc,fifo,lnak)
42-- 001 03:00 stat r/w/- status send to RB_STAT
43-- 010 attn -/w/f Attn register: ping RB_LAM lines
44-- 011 09:00 ncyc r/-/- return cycle length of last access
45-- 100 data r/w/- Data register (plain read/write)
46-- 101 dinc r/w/- Data register (autoinc and write check)
47-- 110 fifo r/w/- Fifo interface register
48-- 111 lnak r/w/- delayed ack deassert
49--
50
51library ieee;
52use ieee.std_logic_1164.all;
53use ieee.numeric_std.all;
54
55use work.slvtypes.all;
56use work.memlib.all;
57use work.rblib.all;
58use work.rbdlib.all;
59
60entity rbd_tester is -- rbus dev: rbus tester
61 -- complete rrirp_aif interface
62 generic (
63 RB_ADDR : slv16 := rbaddr_tester);
64 port (
65 CLK : in slbit; -- clock
66 RESET : in slbit; -- reset
67 RB_MREQ : in rb_mreq_type; -- rbus: request
68 RB_SRES : out rb_sres_type; -- rbus: response
69 RB_LAM : out slv16; -- rbus: look at me
70 RB_STAT : out slv4 -- rbus: status flags
71 );
72end entity rbd_tester;
73
74
75architecture syn of rbd_tester is
76
77 constant awidth : positive := 4; -- fifo address width
78
79 constant rbaddr_cntl : slv3 := "000"; -- cntl address offset
80 constant rbaddr_stat : slv3 := "001"; -- stat address offset
81 constant rbaddr_attn : slv3 := "010"; -- attn address offset
82 constant rbaddr_ncyc : slv3 := "011"; -- ncyc address offset
83 constant rbaddr_data : slv3 := "100"; -- data address offset
84 constant rbaddr_dinc : slv3 := "101"; -- dinc address offset
85 constant rbaddr_fifo : slv3 := "110"; -- fifo address offset
86 constant rbaddr_lnak : slv3 := "111"; -- lnak address offset
87
88 constant cntl_rbf_wchk : integer := 15;
89 subtype cntl_rbf_nbusy is integer range 9 downto 0;
90
91 constant init_rbf_cntl : integer := 0;
92 constant init_rbf_data : integer := 1;
93 constant init_rbf_fifo : integer := 2;
94
95 type regs_type is record -- state registers
96 rbsel : slbit; -- rbus select
97 wchk : slbit; -- write check flag
98 stat : slv4; -- stat setting
99 nbusy : slv10; -- nbusy setting
100 data : slv16; -- data register
101 act_1 : slbit; -- rbsel and (re or we) in last cycle
102 ncyc : slv10; -- cycle length of last access
103 cntbusy : slv10; -- busy timer
104 cntcyc : slv10; -- cycle length counter
105 end record regs_type;
106
107 constant regs_init : regs_type := (
108 '0','0', -- rbsel, wchk
109 (others=>'0'), -- stat
110 (others=>'0'), -- nbusy
111 (others=>'0'), -- data
112 '0', -- act_1
113 (others=>'0'), -- ncyc
114 (others=>'0'), -- cntbusy
115 (others=>'0') -- cntcyc
116 );
117
118 constant cntcyc_max : slv(regs_init.cntcyc'range) := (others=>'1');
119
122
123 signal FIFO_RESET : slbit := '0';
124 signal FIFO_CE : slbit := '0';
125 signal FIFO_WE : slbit := '0';
126 signal FIFO_EMPTY : slbit := '0';
127 signal FIFO_FULL : slbit := '0';
128 signal FIFO_SIZE : slv(awidth-1 downto 0) := (others=>'0');
129 signal FIFO_DO : slv16 := (others=>'0');
130
131begin
132
133 FIFO : fifo_simple_dram
134 generic map (
135 AWIDTH => awidth,
136 DWIDTH => 16)
137 port map (
138 CLK => CLK,
139 RESET => FIFO_RESET,
140 CE => FIFO_CE,
141 WE => FIFO_WE,
142 DI => RB_MREQ.din,
143 DO => FIFO_DO,
144 EMPTY => FIFO_EMPTY,
145 FULL => FIFO_FULL,
146 SIZE => FIFO_SIZE
147 );
148
149 proc_regs: process (CLK)
150 begin
151 if rising_edge(CLK) then
152 if RESET = '1' then
153 R_REGS <= regs_init;
154 else
155 R_REGS <= N_REGS;
156 end if;
157 end if;
158 end process proc_regs;
159
160 proc_next : process (R_REGS, RB_MREQ, FIFO_EMPTY, FIFO_FULL, FIFO_DO)
161 variable r : regs_type := regs_init;
162 variable n : regs_type := regs_init;
163 variable irb_ack : slbit := '0';
164 variable irb_busy : slbit := '0';
165 variable irb_err : slbit := '0';
166 variable irb_dout : slv16 := (others=>'0');
167 variable irbena : slbit := '0';
168 variable irblam : slv16 := (others=>'0');
169 variable ififo_ce : slbit := '0';
170 variable ififo_we : slbit := '0';
171 variable ififo_reset : slbit := '0';
172 variable isbusy : slbit := '0';
173 begin
174
175 r := R_REGS;
176 n := R_REGS;
177
178 irb_ack := '0';
179 irb_busy := '0';
180 irb_err := '0';
181 irb_dout := (others=>'0');
182 irblam := (others=>'0');
183
184 irbena := RB_MREQ.re or RB_MREQ.we;
185
186 ififo_ce := '0';
187 ififo_we := '0';
188 ififo_reset := '0';
189
190 isbusy := '0';
191 if unsigned(r.cntbusy) /= 0 then
192 isbusy := '1';
193 end if;
194
195 -- rbus address decoder
196 n.rbsel := '0';
197 if RB_MREQ.aval='1' and RB_MREQ.addr(15 downto 3)=RB_ADDR(15 downto 3) then
198
199 n.rbsel := '1';
200
201 if irbena = '0' then -- addr valid and selected, but no req
202 n.cntbusy := r.nbusy; -- preset busy timer
203 n.cntcyc := (others=>'0'); -- clear cycle length counter
204 end if;
205
206 end if;
207
208 -- rbus transactions
209 if r.rbsel = '1' then
210
211 if irbena = '1' then -- if request active
212 if unsigned(r.cntbusy) /= 0 then -- if busy timer > 0
213 n.cntbusy := slv(unsigned(r.cntbusy) - 1); -- decrement busy timer
214 end if;
215 if r.cntcyc /= cntcyc_max then -- if cycle counter < max
216 n.cntcyc := slv(unsigned(r.cntcyc) + 1); -- increment cycle counter
217 end if;
218 end if;
219
220 irb_ack := irbena; -- ack all (some rejects later)
221
222 case RB_MREQ.addr(2 downto 0) is
223
224 when rbaddr_cntl =>
225 if RB_MREQ.we='1' then
226 n.wchk := RB_MREQ.din(cntl_rbf_wchk);
227 n.nbusy := RB_MREQ.din(cntl_rbf_nbusy);
228 end if;
229
230 when rbaddr_stat =>
231 if RB_MREQ.we='1' then
232 n.stat := RB_MREQ.din(r.stat'range);
233 end if;
234
235 when rbaddr_attn =>
236 if RB_MREQ.we = '1' then -- on we
237 irblam := RB_MREQ.din; -- ping lam lines
238 elsif RB_MREQ.re = '1' then -- on re
239 irb_err := '1'; -- reject
240 end if;
241
242 when rbaddr_ncyc =>
243 if RB_MREQ.we = '1' then -- on we
244 irb_err := '1'; -- reject
245 end if;
246
247 when rbaddr_data =>
248 irb_busy := irbena and isbusy;
249 if RB_MREQ.we='1' and isbusy='0' then
250 n.wchk := '0';
251 n.data := RB_MREQ.din;
252 end if;
253
254 when rbaddr_dinc =>
255 irb_busy := irbena and isbusy;
256 if RB_MREQ.we = '1' then
257 if r.data /= RB_MREQ.din then
258 n.wchk := '1';
259 end if;
260 end if;
261 if (RB_MREQ.re='1' or RB_MREQ.we='1') and isbusy='0' then
262 n.data := slv(unsigned(r.data) + 1);
263 end if;
264
265 when rbaddr_fifo =>
266 irb_busy := irbena and isbusy;
267 if RB_MREQ.re='1' and isbusy='0' then
268 if FIFO_EMPTY = '1' then
269 irb_err := '1';
270 else
271 ififo_ce := '1';
272 end if;
273 end if;
274 if RB_MREQ.we='1' and isbusy='0' then
275 if FIFO_FULL = '1' then
276 irb_err := '1';
277 else
278 ififo_ce := '1';
279 ififo_we := '1';
280 end if;
281 end if;
282
283 when rbaddr_lnak =>
284 irb_ack := '0'; -- nak it
285 if isbusy = '1' then -- or do a delayed nak
286 irb_ack := irbena;
287 irb_busy := irbena;
288 end if;
289
290 when others => null;
291 end case;
292 end if;
293
294 -- rbus output driver
295 -- send a '0101...' pattern when selected and busy or err
296 -- send data only when busy=0 and err=0
297 -- this extra logic allows to debug rlink state machine
298 if r.rbsel = '1' then
299 irb_dout := "0101010101010101"; -- drive this pattern when selected
300 if RB_MREQ.re='1' and irb_busy='0' and irb_err='0' then
301 case RB_MREQ.addr(2 downto 0) is
302 when rbaddr_cntl =>
303 irb_dout := (others=>'0');
304 irb_dout(cntl_rbf_wchk) := r.wchk;
305 irb_dout(cntl_rbf_nbusy) := r.nbusy;
306 when rbaddr_stat =>
307 irb_dout := (others=>'0');
308 irb_dout(r.stat'range) := r.stat;
309 when rbaddr_attn => null;
310 when rbaddr_ncyc =>
311 irb_dout := (others=>'0');
312 irb_dout(r.cntcyc'range) := r.ncyc;
313 when rbaddr_data | rbaddr_dinc =>
314 irb_dout := r.data;
315 when rbaddr_fifo =>
316 if FIFO_EMPTY = '0' then
317 irb_dout := FIFO_DO;
318 end if;
319 when rbaddr_lnak => null;
320 when others => null;
321 end case;
322 end if;
323 end if;
324
325 -- init transactions
326 if RB_MREQ.init='1' and RB_MREQ.addr=RB_ADDR then
327 if RB_MREQ.din(init_rbf_cntl) = '1' then
328 n.wchk := '0';
329 n.stat := (others=>'0');
330 n.nbusy := (others=>'0');
331 end if;
332 if RB_MREQ.din(init_rbf_data) = '1' then
333 n.data := (others=>'0');
334 end if;
335 if RB_MREQ.din(init_rbf_fifo) = '1' then
336 ififo_reset := '1';
337 end if;
338 end if;
339
340 -- other transactions
341 if irbena='0' and r.act_1='1' then
342 n.ncyc := r.cntcyc;
343 end if;
344 n.act_1 := irbena;
345
346 N_REGS <= n;
347
348 FIFO_CE <= ififo_ce;
349 FIFO_WE <= ififo_we;
350 FIFO_RESET <= ififo_reset;
351
352 RB_SRES.dout <= irb_dout;
353 RB_SRES.ack <= irb_ack;
354 RB_SRES.err <= irb_err;
355 RB_SRES.busy <= irb_busy;
356
357 RB_LAM <= irblam;
358 RB_STAT <= r.stat;
359
360 end process proc_next;
361
362end syn;
out DO slv( DWIDTH- 1 downto 0)
in DI slv( DWIDTH- 1 downto 0)
AWIDTH positive := 6
out SIZE slv( AWIDTH- 1 downto 0)
DWIDTH positive := 16
slbit := '0' FIFO_FULL
Definition: rbd_tester.vhd:127
integer := 1 init_rbf_data
Definition: rbd_tester.vhd:92
integer range 9 downto 0 cntl_rbf_nbusy
Definition: rbd_tester.vhd:89
slv( awidth- 1 downto 0) :=( others => '0') FIFO_SIZE
Definition: rbd_tester.vhd:128
slbit := '0' FIFO_CE
Definition: rbd_tester.vhd:124
regs_type := regs_init N_REGS
Definition: rbd_tester.vhd:121
integer := 0 init_rbf_cntl
Definition: rbd_tester.vhd:91
slv3 := "101" rbaddr_dinc
Definition: rbd_tester.vhd:84
integer := 2 init_rbf_fifo
Definition: rbd_tester.vhd:93
integer := 15 cntl_rbf_wchk
Definition: rbd_tester.vhd:88
slv16 :=( others => '0') FIFO_DO
Definition: rbd_tester.vhd:129
slv3 := "000" rbaddr_cntl
Definition: rbd_tester.vhd:79
slv3 := "001" rbaddr_stat
Definition: rbd_tester.vhd:80
slv3 := "110" rbaddr_fifo
Definition: rbd_tester.vhd:85
regs_type := regs_init R_REGS
Definition: rbd_tester.vhd:120
slbit := '0' FIFO_EMPTY
Definition: rbd_tester.vhd:126
slbit := '0' FIFO_RESET
Definition: rbd_tester.vhd:123
slv3 := "111" rbaddr_lnak
Definition: rbd_tester.vhd:86
slv3 := "010" rbaddr_attn
Definition: rbd_tester.vhd:81
slv3 := "100" rbaddr_data
Definition: rbd_tester.vhd:83
positive := 4 awidth
Definition: rbd_tester.vhd:77
regs_type :=( '0', '0',( others => '0'),( others => '0'),( others => '0'), '0',( others => '0'),( others => '0'),( others => '0')) regs_init
Definition: rbd_tester.vhd:107
slv( regs_init.cntcyc'range ) :=( others => '1') cntcyc_max
Definition: rbd_tester.vhd:118
slv3 := "011" rbaddr_ncyc
Definition: rbd_tester.vhd:82
slbit := '0' FIFO_WE
Definition: rbd_tester.vhd:125
in RESET slbit
Definition: rbd_tester.vhd:66
RB_ADDR slv16 := rbaddr_tester
Definition: rbd_tester.vhd:63
out RB_STAT slv4
Definition: rbd_tester.vhd:71
out RB_LAM slv16
Definition: rbd_tester.vhd:69
in CLK slbit
Definition: rbd_tester.vhd:65
in RB_MREQ rb_mreq_type
Definition: rbd_tester.vhd:67
out RB_SRES rb_sres_type
Definition: rbd_tester.vhd:68
Definition: rblib.vhd:32
std_logic_vector( 9 downto 0) slv10
Definition: slvtypes.vhd:42
std_logic_vector( 3 downto 0) slv4
Definition: slvtypes.vhd:36
std_logic_vector( 2 downto 0) slv3
Definition: slvtypes.vhd:35
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector slv
Definition: slvtypes.vhd:31