w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
ibd_ibtst.vhd
Go to the documentation of this file.
1-- $Id: ibd_ibtst.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2019- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: ibd_ibtst - syn
7-- Description: ibus dev(rem): ibus tester
8--
9-- Dependencies: memlib/fifo_simple_dram
10-- Test bench: -
11-- Target Devices: generic
12-- Tool versions: ise 14.7; viv 2017.2; ghdl 0.35
13--
14-- Revision History:
15-- Date Rev Version Comment
16-- 2019-03-01 1116 1.0.1 rnam dly[rw]->bsy[rw]; datto for write; add datab
17-- 2019-02-16 1112 1.0 Initial version
18-- 2019-02-09 1110 0.1 First draft
19------------------------------------------------------------------------------
20--
21-- ibus registers:
22--
23-- Addr Bits IB RB IR Name Function
24-- 00 cntl Control register
25-- 15 -- 0W 00 fclr fifo clear
26-- 8 -- RW 00 datab ibus ack while busy for data nak
27-- 7 -- RW 00 datto ibus timeout for data nak
28-- 6 -- RW 00 nobyt disallow byte writes to data (loc+rem)
29-- 5 -- RW 00 bsyw enable loc write busy for fifo/data
30-- 4 -- RW 00 bsyr enable loc read busy for fifo/data
31-- 3 -- RW 11 remw enable rem write for fifo/data
32-- 2 -- RW 11 remr enable rem read for fifo/data
33-- 1 -- RW 00 locw enable loc write for fifo/data
34-- 0 -- RW 00 locr enable loc read for fifo/data
35-- 01 -- R- stat Status register (moni last data/fifo)
36-- 15:12 -- R- fsize fifo size
37-- 6 -- R- racc remote access seen
38-- 5 -- R- cacc console access seen
39-- 4 -- R- be1 byte enable high seen
40-- 3 -- R- be0 byte enable low seen
41-- 2 -- R- rmw read-modify-write seen
42-- 1 -- R- we write enable seen
43-- 0 -- R- re read enable seen
44-- 10 rw rw 00 data data register (byte/word writable)
45-- 11 rw rw fifo fifo interface register
46------------------------------------------------------------------------------
47
48library ieee;
49use ieee.std_logic_1164.all;
50use ieee.numeric_std.all;
51
52use work.slvtypes.all;
53use work.memlib.all;
54use work.iblib.all;
55
56-- ----------------------------------------------------------------------------
57entity ibd_ibtst is -- ibus dev(rem): ibus tester
58 generic (
59 IB_ADDR : slv16 := slv(to_unsigned(8#170000#,16))); -- base address
60 port (
61 CLK : in slbit; -- clock
62 RESET : in slbit; -- reset
63 IB_MREQ : in ib_mreq_type; -- ibus request
64 IB_SRES : out ib_sres_type -- ibus response
65 );
66end ibd_ibtst;
67
68architecture syn of ibd_ibtst is
69
70 constant ibaddr_cntl : slv2 := "00"; -- cntl address offset
71 constant ibaddr_stat : slv2 := "01"; -- stat address offset
72 constant ibaddr_data : slv2 := "10"; -- bdat address offset
73 constant ibaddr_fifo : slv2 := "11"; -- wdat address offset
74
75 constant cntl_ibf_fclr : integer := 15;
76 constant cntl_ibf_datab : integer := 8;
77 constant cntl_ibf_datto : integer := 7;
78 constant cntl_ibf_nobyt : integer := 6;
79 constant cntl_ibf_bsyw : integer := 5;
80 constant cntl_ibf_bsyr : integer := 4;
81 constant cntl_ibf_remw : integer := 3;
82 constant cntl_ibf_remr : integer := 2;
83 constant cntl_ibf_locw : integer := 1;
84 constant cntl_ibf_locr : integer := 0;
85
86 subtype stat_ibf_fsize is integer range 15 downto 12;
87 constant stat_ibf_racc : integer := 6;
88 constant stat_ibf_cacc : integer := 5;
89 constant stat_ibf_be1 : integer := 4;
90 constant stat_ibf_be0 : integer := 3;
91 constant stat_ibf_rmw : integer := 2;
92 constant stat_ibf_we : integer := 1;
93 constant stat_ibf_re : integer := 0;
94
95 type regs_type is record -- state registers
96 ibsel : slbit; -- ibus select
97 datab : slbit; -- cntl: ibus busy for bad loc data
98 datto : slbit; -- cntl: ibus timeout for bad loc data
99 nobyt : slbit; -- cntl: disallow byte writes to data
100 bsyw : slbit; -- cntl: enable loc write busy
101 bsyr : slbit; -- cntl: enable loc read busy
102 remw : slbit; -- cntl: enable rem write
103 remr : slbit; -- cntl: enable rem read
104 locw : slbit; -- cntl: enable loc write
105 locr : slbit; -- cntl: enable loc read
106 racc : slbit; -- stat: racc seen
107 cacc : slbit; -- stat: cacc seen
108 be1 : slbit; -- stat: be1 seen
109 be0 : slbit; -- stat: be0 seen
110 rmw : slbit; -- stat: rmw seen
111 we : slbit; -- stat: we seen
112 re : slbit; -- stat: re seen
113 data : slv16; -- data register
114 dcnt : slv3; -- delay counter
115 req_1 : slbit; -- (re or we) of last cycle
116 rwm_1 : slbit; -- (re or we or rmw) of last cycle
117 end record regs_type;
118
119 constant regs_init : regs_type := (
120 '0', -- ibsel
121 '0','0','0','0','0', -- datab,datto,nobyt,bsyw,bsyr
122 '1','1','0','0', -- remw,remr,locw,locr
123 '0','0','0','0', -- racc,cacc,be1,be0
124 '0','0','0', -- rmw,we,re
125 (others=>'0'), -- data
126 (others=>'0'), -- dcnt
127 '0','0' -- req_1,rwm_1
128 );
129
132
133 signal FIFO_CE : slbit := '0';
134 signal FIFO_WE : slbit := '0';
135 signal FIFO_RESET : slbit := '0';
136 signal FIFO_EMPTY : slbit := '0';
137 signal FIFO_FULL : slbit := '0';
138 signal FIFO_SIZE : slv4 := (others=>'0');
139 signal FIFO_DO : slv16 := (others=>'0');
140
141begin
142
143 FIFO : fifo_simple_dram
144 generic map (
145 AWIDTH => 4,
146 DWIDTH => 16)
147 port map (
148 CLK => CLK,
149 RESET => FIFO_RESET,
150 CE => FIFO_CE,
151 WE => FIFO_WE,
152 DI => IB_MREQ.din,
153 DO => FIFO_DO,
154 EMPTY => FIFO_EMPTY,
155 FULL => FIFO_FULL,
156 SIZE => FIFO_SIZE
157 );
158
159 proc_regs: process (CLK)
160 begin
161 if rising_edge(CLK) then
162 if RESET = '1' then
163 R_REGS <= regs_init;
164 else
165 R_REGS <= N_REGS;
166 end if;
167 end if;
168 end process proc_regs;
169
170 proc_next : process (R_REGS, IB_MREQ, RESET, FIFO_DO, FIFO_EMPTY,
172 variable r : regs_type := regs_init;
173 variable n : regs_type := regs_init;
174 variable ibreq : slbit := '0';
175 variable ibbusy : slbit := '0';
176 variable iback : slbit := '0';
177 variable idout : slv16 := (others=>'0');
178 variable ififo_rst : slbit := '0';
179 variable ififo_ce : slbit := '0';
180 variable ififo_we : slbit := '0';
181 variable bsyok : slbit := '0'; -- fifo/data busy ok
182 variable dobsy : slbit := '0'; -- fifo/data do busy
183 variable wrok : slbit := '0'; -- fifo/data write ok
184 variable rdok : slbit := '0'; -- fifo/data read ok
185 begin
186
187 r := R_REGS;
188 n := R_REGS;
189
190 idout := (others=>'0');
191 ibreq := IB_MREQ.re or IB_MREQ.we;
192 ibbusy := '0';
193 iback := r.ibsel and ibreq;
194 ififo_rst := RESET;
195 ififo_ce := '0';
196 ififo_we := '0';
197
198 bsyok := '0';
199 if IB_MREQ.racc = '0' then -- loc
200 bsyok := (r.bsyr and IB_MREQ.re) or (r.bsyw and IB_MREQ.we);
201 end if;
202 dobsy := '0';
203
204 if IB_MREQ.racc = '1' then -- rem
205 wrok := r.remw;
206 rdok := r.remr;
207 else -- loc
208 wrok := r.locw;
209 rdok := r.locr;
210 end if;
211
212 -- ibus address decoder
213 n.ibsel := '0';
214 if IB_MREQ.aval='1' and IB_MREQ.addr(12 downto 3)=IB_ADDR(12 downto 3) then
215 n.ibsel := '1';
216 end if;
217
218 -- re,we,rmw edge detectors
219 n.req_1 := r.ibsel and (ibreq);
220 n.rwm_1 := r.ibsel and (ibreq or IB_MREQ.rmw);
221
222 -- ibus mreq monitor
223 if r.ibsel = '1' then
224 if (ibreq or IB_MREQ.rmw) = '1' and -- re or we or rmw
225 IB_MREQ.addr(2) = '1' then -- and addr = (data or fifo)
226 if r.rwm_1 = '0' then -- leading edge
227 n.racc := IB_MREQ.racc;
228 n.cacc := IB_MREQ.cacc;
229 n.be1 := IB_MREQ.be1;
230 n.be0 := IB_MREQ.be0;
231 n.rmw := IB_MREQ.rmw;
232 n.we := IB_MREQ.we;
233 n.re := IB_MREQ.re;
234 else -- later
235 n.we := r.we or IB_MREQ.we;
236 n.re := r.re or IB_MREQ.re;
237 end if;
238 end if;
239 end if;
240
241 -- delay counter
242 if r.ibsel='1' and ibreq='1' and bsyok='1' then -- selected,active,busy
243 if r.req_1 = '0' then -- leading edge
244 n.dcnt := "111";
245 dobsy := '1';
246 else -- later
247 if r.dcnt /= "000" then
248 n.dcnt := slv(unsigned(r.dcnt) - 1);
249 dobsy := '1';
250 end if;
251 end if;
252 end if;
253
254 -- ibus transactions
255 if r.ibsel = '1' then
256 case IB_MREQ.addr(2 downto 1) is
257 when ibaddr_cntl => -- CNTL
258 if IB_MREQ.racc = '1' then -- rem
259 if IB_MREQ.we = '1' then -- write
260 ififo_rst := IB_MREQ.din(cntl_ibf_fclr);
261 n.datab := IB_MREQ.din(cntl_ibf_datab);
262 n.datto := IB_MREQ.din(cntl_ibf_datto);
263 n.nobyt := IB_MREQ.din(cntl_ibf_nobyt);
264 n.bsyw := IB_MREQ.din(cntl_ibf_bsyw);
265 n.bsyr := IB_MREQ.din(cntl_ibf_bsyr);
266 n.remw := IB_MREQ.din(cntl_ibf_remw);
267 n.remr := IB_MREQ.din(cntl_ibf_remr);
268 n.locw := IB_MREQ.din(cntl_ibf_locw);
269 n.locr := IB_MREQ.din(cntl_ibf_locr);
270 end if;
271 else -- loc
272 iback := '0'; -- reject loc access to CNTL
273 end if;
274
275 when ibaddr_stat => -- STAT
276 if IB_MREQ.racc = '0' then -- loc
277 iback := '0'; -- reject loc access to STAT
278 end if;
279
280 when ibaddr_data => -- DATA
281 if IB_MREQ.we = '1' then -- write
282 if wrok = '1' then -- write enabled
283 if r.nobyt = '1' and -- byte write allowed check
284 (IB_MREQ.be1='0' or IB_MREQ.be0='0') then
285 iback := '0'; -- send nak
286 else -- byte check ok
287 if dobsy = '1' then -- busy active
288 iback := '0';
289 ibbusy := '1';
290 else -- no busy active
291 if IB_MREQ.be1 = '1' then
292 n.data(ibf_byte1) := IB_MREQ.din(ibf_byte1);
293 end if;
294 if IB_MREQ.be0 = '1' then
295 n.data(ibf_byte0) := IB_MREQ.din(ibf_byte0);
296 end if;
297 end if; -- dobsy = '1'
298 end if; -- byte check
299 else -- write disabled
300 if dobsy = '1' then -- busy active
301 iback := r.datab; -- send ack when busy for nak
302 ibbusy := '1';
303 else -- no busy active
304 if r.datto = '1' then -- data time out enabled
305 iback := '0';
306 ibbusy := '1'; -- will cause timeout !
307 else
308 iback := '0'; -- send nak
309 end if;
310 end if; -- dobsy = '1'
311 end if; -- wrok = '1'
312 end if; -- IB_MREQ.we = '1'
313
314 if IB_MREQ.re = '1' then -- read
315 if rdok = '1' then -- read enabled
316 if dobsy = '1' then -- busy active
317 iback := '0';
318 ibbusy := '1';
319 end if;
320 else -- read disabled
321 if dobsy = '1' then -- busy active
322 iback := r.datab; -- send ack when busy for nak
323 ibbusy := '1';
324 else -- no busy active
325 if r.datto = '1' then -- data time out enabled
326 iback := '0';
327 ibbusy := '1'; -- will cause timeout !
328 else
329 iback := '0'; -- send nak
330 end if;
331 end if; -- dobsy = '1'
332 end if; -- rdok = '0'
333 end if; -- IB_MREQ.re = '1'
334
335 when ibaddr_fifo => -- FIFO
336 if IB_MREQ.we = '1' then -- write
337 if wrok = '1' then -- write enabled
338 if dobsy = '1' then -- busy active
339 iback := '0';
340 ibbusy := '1';
341 else -- busy not active
342 if FIFO_FULL = '0' then -- fifo not full
343 ififo_ce := '1';
344 ififo_we := '1';
345 else -- fifo full
346 iback := '0'; -- send nak
347 end if; -- FIFO_FULL = '0'
348 end if; -- dobsy = '1'
349 else -- write disabled
350 iback := '0'; -- send nak
351 end if; -- wrok = '1'
352 end if; -- IB_MREQ.we = '1'
353
354 if IB_MREQ.re = '1' then -- read
355 if rdok = '1' then -- read enabled
356 if dobsy = '1' then -- busy active
357 iback := '0';
358 ibbusy := '1';
359 else -- busy not active
360 if FIFO_EMPTY = '0' then -- fifo not empty
361 ififo_ce := '1';
362 else -- fifo empty
363 iback := '0'; -- send nak
364 end if; -- FIFO_EMPTY = '0'
365 end if; -- dobsy = '1'
366 else -- read disabled
367 iback := '0'; -- send nak
368 end if; -- rdok = '1'
369 end if; -- IB_MREQ.re = '1'
370
371 when others => null;
372 end case; --
373 end if; --r.ibsel = '1'
374
375 -- ibus output driver
376 if r.ibsel = '1' then
377 case IB_MREQ.addr(2 downto 1) is
378 when ibaddr_cntl => -- CNTL
379 idout(cntl_ibf_datab) := r.datab;
380 idout(cntl_ibf_datto) := r.datto;
381 idout(cntl_ibf_nobyt) := r.nobyt;
382 idout(cntl_ibf_bsyw) := r.bsyw;
383 idout(cntl_ibf_bsyr) := r.bsyr;
384 idout(cntl_ibf_remw) := r.remw;
385 idout(cntl_ibf_remr) := r.remr;
386 idout(cntl_ibf_locw) := r.locw;
387 idout(cntl_ibf_locr) := r.locr;
388 when ibaddr_stat => -- STAT
389 idout(stat_ibf_fsize) := FIFO_SIZE;
390 idout(stat_ibf_racc) := r.racc;
391 idout(stat_ibf_cacc) := r.cacc;
392 idout(stat_ibf_be1) := r.be1;
393 idout(stat_ibf_be0) := r.be0;
394 idout(stat_ibf_rmw) := r.rmw;
395 idout(stat_ibf_we) := r.we;
396 idout(stat_ibf_re) := r.re;
397 when ibaddr_data => -- DATA
398 idout := r.data;
399 when ibaddr_fifo => -- FIFO
400 idout := FIFO_DO;
401 when others => null;
402 end case;
403 end if;
404
405 N_REGS <= n;
406
407 FIFO_RESET <= ififo_rst;
408 FIFO_CE <= ififo_ce;
409 FIFO_WE <= ififo_we;
410
411 IB_SRES.dout <= idout;
412 IB_SRES.ack <= iback;
413 IB_SRES.busy <= ibbusy;
414
415 end process proc_next;
416
417
418end 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: ibd_ibtst.vhd:137
integer := 4 cntl_ibf_bsyr
Definition: ibd_ibtst.vhd:80
integer := 4 stat_ibf_be1
Definition: ibd_ibtst.vhd:89
integer := 0 cntl_ibf_locr
Definition: ibd_ibtst.vhd:84
integer := 15 cntl_ibf_fclr
Definition: ibd_ibtst.vhd:75
slv4 :=( others => '0') FIFO_SIZE
Definition: ibd_ibtst.vhd:138
integer := 1 stat_ibf_we
Definition: ibd_ibtst.vhd:92
slbit := '0' FIFO_CE
Definition: ibd_ibtst.vhd:133
regs_type := regs_init N_REGS
Definition: ibd_ibtst.vhd:131
integer := 2 stat_ibf_rmw
Definition: ibd_ibtst.vhd:91
slv2 := "10" ibaddr_data
Definition: ibd_ibtst.vhd:72
integer := 6 stat_ibf_racc
Definition: ibd_ibtst.vhd:87
integer := 0 stat_ibf_re
Definition: ibd_ibtst.vhd:93
slv16 :=( others => '0') FIFO_DO
Definition: ibd_ibtst.vhd:139
regs_type :=( '0', '0', '0', '0', '0', '0', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0',( others => '0'),( others => '0'), '0', '0') regs_init
Definition: ibd_ibtst.vhd:119
integer := 5 cntl_ibf_bsyw
Definition: ibd_ibtst.vhd:79
integer := 5 stat_ibf_cacc
Definition: ibd_ibtst.vhd:88
integer := 1 cntl_ibf_locw
Definition: ibd_ibtst.vhd:83
integer := 6 cntl_ibf_nobyt
Definition: ibd_ibtst.vhd:78
integer := 3 cntl_ibf_remw
Definition: ibd_ibtst.vhd:81
regs_type := regs_init R_REGS
Definition: ibd_ibtst.vhd:130
slbit := '0' FIFO_EMPTY
Definition: ibd_ibtst.vhd:136
slv2 := "01" ibaddr_stat
Definition: ibd_ibtst.vhd:71
slbit := '0' FIFO_RESET
Definition: ibd_ibtst.vhd:135
integer := 3 stat_ibf_be0
Definition: ibd_ibtst.vhd:90
slv2 := "00" ibaddr_cntl
Definition: ibd_ibtst.vhd:70
slv2 := "11" ibaddr_fifo
Definition: ibd_ibtst.vhd:73
integer := 7 cntl_ibf_datto
Definition: ibd_ibtst.vhd:77
integer range 15 downto 12 stat_ibf_fsize
Definition: ibd_ibtst.vhd:86
integer := 2 cntl_ibf_remr
Definition: ibd_ibtst.vhd:82
integer := 8 cntl_ibf_datab
Definition: ibd_ibtst.vhd:76
slbit := '0' FIFO_WE
Definition: ibd_ibtst.vhd:134
in RESET slbit
Definition: ibd_ibtst.vhd:62
in CLK slbit
Definition: ibd_ibtst.vhd:61
in IB_MREQ ib_mreq_type
Definition: ibd_ibtst.vhd:63
out IB_SRES ib_sres_type
Definition: ibd_ibtst.vhd:65
IB_ADDR slv16 := slv( to_unsigned( 8#170000#, 16) )
Definition: ibd_ibtst.vhd:59
Definition: iblib.vhd:33
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( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31