w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
ibdr_dl11_buf.vhd
Go to the documentation of this file.
1-- $Id: ibdr_dl11_buf.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: ibdr_dl11_buf - syn
7-- Description: ibus dev(rem): DL11-A/B
8--
9-- Dependencies: fifo_simple_dram
10-- ib_rlim_slv
11-- Test bench: -
12-- Target Devices: generic
13-- Tool versions: ise 8.2-14.7; viv 2017.2; ghdl 0.18-0.35
14--
15-- Revision History:
16-- Date Rev Version Comment
17-- 2019-05-31 1156 1.0.1 size->fuse rename; re-organize rlim handling
18-- 2019-04-26 1139 1.0 Initial version (derived from ibdr_{dl11,pc11_buf})
19------------------------------------------------------------------------------
20
21library ieee;
22use ieee.std_logic_1164.all;
23use ieee.numeric_std.all;
24
25use work.slvtypes.all;
26use work.memlib.all;
27use work.iblib.all;
28
29-- ----------------------------------------------------------------------------
30entity ibdr_dl11_buf is -- ibus dev(rem): DL11-A/B
31 generic (
32 IB_ADDR : slv16 := slv(to_unsigned(8#177560#,16));
33 AWIDTH : natural := 5); -- fifo address width
34 port (
35 CLK : in slbit; -- clock
36 RESET : in slbit; -- system reset
37 BRESET : in slbit; -- ibus reset
38 RLIM_CEV : in slv8; -- clock enable vector
39 RB_LAM : out slbit; -- remote attention
40 IB_MREQ : in ib_mreq_type; -- ibus request
41 IB_SRES : out ib_sres_type; -- ibus response
42 EI_REQ_RX : out slbit; -- interrupt request, receiver
43 EI_REQ_TX : out slbit; -- interrupt request, transmitter
44 EI_ACK_RX : in slbit; -- interrupt acknowledge, receiver
45 EI_ACK_TX : in slbit -- interrupt acknowledge, transmitter
46 );
48
49architecture syn of ibdr_dl11_buf is
50
51 constant ibaddr_rcsr : slv2 := "00"; -- rcsr address offset
52 constant ibaddr_rbuf : slv2 := "01"; -- rbuf address offset
53 constant ibaddr_xcsr : slv2 := "10"; -- xcsr address offset
54 constant ibaddr_xbuf : slv2 := "11"; -- xbuf address offset
55
56 subtype rcsr_ibf_rrlim is integer range 14 downto 12;
57 subtype rcsr_ibf_type is integer range 10 downto 8;
58 constant rcsr_ibf_rdone : integer := 7;
59 constant rcsr_ibf_rie : integer := 6;
60 constant rcsr_ibf_rir : integer := 5;
61 constant rcsr_ibf_rlb : integer := 4;
62 constant rcsr_ibf_fclr : integer := 1;
63
64 subtype rbuf_ibf_rfuse is integer range AWIDTH-1+8 downto 8;
65 subtype rbuf_ibf_xfuse is integer range AWIDTH-1 downto 0;
66 subtype rbuf_ibf_data is integer range 7 downto 0;
67
68 subtype xcsr_ibf_xrlim is integer range 14 downto 12;
69 constant xcsr_ibf_xrdy : integer := 7;
70 constant xcsr_ibf_xie : integer := 6;
71 constant xcsr_ibf_xir : integer := 5;
72 constant xcsr_ibf_rlb : integer := 4;
73 constant xcsr_ibf_fclr : integer := 1;
74
75 constant xbuf_ibf_xval : integer := 15;
76 subtype xbuf_ibf_fuse is integer range AWIDTH-1+8 downto 8;
77 subtype xbuf_ibf_data is integer range 7 downto 0;
78
79 type regs_type is record -- state registers
80 ibsel : slbit; -- ibus select
81 rrlim : slv3; -- rcsr: receiver rate limit
82 rdone : slbit; -- rcsr: receiver done
83 rie : slbit; -- rcsr: receiver interrupt enable
84 rintreq : slbit; -- rx interrupt request
85 xrlim : slv3; -- xcsr: transmitter rate limit
86 xrdy : slbit; -- xcsr: transmitter ready
87 xie : slbit; -- xcsr: transmitter interrupt enable
88 xintreq : slbit; -- tx interrupt request
89 end record regs_type;
90
91 constant regs_init : regs_type := (
92 '0', -- ibsel
93 "000", -- rrlim
94 '0','0','0', -- rdone,rie,rintreq
95 "000", -- xrlim
96 '1', -- xrdy !! is set !!
97 '0', -- xie
98 '0' -- xintreq
99 );
100
101 constant c_fuse1 : slv(AWIDTH-1 downto 0) := slv(to_unsigned(1,AWIDTH));
102
105
106 signal RBUF_CE : slbit := '0';
107 signal RBUF_WE : slbit := '0';
108 signal RBUF_DO : slv8 := (others=>'0');
109 signal RBUF_RESET : slbit := '0';
110 signal RBUF_EMPTY : slbit := '0';
111 signal RBUF_FULL : slbit := '0';
112 signal RBUF_FUSE : slv(AWIDTH-1 downto 0) := (others=>'0');
113
114 signal XBUF_CE : slbit := '0';
115 signal XBUF_WE : slbit := '0';
116 signal XBUF_DO : slv8 := (others=>'0');
117 signal XBUF_RESET : slbit := '0';
118 signal XBUF_EMPTY : slbit := '0';
119 signal XBUF_FULL : slbit := '0';
120 signal XBUF_FUSE : slv(AWIDTH-1 downto 0) := (others=>'0');
121
122 signal RRLIM_START : slbit := '0';
123 signal RRLIM_BUSY : slbit := '0';
124 signal XRLIM_START : slbit := '0';
125 signal XRLIM_BUSY : slbit := '0';
126
127begin
128
129 assert AWIDTH>=4 and AWIDTH<=7
130 report "assert(AWIDTH>=4 and AWIDTH<=7): unsupported AWIDTH"
131 severity failure;
132
133 RBUF : fifo_simple_dram
134 generic map (
135 AWIDTH => AWIDTH,
136 DWIDTH => 8)
137 port map (
138 CLK => CLK,
139 RESET => RBUF_RESET,
140 CE => RBUF_CE,
141 WE => RBUF_WE,
142 DI => IB_MREQ.din(rbuf_ibf_data),
143 DO => RBUF_DO,
144 EMPTY => RBUF_EMPTY,
145 FULL => RBUF_FULL,
146 SIZE => RBUF_FUSE
147 );
148
149 XBUF : fifo_simple_dram
150 generic map (
151 AWIDTH => AWIDTH,
152 DWIDTH => 8)
153 port map (
154 CLK => CLK,
155 RESET => XBUF_RESET,
156 CE => XBUF_CE,
157 WE => XBUF_WE,
158 DI => IB_MREQ.din(xbuf_ibf_data),
159 DO => XBUF_DO,
160 EMPTY => XBUF_EMPTY,
161 FULL => XBUF_FULL,
162 SIZE => XBUF_FUSE
163 );
164
165 RRLIM : ib_rlim_slv
166 port map (
167 CLK => CLK,
168 RESET => RESET,
170 SEL => R_REGS.rrlim,
172 STOP => BRESET,
173 DONE => open,
175 );
176
177 XRLIM : ib_rlim_slv
178 port map (
179 CLK => CLK,
180 RESET => RESET,
182 SEL => R_REGS.xrlim,
184 STOP => BRESET,
185 DONE => open,
187 );
188
189 proc_regs: process (CLK)
190 begin
191 if rising_edge(CLK) then
192 if BRESET = '1' then
193 R_REGS <= regs_init;
194 if RESET = '0' then -- if RESET=0 we do just an ibus reset
195 R_REGS.rrlim <= N_REGS.rrlim; -- keep RRLIM field
196 R_REGS.xrlim <= N_REGS.xrlim; -- keep XRLIM field
197 end if;
198 else
199 R_REGS <= N_REGS;
200 end if;
201 end if;
202 end process proc_regs;
203
204 proc_next : process (R_REGS, IB_MREQ, EI_ACK_RX, EI_ACK_TX, RESET,
207 variable r : regs_type := regs_init;
208 variable n : regs_type := regs_init;
209 variable idout : slv16 := (others=>'0');
210 variable ibreq : slbit := '0';
211 variable iback : slbit := '0';
212 variable ibrd : slbit := '0';
213 variable ibw0 : slbit := '0';
214 variable ibw1 : slbit := '0';
215 variable ilam : slbit := '0';
216 variable irbufce : slbit := '0';
217 variable irbufwe : slbit := '0';
218 variable irbufrst : slbit := '0';
219 variable irrlimsta : slbit := '0';
220 variable ixbufce : slbit := '0';
221 variable ixbufwe : slbit := '0';
222 variable ixbufrst : slbit := '0';
223 variable ixrlimsta : slbit := '0';
224 begin
225
226 r := R_REGS;
227 n := R_REGS;
228
229 idout := (others=>'0');
230 ibreq := IB_MREQ.re or IB_MREQ.we;
231 iback := r.ibsel and ibreq;
232 ibrd := IB_MREQ.re;
233 ibw0 := IB_MREQ.we and IB_MREQ.be0;
234 ibw1 := IB_MREQ.we and IB_MREQ.be1;
235 ilam := '0';
236 irbufce := '0';
237 irbufwe := '0';
238 irbufrst := RESET;
239 irrlimsta := '0';
240 ixbufce := '0';
241 ixbufwe := '0';
242 ixbufrst := RESET;
243 ixrlimsta := '0';
244
245 -- ibus address decoder
246 n.ibsel := '0';
247 if IB_MREQ.aval='1' and
248 IB_MREQ.addr(12 downto 3)=IB_ADDR(12 downto 3) then
249 n.ibsel := '1';
250 end if;
251
252 -- ibus transactions
253 if r.ibsel = '1' then -- ibus selected ---------------------
254 case IB_MREQ.addr(2 downto 1) is
255
256 when ibaddr_rcsr => -- RCSR -- receive control status ----
257
258 idout(rcsr_ibf_rdone) := r.rdone;
259 idout(rcsr_ibf_rie) := r.rie;
260
261 if IB_MREQ.racc = '0' then -- cpu ---------------------
262 if ibw0 = '1' then -- rcsr write
263 n.rie := IB_MREQ.din(rcsr_ibf_rie);
264 if IB_MREQ.din(rcsr_ibf_rie) = '1' then-- set IE to 1
265 if r.rdone='1' and r.rie='0' then -- ie 0->1 while done=1
266 n.rintreq := '1'; -- request interrupt
267 end if;
268 else -- set IE to 0
269 n.rintreq := '0'; -- cancel interrupt
270 end if;
271 end if;
272
273 else -- rri ---------------------
274 idout(rcsr_ibf_rrlim) := r.rrlim;
275 idout(rcsr_ibf_type) := slv(to_unsigned(AWIDTH,3));
276 idout(rcsr_ibf_rir) := r.rintreq;
277 idout(rcsr_ibf_rlb) := RRLIM_BUSY;
278
279 if ibw1 = '1' then
280 n.rrlim := IB_MREQ.din(rcsr_ibf_rrlim);
281 end if;
282 if ibw0 = '1' then
283 if IB_MREQ.din(rcsr_ibf_fclr) = '1' then -- 1 written to FCLR
284 irbufrst := '1'; -- then reset fifo
285 end if;
286 end if;
287 end if;
288
289 when ibaddr_rbuf => -- RBUF -- receive data buffer -------
290
291 if IB_MREQ.racc = '0' then -- cpu ---------------------
292 idout(rbuf_ibf_data) := RBUF_DO;
293 if ibrd = '1' then -- rbuf read
294 n.rdone := '0'; -- clear done
295 n.rintreq := '0'; -- cancel interrupt
296 if r.rdone='1' then -- data available ?
297 irbufce := '1'; -- read next from fifo
298 irbufwe := '0';
299 if RBUF_FUSE = c_fuse1 then -- last value (fuse=1) ?
300 ilam := '1'; -- rri lam
301 end if;
302 end if;
303 end if;
304
305 else -- rri ---------------------
306 idout(rbuf_ibf_rfuse) := RBUF_FUSE;
307 idout(rbuf_ibf_xfuse) := XBUF_FUSE;
308 if ibw0 = '1' then
309 if RBUF_FULL = '0' then -- fifo not full
310 irbufce := '1'; -- write to fifo
311 irbufwe := '1';
312 else -- write to full fifo
313 iback := '0'; -- signal nak
314 end if;
315 end if;
316 end if;
317
318 when ibaddr_xcsr => -- XCSR -- transmit control status ---
319
320 idout(xcsr_ibf_xrdy) := r.xrdy;
321 idout(xcsr_ibf_xie) := r.xie;
322
323 if IB_MREQ.racc = '0' then -- cpu ---------------------
324 if ibw0 = '1' then
325 n.xie := IB_MREQ.din(xcsr_ibf_xie);
326 if IB_MREQ.din(xcsr_ibf_xie) = '1' then-- set IE to 1
327 if r.xrdy='1' and r.xie='0' then -- ie 0->1 while ready=1
328 n.xintreq := '1'; -- request interrupt
329 end if;
330 else -- set IE to 0
331 n.xintreq := '0'; -- cancel interrupts
332 end if;
333 end if;
334
335 else -- rri ---------------------
336 idout(xcsr_ibf_xrlim) := r.xrlim;
337 idout(xcsr_ibf_xir) := r.xintreq;
338 idout(xcsr_ibf_rlb) := XRLIM_BUSY;
339
340 if ibw1 = '1' then
341 n.xrlim := IB_MREQ.din(xcsr_ibf_xrlim); -- set XRLIM field
342 end if;
343 if ibw0 = '1' then
344 if IB_MREQ.din(xcsr_ibf_fclr) = '1' then -- 1 written to FCLR
345 ixbufrst := '1'; -- then reset fifo
346 end if;
347 end if;
348 end if;
349
350 when ibaddr_xbuf => -- XBUF -- transmit data buffer ------
351
352 if IB_MREQ.racc = '0' then -- cpu ---------------------
353 if ibw0 = '1' then
354 if r.xrdy = '1' then -- ignore buf write when rdy=0
355 n.xrdy := '0'; -- clear ready
356 n.xintreq := '0'; -- cancel interrupt
357 if XBUF_FULL = '0' then -- fifo not full
358 ixbufce := '1'; -- write to fifo
359 ixbufwe := '1';
360 if XBUF_EMPTY = '1' then -- first write to empty fifo
361 ilam := '1'; -- request attention
362 end if;
363 end if;
364 end if;
365 end if;
366
367 else -- rri ---------------------
368 idout(xbuf_ibf_xval) := not XBUF_EMPTY;
369 idout(xbuf_ibf_fuse) := XBUF_FUSE;
370 idout(xbuf_ibf_data) := XBUF_DO;
371 if ibrd = '1' then
372 if XBUF_EMPTY = '0' then -- fifo not empty
373 ixbufce := '1'; -- read from fifo
374 ixbufwe := '0';
375 else -- read from empty fifo
376 iback := '0'; -- signal nak
377 end if;
378 end if;
379 end if;
380
381 when others => null;
382 end case;
383
384 else -- ibus not selected -----------------
385 -- handle rx done, timer and interrupt
386 if RBUF_EMPTY='0' and RRLIM_BUSY='0' then -- not empty and not busy ?
387 if r.rdone = '0' then -- done not set ?
388 n.rdone := '1'; -- set done
389 irrlimsta := '1'; -- start timer
390 if r.rie = '1' then -- irupts enabled ?
391 n.rintreq := '1'; -- request rx interrupt
392 end if;
393 end if;
394 end if;
395
396 -- handle tx ready, timer and interrupt
397 if XBUF_FULL='0' and XRLIM_BUSY='0' then -- not full and not busy ?
398 if r.xrdy = '0' then -- ready not set ?
399 n.xrdy := '1'; -- set ready
400 ixrlimsta := '1'; -- start timer
401 if r.xie = '1' then -- irupts enabled ?
402 n.xintreq := '1'; -- request tx interrupt
403 end if;
404 end if;
405 end if;
406 end if; -- else r.ibsel='1'
407
408 -- other state changes
409
410 if EI_ACK_RX = '1' then
411 n.rintreq := '0';
412 end if;
413 if EI_ACK_TX = '1' then
414 n.xintreq := '0';
415 end if;
416
417 N_REGS <= n;
418
419 RBUF_RESET <= irbufrst;
420 RBUF_CE <= irbufce;
421 RBUF_WE <= irbufwe;
422 RRLIM_START <= irrlimsta;
423
424 XBUF_RESET <= ixbufrst;
425 XBUF_CE <= ixbufce;
426 XBUF_WE <= ixbufwe;
427 XRLIM_START <= ixrlimsta;
428
429 IB_SRES.dout <= idout;
430 IB_SRES.ack <= iback;
431 IB_SRES.busy <= '0';
432
433 RB_LAM <= ilam;
434 EI_REQ_RX <= r.rintreq;
435 EI_REQ_TX <= r.xintreq;
436
437 end process proc_next;
438
439
440end 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
in STOP slbit
Definition: ib_rlim_slv.vhd:46
in RESET slbit
Definition: ib_rlim_slv.vhd:42
out BUSY slbit
Definition: ib_rlim_slv.vhd:49
out DONE slbit
Definition: ib_rlim_slv.vhd:47
in CLK slbit
Definition: ib_rlim_slv.vhd:41
in SEL slv3
Definition: ib_rlim_slv.vhd:44
in RLIM_CEV slv8
Definition: ib_rlim_slv.vhd:43
in START slbit
Definition: ib_rlim_slv.vhd:45
integer range 7 downto 0 xbuf_ibf_data
slv( AWIDTH- 1 downto 0) :=( others => '0') RBUF_FUSE
slbit := '0' XBUF_FULL
ib_rlim_slv xrlimxrlim
slv2 := "01" ibaddr_rbuf
slv8 :=( others => '0') RBUF_DO
slbit := '0' XBUF_EMPTY
slbit := '0' RBUF_WE
slbit := '0' XRLIM_START
integer := 1 rcsr_ibf_fclr
slbit := '0' XBUF_RESET
integer := 7 xcsr_ibf_xrdy
slbit := '0' RBUF_FULL
integer := 1 xcsr_ibf_fclr
ib_rlim_slv rrlimrrlim
slv( AWIDTH- 1 downto 0) := slv( to_unsigned( 1, AWIDTH) ) c_fuse1
slv( AWIDTH- 1 downto 0) :=( others => '0') XBUF_FUSE
slbit := '0' XBUF_WE
slv2 := "00" ibaddr_rcsr
integer range 14 downto 12 xcsr_ibf_xrlim
regs_type := regs_init N_REGS
integer := 5 rcsr_ibf_rir
slv2 := "10" ibaddr_xcsr
slbit := '0' RBUF_EMPTY
integer range 7 downto 0 rbuf_ibf_data
integer := 6 xcsr_ibf_xie
integer range AWIDTH- 1 downto 0 rbuf_ibf_xfuse
integer := 4 rcsr_ibf_rlb
integer := 4 xcsr_ibf_rlb
slbit := '0' RRLIM_BUSY
integer := 7 rcsr_ibf_rdone
integer range 14 downto 12 rcsr_ibf_rrlim
slbit := '0' RRLIM_START
regs_type := regs_init R_REGS
slv8 :=( others => '0') XBUF_DO
integer range 10 downto 8 rcsr_ibf_type
integer := 6 rcsr_ibf_rie
slv2 := "11" ibaddr_xbuf
regs_type :=( '0', "000", '0', '0', '0', "000", '1', '0', '0') regs_init
integer := 15 xbuf_ibf_xval
slbit := '0' XBUF_CE
slbit := '0' RBUF_RESET
integer range AWIDTH- 1+ 8 downto 8 rbuf_ibf_rfuse
integer range AWIDTH- 1+ 8 downto 8 xbuf_ibf_fuse
slbit := '0' XRLIM_BUSY
slbit := '0' RBUF_CE
integer := 5 xcsr_ibf_xir
IB_ADDR slv16 := slv( to_unsigned( 8#177560#, 16) )
in RESET slbit
AWIDTH natural := 5
in EI_ACK_TX slbit
in EI_ACK_RX slbit
in BRESET slbit
out RB_LAM slbit
in CLK slbit
out EI_REQ_RX slbit
in IB_MREQ ib_mreq_type
out IB_SRES ib_sres_type
in RLIM_CEV slv8
out EI_REQ_TX slbit
Definition: iblib.vhd:33
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( 7 downto 0) slv8
Definition: slvtypes.vhd:40
std_logic_vector( 1 downto 0) slv2
Definition: slvtypes.vhd:34
std_logic_vector slv
Definition: slvtypes.vhd:31