OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [vlib/] [rlink/] [rlink_core.vhd] - Blame information for rev 34

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 wfjm
-- $Id: rlink_core.vhd 718 2015-12-26 15:59:48Z mueller $
2 2 wfjm
--
3 34 wfjm
-- Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 2 wfjm
--
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 9 wfjm
-- Module Name:    rlink_core - syn
16 27 wfjm
-- Description:    rlink core with 9bit interface (with rlmon+rbmon)
17 2 wfjm
--
18 27 wfjm
-- Dependencies:   memlib/ram_2swsr_rfirst_gen
19
--                 memlib/fifo_1c_dram
20
--                 comlib/crc16
21
--                 rb_sel
22
--                 rb_sres_or_2
23
--                 rlink_mon_sb    [sim only]
24
--                 rbus/rb_mon_sb  [sim only]
25 2 wfjm
--
26 9 wfjm
-- Test bench:     tb/tb_rlink_direct
27
--                 tb/tb_rlink_serport
28
--                 tb/tb_rlink_tba_ttcombo
29 2 wfjm
--
30
-- Target Devices: generic
31 29 wfjm
-- Tool versions:  ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
32 2 wfjm
--
33
-- Synthesized (xst):
34
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
35 34 wfjm
-- 2015-12-26   718 14.7  131013 xc6slx16-2   312  460   16  150 s  7.0 ver 4.1
36 27 wfjm
-- 2014-12-20   614 14.7  131013 xc6slx16-2   310  453   16  146 s  6.8 ver 4.0
37
-- 2014-08-13   581 14.7  131013 xc6slx16-2   160  230    0   73 s  6.0 ver 3.0
38
-- 2014-08-13   581 14.7  131013 xc3s1000-4   160  358    0  221 s  8.9 ver 3.0
39 2 wfjm
--
40
-- Revision History: 
41
-- Date         Rev Version  Comment
42 34 wfjm
-- 2015-12-26   718   4.1.1  add proc_sres: strip 'x' from RB_SRES.dout
43 28 wfjm
-- 2014-12-21   617   4.1    use stat(_rbf_rbtout) to signal rbus timeout
44 27 wfjm
-- 2014-12-20   614   4.0    largely rewritten; 2 FSMs; v3 protocol; 4 bit STAT
45
-- 2014-08-15   583   3.5    rb_mreq addr now 16 bit; add s_rxaddrl state
46 13 wfjm
-- 2011-11-19   427   3.1.3  now numeric_std clean
47 9 wfjm
-- 2010-12-25   348   3.1.2  drop RL_FLUSH support, add RL_MONI for rlink_core;
48
-- 2010-12-24   347   3.1.1  rename: CP_*->RL->*
49
-- 2010-12-22   346   3.1    wblk dcrc error: send nak, transit to s_error now;
50
--                           rename stat flags: [cd]crc->[cd]err, ioto->rbnak,
51
--                           ioerr->rberr; '111' cmd now aborts via s_txnak and
52
--                           sets cerr flag; set [cd]err on eop/nak aborts;
53
-- 2010-12-04   343   3.0    renamed rri_ -> rlink_; rbus V3 interface: use now
54
--                           aval,re,we; add new states: s_rstart, s_wstart
55 2 wfjm
-- 2010-06-20   308   2.6    use rbinit,rbreq,rbwe state flops to drive rb_mreq;
56
--                           now nak on reserved cmd 111; use do_comma_abort();
57
-- 2010-06-18   306   2.5.1  rename rbus data fields to _rbf_
58
-- 2010-06-06   302   2.5    use sop/eop framing instead of soc+chaining
59
-- 2010-06-03   299   2.1.2  drop unneeded unsigned casts; change init encoding
60
-- 2010-05-02   287   2.1.1  ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
61
--                           drop RP_IINT signal from interfaces
62
-- 2010-04-03   274   2.1    add CP_FLUSH output
63
-- 2009-07-12   233   2.0.1  remove snoopers
64
-- 2008-08-24   162   2.0    with new rb_mreq/rb_sres interface
65
-- 2008-03-02   121   1.1.1  comment out snoopers
66
-- 2007-11-24    98   1.1    new internal init handling (addr=11111111)
67
-- 2007-10-12    88   1.0.1  avoid ieee.std_logic_unsigned, use cast to unsigned
68
-- 2007-09-15    82   1.0    Initial version, fully functional
69
-- 2007-06-17    58   0.5    First preliminary version
70
------------------------------------------------------------------------------
71
--  7 supported commands:
72 27 wfjm
--    nak aborts to _txnak are indicated as [nak:<nakcode>]
73
--    commands to rbus engine are indicated as [bcmd:<bfunc>]
74 2 wfjm
--
75
--   000 read reg (rreg):
76 27 wfjm
--        rx: cmd al ah ccrcl ccrch
77
--        tx: cmd dl dh stat crcl crch
78
--       seq: _rxcmd _rxaddrl _rxaddrh
79
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
80
--            _rstart[bcmd:rblk] {_txdat}*
81
--            _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd
82 2 wfjm
--
83
--   001 read blk (rblk):
84 27 wfjm
--        rx: cmd al ah cl ch ccrcl ccrch
85
--        tx: cmd cnt dl dh ... dcl dch stat crcl crch
86
--       seq: _rxcmd _rxaddrl _rxaddrh _rxcntl _rxcnth
87
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
88
--            _txcntl _txcnth _rstart[bcmd:rblk] {_txdat}* _txdcntl _txdcnth
89
--            _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd
90 2 wfjm
--
91
--   010 write reg (wreg):
92 27 wfjm
--        rx: cmd al ah dl dh ccrcl ccrch
93
--        tx: cmd stat crcl crch
94
--       seq: _rxcmd _rxaddrl _rxaddrh _rxdatl _rxdath
95
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
96
--            _txcmd[bcmd:wblk] _wwait0
97
--            _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd
98 2 wfjm
--
99
--   011 write blk (wblk):
100 27 wfjm
--        rx: cmd al ah cnt ccrcl ccrch dl dh ... dcrcl dcrch
101
--        tx: cmd dcl dch stat crcl crch
102
--       seq: _rxcmd _rxaddrl _rxaddrh _rxcntl _rxcnth
103
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
104
--            _wblk {_rxwblk}* _rxdcrc[nak:dcrc,rtwblk]
105
--            _wblk0 _wblk1 _wblk2[bcmd:wblk] {_wblkl _wblkh}*
106
--            _wwait0 _wwait1 _txdcntl _txdcnth
107
--            _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd
108 2 wfjm
--
109 27 wfjm
--   100 list abort (labo):
110
--        rx: cmd ccrcl ccrch
111
--        tx: cmd babo stat crcl crch
112
--       seq: _rxcmd 
113
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
114
--            _txlabo
115
--            _txstat_txcrcl[nak:rtovfl] -> _txcrch -> [_rxcmd|_rxeop]
116 2 wfjm
--
117
--   101 read attn (attn):
118 27 wfjm
--        rx: cmd ccrcl ccrch
119
--        tx: cmd dl dh stat crcl crch
120
--       seq: _rxcmd
121
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd
122
--            _attn _txcntl _txcnth
123
--            _txstat _txcrcl[nak:rtovfl] -> _txcrch -> _rxcmd
124 2 wfjm
--
125
--   110 write init (init):
126 27 wfjm
--        rx: cmd al ah dl dh ccrcl ccrch
127
--        tx: cmd stat crcl crch
128
--       seq: _rxcmd _rxaddrl _rxaddrh _rxdatl _rxdath
129
--            _rxccrcl[nak:ccrc] _rxccrch[nak:ccrc] _txcmd[bcmd:init]
130
--            _txstat _txcrc[nak:rtovfl] -> _rxcmd
131 2 wfjm
--
132
--   111 is currently not a legal command and causes a nak
133
--       seq: _txnak
134
--
135
-- The different rbus cycle types are encoded as:
136
--
137 9 wfjm
--        init aval re we
138
--          0    0   0  0   idle
139 27 wfjm
--          0    1   1  0   read 
140
--          0    1   0  1   write
141
--          1    0   0  0   init
142 9 wfjm
--          0    0   1  0   not allowed
143
--          0    0   0  1   not allowed
144 27 wfjm
--          1    0   0  1   not allowed
145 9 wfjm
--          1    0   1  0   not allowed
146
--          *    *   1  1   not allowed
147
--          1    1   *  *   not allowed
148 2 wfjm
--
149
 
150
library ieee;
151
use ieee.std_logic_1164.all;
152 13 wfjm
use ieee.numeric_std.all;
153 2 wfjm
 
154
use work.slvtypes.all;
155 27 wfjm
use work.memlib.all;
156 2 wfjm
use work.comlib.all;
157 9 wfjm
use work.rblib.all;
158
use work.rlinklib.all;
159 2 wfjm
 
160 9 wfjm
entity rlink_core is                    -- rlink core with 9bit interface
161 2 wfjm
  generic (
162 27 wfjm
    BTOWIDTH : positive :=  5;          -- rbus timeout counter width
163
    RTAWIDTH : positive :=  12;         -- retransmit buffer address width
164
    SYSID : slv32 := (others=>'0');     -- rlink system id
165
    ENAPIN_RLMON : integer := -1;       -- SB_CNTL for rlmon  (-1=none)
166
    ENAPIN_RBMON : integer := -1);      -- SB_CNTL for rbmon  (-1=none)
167 2 wfjm
  port (
168
    CLK  : in slbit;                    -- clock      
169 27 wfjm
    CE_INT : in slbit := '0';           -- rri ato time unit clock enable
170 2 wfjm
    RESET  : in slbit;                  -- reset
171 9 wfjm
    RL_DI : in slv9;                    -- rlink 9b: data in
172
    RL_ENA : in slbit;                  -- rlink 9b: data enable
173
    RL_BUSY : out slbit;                -- rlink 9b: data busy
174
    RL_DO : out slv9;                   -- rlink 9b: data out
175
    RL_VAL : out slbit;                 -- rlink 9b: data valid
176
    RL_HOLD : in slbit;                 -- rlink 9b: data hold
177
    RL_MONI : out rl_moni_type;         -- rlink: monitor port
178 2 wfjm
    RB_MREQ : out rb_mreq_type;         -- rbus: request
179
    RB_SRES : in rb_sres_type;          -- rbus: response
180
    RB_LAM : in slv16;                  -- rbus: look at me
181 27 wfjm
    RB_STAT : in slv4                   -- rbus: status flags
182 2 wfjm
  );
183 27 wfjm
 
184
  attribute fsm_encoding : string;
185
  attribute fsm_encoding of rlink_core : entity is "one-hot";
186
 
187 9 wfjm
end entity rlink_core;
188 2 wfjm
 
189 9 wfjm
architecture syn of rlink_core is
190 28 wfjm
   -- core config registers (top 4 in rbus space)
191
  constant rbaddr : slv16 := x"fffc";    -- fffc/4: 1111 1111 1111 11xx
192 27 wfjm
  constant rbaddr_cntl : slv2 := "11";   -- cntl address offset
193
  constant rbaddr_stat : slv2 := "10";   -- stat address offset
194
  constant rbaddr_id1  : slv2 := "01";   -- id1  address offset
195
  constant rbaddr_id0  : slv2 := "00";   -- id0  address offset
196
 
197
  constant d_f_cflag   : integer := 8;                -- d9: comma flag
198
  subtype  d_f_ctyp   is integer range  2 downto  0;  -- d9: comma type
199
  subtype  d_f_data   is integer range  7 downto  0;  -- d9: data field
200
 
201
  subtype  f_byte1    is integer range 15 downto 8;
202
  subtype  f_byte0    is integer range  7 downto 0;
203
 
204
  constant cntl_rbf_anena    : integer := 15;               -- anena flag
205
  constant cntl_rbf_atoena   : integer := 14;               -- atoena flag
206
  subtype  cntl_rbf_atoval  is integer range  7 downto  0;  -- atoval value
207
  subtype  stat_rbf_lcmd    is integer range 15 downto  8;  -- lcmd
208
  constant stat_rbf_babo     : integer :=  7;               -- block abort flag
209
  constant stat_rbf_arpend   : integer :=  6;               -- attn read pend
210
  subtype  stat_rbf_rbsize  is integer range  2 downto  0;  -- rbuf size
211
 
212
  -- following 4 constants can derived from c_rlink_dat_sop,...
213
  -- defined directly here to work around a ghdl bug
214
  constant c_sop  : slv3 := "000";
215
  constant c_eop  : slv3 := "001";
216
  constant c_nak  : slv3 := "010";
217
  constant c_attn : slv3 := "011";
218
 
219
  constant c_bcmd_stat : slv2 := "00";
220
  constant c_bcmd_init : slv2 := "01";
221
  constant c_bcmd_rblk : slv2 := "10";
222
  constant c_bcmd_wblk : slv2 := "11";
223
 
224
  constant cntawidth : positive := RTAWIDTH-1;        -- cnt is word count
225
  subtype  cnt_f_dat  is integer range cntawidth-1 downto  0;   -- cnt data
226
 
227
  -- link FSM states and state vector ----------------------------------------
228
  type lstate_type is (
229
    sl_idle,                            -- sl_idle: wait for sop
230
    sl_txanot,                          -- sl_txanot: send attn notify
231
    sl_txsop,                           -- sl_txsop: send sop
232
    sl_txnak,                           -- sl_txnak: send nak
233
    sl_txnakcode,                       -- sl_txnakcode: send nakcode
234
    sl_txrtbuf,                         -- sl_txrtbuf: send rtbuf
235
    sl_txeop,                           -- sl_txeop: send eop
236
    sl_rxeop,                           -- sl_rxeop: wait for eop
237
    sl_rxcmd,                           -- sl_rxcmd: wait for cmd
238
    sl_rxaddrl,                         -- sl_rxaddrl: wait for addr low
239
    sl_rxaddrh,                         -- sl_rxaddrh: wait for addr high
240
    sl_rxdatl,                          -- sl_rxdatl: wait for data low
241
    sl_rxdath,                          -- sl_rxdath: wait for data high
242
    sl_rxcntl,                          -- sl_rxcntl: wait for count low
243
    sl_rxcnth,                          -- sl_rxcnth: wait for count low
244
    sl_rxccrcl,                         -- sl_rxccrcl: wait for command crc low
245
    sl_rxccrch,                         -- sl_rxccrcl: wait for command crc high
246
    sl_txcmd,                           -- sl_txcmd: send cmd
247
    sl_txcntl,                          -- sl_txcntl: send cnt lsb
248
    sl_txcnth,                          -- sl_txcnth: send cnt msb
249
    sl_rstart,                          -- sl_rstart: start rreg or rblk
250
    sl_txdat,                           -- sl_txdat: send data
251
    sl_wblk,                            -- sl_wblk: setup rx wblk data
252
    sl_rxwblk,                          -- sl_rxwblk: wait for wblk data
253
    sl_rxdcrcl,                         -- sl_rxdcrcl: wait for data crc low
254
    sl_rxdcrch,                         -- sl_rxdcrch: wait for data crc high
255
    sl_wblk0,                           -- sl_wblk0: start wblk pipe
256
    sl_wblk1,                           -- sl_wblk1: start wblk data lsb
257
    sl_wblk2,                           -- sl_wblk2: start wblk data msb
258
    sl_wblkl,                           -- sl_wblkl: wblk data lsb
259
    sl_wblkh,                           -- sl_wblkh: wblk data msb
260
    sl_wwait0,                          -- sl_wwait0: wait for wdone
261
    sl_wwait1,                          -- sl_wwait1: wait for dcnt
262
    sl_txdcntl,                         -- sl_txdcntl: send dcnt lsb
263
    sl_txdcnth,                         -- sl_txdcnth: send dcnt lsb
264
    sl_txlabo,                          -- sl_txlabo: send labo flag
265
    sl_attn,                            -- sl_attn: handle attention flags
266
    sl_txstat,                          -- sl_txstat: send status
267
    sl_txcrcl,                          -- sl_txcrcl: send crc low
268
    sl_txcrch                           -- sl_txcrch: send crc high
269 2 wfjm
  );
270
 
271 27 wfjm
  type lregs_type is record
272
    state : lstate_type;                -- state
273 2 wfjm
    rcmd : slv8;                        -- received command
274 27 wfjm
    lcmd : slv8;                        -- last command
275
    addr : slv16;                       -- rbus register address
276
    din : slv16;                        -- rbus input data
277
    cnt : slv16;                        -- block transfer count
278
    bcnt : slv(RTAWIDTH-1 downto 0);    -- blk counter (byte and word)
279 2 wfjm
    attn : slv16;                       -- attn mask
280 27 wfjm
    anreq : slbit;                      -- attn notify request
281
    anact : slbit;                      -- attn notify active
282
    arpend : slbit;                     -- attn read pending
283
    atocnt : slv8;                      -- attn timeout counter
284
    babo : slbit;                       -- last blk aborted
285
    nakdone : slbit;                    -- nak done
286
    nakcode : slv3;                     -- nak code
287
    cmdseen : slbit;                    -- 1st command seen
288
    doretra : slbit;                    -- do a retransmit
289
    dinl : slv8;                        -- din lsb for wblk pipeline
290
    rtaddra : slv(RTAWIDTH-1 downto 0); -- rtbuf port a addr (write pointer)
291
    rtaddra_red : slbit;                -- rtaddra red (at max)
292
    rtaddra_bad : slbit;                -- rtaddra bad (inc beyond max)
293
    rtaddrb : slv(RTAWIDTH-1 downto 0); -- rtbuf port b addr (aux pointer)
294
    rtaddrb_red : slbit;                -- rtaddrb red (at max)
295
    rtaddrb_bad : slbit;                -- rtaddrb bad (inc beyond max)
296 9 wfjm
    moneop : slbit;                     -- rl_moni: eop send pulse
297
    monattn : slbit;                    -- rl_moni: attn send pulse
298 27 wfjm
  end record lregs_type;
299 2 wfjm
 
300 27 wfjm
  constant bcnt_zero   : slv(RTAWIDTH-1 downto 0) := (others=>'0');
301
  constant rtaddr_zero : slv(RTAWIDTH-1 downto 0) := (others=>'0');
302
  constant rtaddr_tred : slv(RTAWIDTH-1 downto 0) := (0=>'0', others=>'1');
303 2 wfjm
 
304 27 wfjm
  constant lregs_init : lregs_type := (
305
    sl_idle,                            -- state
306 2 wfjm
    (others=>'0'),                      -- rcmd
307 27 wfjm
    (others=>'1'),                      -- lcmd
308 2 wfjm
    (others=>'0'),                      -- addr
309 27 wfjm
    (others=>'0'),                      -- din
310 2 wfjm
    (others=>'0'),                      -- cnt
311 27 wfjm
    bcnt_zero,                          -- bcnt
312 2 wfjm
    (others=>'0'),                      -- attn
313 27 wfjm
    '0','0','0',                        -- anreq,anact,arpend
314
    (others=>'0'),                      -- atocnt
315
    '0',                                -- babo
316
    '0',                                -- nakdone
317
    (others=>'0'),                      -- nakcode
318
    '0','0',                            -- cmdseen,doretra
319
    (others=>'0'),                      -- dinl
320
    rtaddr_zero,                        -- rtaddra
321
    '0','0',                            -- rtaddra_red, rtaddra_bad
322
    rtaddr_zero,                        -- rtaddrb
323
    '0','0',                            -- rtaddrb_red, rtaddrb_bad
324
    '0','0'                             -- moneop,monattn
325
  );
326
 
327
  -- bus FSM states and state vector -----------------------------------------
328
  type bstate_type is (
329
    sb_idle,                            -- sb_idle: wait for cmd
330
    sb_rstart,                          -- sb_rstart: start rblk
331
    sb_rreg0,                           -- sb_rreg0: rbus read cycle
332
    sb_rreg1,                           -- sb_rreg1: send read data
333
    sb_rwait,                           -- sb_rwait: wait for fifo
334
    sb_rend,                            -- sb_rend: send last read data
335
    sb_rabo0,                           -- sb_rabo0: rblk abort, lsb data
336
    sb_rabo1,                           -- sb_rabo1: rblk abort, msb data
337
    sb_wstart,                          -- sb_wstart: start wblk
338
    sb_wreg0,                           -- sb_wreg0: rbus write cycle
339
    sb_wreg1,                           -- sb_wreg1: wait write data
340
    sb_wabo0,                           -- sb_wabo0: wblk abort, drop data
341
    sb_wabo1                            -- sb_wabo1: wblk abort, wait
342
  );
343
 
344
  type bregs_type is record
345
    state : bstate_type;                -- state
346
    rbinit : slbit;                     -- rbus init signal
347
    rbaval : slbit;                     -- rbus aval signal
348
    rbre : slbit;                       -- rbus re signal
349
    rbwe : slbit;                       -- rbus we signal
350
    rbdout : slv16;                     -- rbus dout
351 28 wfjm
    rbtout: slbit;                      -- rbus timeout
352
    rbnak: slbit;                       -- rbus no ack
353 27 wfjm
    rberr : slbit;                      -- rbus err bit set
354
    blkabo : slbit;                     -- blk abort
355
    cnt : slv(cntawidth-1 downto 0);    -- word count for rblk and wblk
356
    dcnt : slv(cntawidth-1 downto 0);   -- done count for rblk and wblk
357
    btocnt : slv(BTOWIDTH-1 downto 0);  -- rbus timeout counter
358
    dathpend : slbit;                   -- dat msb pending
359
    wfifo : slbit;                      -- wait for fifo
360
    stat : slv4;                        -- external status flags
361
  end record bregs_type;
362
 
363
  constant btocnt_init : slv(BTOWIDTH-1 downto 0) := (others=>'1');
364
  constant cnt_zero    : slv(cntawidth-1 downto 0) := (others=>'0');
365
 
366
  constant bregs_init : bregs_type := (
367
    sb_idle,                            -- state
368 9 wfjm
    '0','0','0','0',                    -- rbinit,rbaval,rbre,rbwe
369 27 wfjm
    (others=>'0'),                      -- rbdout
370 28 wfjm
    '0','0','0',                        -- rbtout,rbnak,rberr
371 27 wfjm
    '0',                                -- blkabo
372
    cnt_zero,                           -- cnt
373
    cnt_zero,                           -- dcnt
374
    btocnt_init,                        -- btocnt
375
    '0','0',                            -- dathpend,wfifo
376 2 wfjm
    (others=>'0')                       -- stat
377
  );
378
 
379 27 wfjm
  -- config state regs --------------------------------------------------------
380
  type cregs_type is record
381
    anena : slbit;                      -- attn notification enable flag
382
    atoena : slbit;                     -- attn timeout enable flag
383
    atoval : slv8;                      -- attn timeout value
384
  end record cregs_type;
385
 
386
  constant cregs_init : cregs_type := (
387
    '0','0',                            -- anena,atoena
388
    (others=>'0')                       -- atoval
389
  );
390 2 wfjm
 
391 27 wfjm
  signal R_LREGS : lregs_type := lregs_init;  -- state registers link FSM
392
  signal N_LREGS : lregs_type := lregs_init;  -- next value state regs link FSM
393
  signal R_BREGS : bregs_type := bregs_init;  -- state registers bus FSM
394
  signal N_BREGS : bregs_type := bregs_init;  -- next value state regs bus FSM
395
  signal R_CREGS : cregs_type := cregs_init;  -- state registers config
396
  signal N_CREGS : cregs_type := cregs_init;  -- next value state regs config
397
 
398
  signal RTBUF_ENB : slbit := '0';
399
  signal RTBUF_WEA : slbit := '0';
400
  signal RTBUF_WEB : slbit := '0';
401
  signal RTBUF_DIA : slv8 := (others=>'0');
402
  signal RTBUF_DIB : slv8 := (others=>'0');
403
  signal RTBUF_DOB : slv8 := (others=>'0');
404
 
405
  signal DOFIFO_DI   : slv8  := (others=>'0');
406
  signal DOFIFO_ENA  : slbit := '0';
407
  signal DOFIFO_DO   : slv8  := (others=>'0');
408
  signal DOFIFO_VAL  : slbit := '0';
409
  signal DOFIFO_HOLD : slbit := '0';
410
  signal DOFIFO_SIZE : slv6  := (others=>'0');
411
 
412 2 wfjm
  signal CRC_RESET : slbit := '0';
413 27 wfjm
  signal ICRC_ENA  : slbit := '0';
414
  signal OCRC_ENA  : slbit := '0';
415
  signal ICRC_OUT  : slv16 := (others=>'0');
416
  signal OCRC_OUT  : slv16 := (others=>'0');
417
  signal OCRC_IN   : slv8  := (others=>'0');
418 2 wfjm
 
419 27 wfjm
  signal RBSEL : slbit := '0';
420
 
421 34 wfjm
  signal RB_MREQ_L     : rb_mreq_type := rb_mreq_init;  -- internal mreq
422
  signal RB_SRES_CLEAN : rb_sres_type := rb_sres_init;  -- cleaned rb_sres
423
  signal RB_SRES_CONF  : rb_sres_type := rb_sres_init;  -- config sres
424
  signal RB_SRES_TOT   : rb_sres_type := rb_sres_init;  -- total  sres
425 27 wfjm
 
426
  signal RL_BUSY_L : slbit := '0';
427
  signal RL_DO_L   : slv9  := (others=>'0');
428
  signal RL_VAL_L  : slbit := '0';
429
 
430
  signal L2B_GO    : slbit := '0';
431
  signal L2B_CMD  : slv2 := (others=>'0');
432
  signal B2L_WDONE : slbit := '0';
433
 
434 2 wfjm
begin
435
 
436 27 wfjm
  -- allow 11 bit (1 x 18kbit BRAM) to 15 bit (8 x 36 kbit BRAMs)
437
  assert RTAWIDTH>=11 and RTAWIDTH<=14
438
    report "assert(RTAWIDTH>=11 and RTAWIDTH<=15): unsupported RTAWIDTH"
439 2 wfjm
    severity failure;
440 27 wfjm
 
441
  RTBUF : ram_2swsr_rfirst_gen
442
    generic map (
443
      AWIDTH => RTAWIDTH,
444
      DWIDTH =>  8)
445
    port map (
446
      CLKA  => CLK,
447
      CLKB  => CLK,
448
      ENA   => RTBUF_WEA,               -- port A write only, thus en=we
449
      ENB   => RTBUF_ENB,
450
      WEA   => RTBUF_WEA,
451
      WEB   => RTBUF_WEB,
452
      ADDRA => R_LREGS.rtaddra,
453
      ADDRB => R_LREGS.rtaddrb,
454
      DIA   => RTBUF_DIA,
455
      DIB   => RTBUF_DIB,
456
      DOA   => open,
457
      DOB   => RTBUF_DOB
458
      );
459
 
460
  DOFIFO : fifo_1c_dram
461
    generic map (
462
      AWIDTH => 5,
463
      DWIDTH => 8)
464
    port map (
465
      CLK   => CLK,
466
      RESET => RESET,
467
      DI    => DOFIFO_DI,
468
      ENA   => DOFIFO_ENA,
469
      BUSY  => open,
470
      DO    => DOFIFO_DO,
471
      VAL   => DOFIFO_VAL,
472
      HOLD  => DOFIFO_HOLD,
473
      SIZE  => DOFIFO_SIZE
474
    );
475 2 wfjm
 
476 27 wfjm
  ICRC : crc16                          -- crc generator for input data
477
    port map (
478
      CLK   => CLK,
479
      RESET => CRC_RESET,
480
      ENA   => ICRC_ENA,
481
      DI    => RL_DI(d_f_data),
482
      CRC   => ICRC_OUT
483
    );
484 2 wfjm
 
485 27 wfjm
  OCRC : crc16                          -- crc generator for output data
486
    port map (
487
      CLK   => CLK,
488
      RESET => CRC_RESET,
489
      ENA   => OCRC_ENA,
490
      DI    => OCRC_IN,
491
      CRC   => OCRC_OUT
492
    );
493 2 wfjm
 
494 27 wfjm
  SEL : rb_sel                          -- rbus address select for config regs
495
    generic map (
496
      RB_ADDR => rbaddr,
497
      SAWIDTH => 2)
498
    port map (
499
      CLK     => CLK,
500
      RB_MREQ => RB_MREQ_L,
501
      SEL     => RBSEL
502
    );
503
 
504
  RB_SRES_OR : rb_sres_or_2
505
    port map (
506 34 wfjm
      RB_SRES_1  => RB_SRES_CLEAN,
507 27 wfjm
      RB_SRES_2  => RB_SRES_CONF,
508
      RB_SRES_OR => RB_SRES_TOT
509
    );
510
 
511 34 wfjm
  proc_sres: process (RB_SRES)
512
    variable sres : rb_sres_type := rb_sres_init;
513
    variable datax01 : slv16 := (others=>'0');
514
    variable data01  : slv16 := (others=>'0');
515
  begin
516
    sres.ack  := to_x01(RB_SRES.ack);
517
    sres.busy := to_x01(RB_SRES.busy);
518
    sres.err  := to_x01(RB_SRES.err);
519
    sres.dout := to_x01(RB_SRES.dout);
520
 
521
    if sres.ack = '1' and sres.busy = '0' and is_x(sres.dout) then
522
      assert false
523
        report "rlink_core: seen 'x' in rb_sres.data"
524
        severity warning;
525
      sres.dout := (others=>'1');
526
    end if;
527
 
528
    RB_SRES_CLEAN <= sres;
529
  end process proc_sres;
530
 
531 2 wfjm
  proc_regs: process (CLK)
532
  begin
533
 
534 13 wfjm
    if rising_edge(CLK) then
535 2 wfjm
      if RESET = '1' then
536 27 wfjm
        R_LREGS <= lregs_init;
537
        R_BREGS <= bregs_init;
538
        R_CREGS <= cregs_init;
539 2 wfjm
      else
540 27 wfjm
        R_LREGS <= N_LREGS;
541
        R_BREGS <= N_BREGS;
542
        R_CREGS <= N_CREGS;
543
     end if;
544 2 wfjm
    end if;
545
 
546
  end process proc_regs;
547
 
548 27 wfjm
  -- link FSM ================================================================
549 2 wfjm
 
550 27 wfjm
  proc_lnext: process (R_LREGS, R_CREGS, R_BREGS,
551
                       CE_INT, RL_DI, RL_ENA, RL_HOLD, RB_LAM,
552
                       ICRC_OUT, OCRC_OUT, RTBUF_DOB,
553
                       DOFIFO_DO, DOFIFO_VAL,
554
                       B2L_WDONE)
555 2 wfjm
 
556 27 wfjm
    variable r : lregs_type := lregs_init;
557
    variable n : lregs_type := lregs_init;
558
 
559 2 wfjm
    variable ival : slbit := '0';
560
    variable ibusy : slbit := '0';
561
    variable ido : slv9 := (others=>'0');
562
    variable crcreset : slbit := '0';
563
    variable icrcena : slbit := '0';
564
    variable ocrcena : slbit := '0';
565
    variable has_attn : slbit := '0';
566
    variable idi8 : slv8 := (others=>'0');
567
    variable is_comma : slbit := '0';
568 27 wfjm
    variable comma_typ : slv3 := "000";
569
    variable idohold : slbit := '0';
570
    variable cnt_iszero : slbit := '0';
571
    variable bcnt_load : slbit := '0';
572
    variable bcnt_val : slv(RTAWIDTH-1 downto 0) := (others=>'0');
573
    variable bcnt_dec : slbit := '0';
574
    variable bcnt_end : slbit := '0';
575
    variable irtwea : slbit := '0';
576
    variable irtreb : slbit := '0';
577
    variable irtweb : slbit := '0';
578
    variable addra_clear : slbit := '0';
579
    variable addrb_load  : slbit := '0';
580
    variable addrb_sela  : slbit := '0';
581
    variable ibcmd : slv2 := (others=>'0');
582
    variable ibgo  : slbit := '0';
583 2 wfjm
 
584
  begin
585
 
586 27 wfjm
    r := R_LREGS;
587
    n := R_LREGS;
588 2 wfjm
 
589 9 wfjm
    n.moneop  := '0';                   -- default '0', only set by states
590
    n.monattn := '0';                   -- "
591 2 wfjm
 
592 27 wfjm
    ival := '0';
593 2 wfjm
    ibusy := '1';                       -- default is to hold input
594
    ido  := (others=>'0');
595
 
596
    crcreset := '0';
597
    icrcena  := '0';
598
    ocrcena  := '0';
599
 
600
    has_attn := '0';
601 27 wfjm
 
602
    is_comma  := RL_DI(d_f_cflag);      -- get comma marker
603
    comma_typ := RL_DI(d_f_ctyp);       -- get comma type
604
    idi8      := RL_DI(d_f_data);       -- get data part of RL_DI
605
 
606
    idohold := '1';                     -- default is to hold DOFIFO
607
 
608
    cnt_iszero := '0';
609
    if unsigned(r.cnt(cnt_f_dat)) = 0 then
610
      cnt_iszero := '1';
611
    end if;
612 9 wfjm
 
613 27 wfjm
    bcnt_load := '0';
614
    bcnt_val  := r.cnt(cnt_f_dat) & '0'; -- default: 2*cnt (most used)
615
    bcnt_dec  := '0';
616
    bcnt_end  := '0';
617
    if unsigned(r.bcnt) = 1 then
618
      bcnt_end := '1';
619
    end if;
620
 
621
    irtwea  := '0';
622
    irtreb  := '0';
623
    irtweb  := '0';
624
    addra_clear := '0';
625
    addrb_load  := '0';
626
    addrb_sela  := '1';           -- default: addra (most used)
627
 
628
    ibcmd := (others=>'0');
629
    ibgo := '0';
630
 
631
    -- handle attention "LAM's"
632
    n.attn := r.attn or RB_LAM;
633
 
634
    -- detect attn notify requests
635
    if unsigned(r.attn) /= 0 then       -- if any of the attn bits set
636 9 wfjm
      has_attn  := '1';
637 27 wfjm
      if R_CREGS.anena='1' and r.arpend='0' then -- if attn to be send
638
        n.anreq := '1';                      -- set notify request flag
639 9 wfjm
      end if;
640 2 wfjm
    end if;
641 9 wfjm
 
642 27 wfjm
    -- handle attn read timeouts
643
    --  atocnt is held in reset when no attn read is pending
644
    --    counting down in CE_INT cycles till zero
645
    --    when zero, an attn notify is requested when atoena is set
646
    --    the attn notify flag will reset atocnt to its start value
647
    --    --> when atoena='1' this creates a notify every atoval CE_INT periods
648
    --    --> when atoena='0' atocnt will count to zero and stay there
649 2 wfjm
 
650 27 wfjm
    if r.arpend = '0' or r.anreq = '1' then   -- if no attn read pending
651
      n.atocnt := R_CREGS.atoval;         -- keep at start value
652
    else                                -- otherwise
653
      if CE_INT = '1' then                -- if CE_INT
654
        if unsigned(r.atocnt) = 0 then      -- alread counted down 
655
          n.anreq :=  R_CREGS.atoena;         -- request attn notify if enabled
656
        else                                -- not yet down
657
          n.atocnt := slv(unsigned(r.atocnt) - 1);  -- decrement
658
        end if;
659
      end if;
660 2 wfjm
    end if;
661
 
662
    case r.state is
663 27 wfjm
 
664
      when sl_idle =>                   -- sl_idle: wait for sop -------------
665
        bcnt_val := r.rtaddra;            -- used for nak handling
666
        addrb_sela := '0';
667
        n.anact    := '0';
668
        n.doretra := '0';
669
        crcreset := '1';                  -- reset crc generators
670
        if r.anreq = '1' then             -- if attn notify requested
671
          n.anreq  := '0';                  -- acknowledge request
672
          n.arpend := '1';                  -- mark attn read pending
673
          n.state := sl_txanot;             -- next: send attn notify
674 2 wfjm
        else
675
          ibusy := '0';                   -- accept input
676 9 wfjm
          if RL_ENA = '1' then            -- if input
677 2 wfjm
            if is_comma = '1' then          -- if comma
678
              case comma_typ is
679
                when c_sop =>                 -- if sop
680 27 wfjm
                  n.cmdseen := '0';             -- clear cmd seen flag
681
                  n.state := sl_txsop;          -- next: echo it
682 2 wfjm
                when c_attn =>                -- if attn
683 27 wfjm
                  n.state := sl_txanot;         -- next: send attn notify
684
                when c_nak =>
685
                  addrb_load := '1';
686
                  bcnt_load  := '1';
687
                  n.doretra  := '1';
688
                  n.state := sl_txsop;          -- next: send sop
689 2 wfjm
                when others => null;          -- other commas: silently ignore
690 27 wfjm
                                                -- especially: eop is ignored
691 2 wfjm
              end case;
692
            else                             -- if normal data
693 27 wfjm
              n.state := sl_idle;              -- silently dropped
694 2 wfjm
            end if;
695
          end if;
696
        end if;
697 27 wfjm
 
698
      when sl_txanot =>                 -- sl_txanot: send attn notify -------
699
        n.cnt := r.attn;                  -- transfer attn to cnt for transmit
700
        n.anact := '1';                   -- signal attn notify active 
701
        ido  := c_rlink_dat_attn;         -- send attn symbol
702 2 wfjm
        ival := '1';
703 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
704 27 wfjm
          n.monattn := '1';                 -- signal on rl_moni
705
          n.state := sl_txcntl;             -- next: send cnt lsb
706 2 wfjm
        end if;
707
 
708 27 wfjm
      when sl_txsop =>                  -- sl_txsop: send sop ----------------
709 9 wfjm
        ido := c_rlink_dat_sop;           -- send sop character
710 2 wfjm
        ival := '1';
711 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
712 27 wfjm
          if r.doretra = '1' then           -- if retra request
713
            irtreb := '1';                    -- request first byte
714
            n.state := sl_txrtbuf;            -- next: send rtbuf
715
          else                              -- or normal command
716
            n.state := sl_rxcmd;              -- next: read first command
717
          end if;
718 2 wfjm
        end if;
719
 
720 27 wfjm
      when sl_txnak =>                  -- sl_txnak: send nak ----------------
721
        n.nakdone := '1';                 -- set nakdone flag
722 9 wfjm
        ido := c_rlink_dat_nak;           -- send nak character
723 2 wfjm
        ival := '1';
724 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
725 27 wfjm
          n.state := sl_txnakcode;          -- next: send nakcode
726 2 wfjm
        end if;
727
 
728 27 wfjm
      when sl_txnakcode =>              -- sl_txnakcode: send nakcode --------
729
        ido := '0' & "10" & (not r.nakcode) & r.nakcode;
730 2 wfjm
        ival := '1';
731 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
732 27 wfjm
          n.state := sl_rxeop;            -- next: wait for eop
733 2 wfjm
        end if;
734
 
735 27 wfjm
      when sl_rxeop =>                  -- sl_rxeop: wait for eop ------------
736 2 wfjm
        ibusy := '0';                     -- accept input
737 9 wfjm
        if RL_ENA = '1' then
738 27 wfjm
          if is_comma = '1' and comma_typ = c_eop then  -- if eop seen
739
            n.state  := sl_txeop;          -- next: echo eop
740 2 wfjm
          end if;
741
        end if;
742
 
743 27 wfjm
      when sl_txrtbuf =>                -- sl_txrtbuf: send rtbuf ------------
744
        ido := '0' & RTBUF_DOB;           -- send rtbuf data
745
        ival := '1';
746
        if RL_HOLD = '0' then             -- wait for accept
747
          bcnt_dec := '1';
748
          if bcnt_end = '0' then            -- if not yet done
749
            irtreb := '1';                    -- request next byte
750
          else                              -- all done
751
            if r.nakdone = '0' then         -- if no nak active
752
              n.state := sl_txeop;              -- next: send eop
753
            else
754
              n.state := sl_txnak;              -- next: send nak
755
            end if;
756
          end if;
757
        end if;
758
 
759
      when sl_txeop =>                  -- sl_txeop: send eop ----------------
760
        ido := c_rlink_dat_eop;           -- send eop character
761
        ival := '1';
762
        if RL_HOLD = '0' then             -- wait for accept
763
          n.moneop := '1';                  -- signal on rl_moni
764
          n.state := sl_idle;               -- next: idle state, wait for sop
765
        end if;
766
 
767
       when sl_rxcmd =>                  -- sl_rxcmd: wait for cmd ------------
768
        ibusy := '0';                      -- accept input
769
        n.cnt := slv(to_unsigned(1,16));   -- preset cnt=1 (used for rreg)
770
        n.rcmd := idi8;                    -- latch cmd (follow till valid)
771 9 wfjm
        if RL_ENA = '1' then
772 2 wfjm
          if is_comma = '1' then          -- if comma
773 27 wfjm
            if comma_typ = c_eop then       -- eop seen
774
              n.state  := sl_txeop;           -- next: echo eop
775
            else                            -- any other comma seen
776
              n.nakcode := c_rlink_nakcode_frame; -- signal framing error
777
              n.state  := sl_txnak;         -- next: send nak
778
            end if;
779 9 wfjm
          else                            -- if not comma
780 27 wfjm
            if r.cmdseen = '0' then         -- if first cmd
781
              n.nakdone := '0';               -- clear nakdone flag
782
              addra_clear := '1';             -- clear rtbuf
783
            end if;
784
            n.cmdseen := '1';               -- set cmd seen flag
785 9 wfjm
            icrcena   := '1';               -- update input crc
786
            case RL_DI(c_rlink_cmd_rbf_code) is
787
              when c_rlink_cmd_rreg |
788
                   c_rlink_cmd_rblk |
789
                   c_rlink_cmd_wreg |
790
                   c_rlink_cmd_wblk |
791
                   c_rlink_cmd_init =>      -- for commands needing addr(data)
792 27 wfjm
                n.state := sl_rxaddrl;        -- next: read address lsb
793
              when c_rlink_cmd_labo |
794
                   c_rlink_cmd_attn =>      -- labo and attn commands
795
                n.state := sl_rxccrcl;        -- next: read command crc low
796 2 wfjm
              when others =>
797 27 wfjm
                n.nakcode := c_rlink_nakcode_cmd; -- signal bad cmd
798
                n.state := sl_txnak;          -- next: send nak
799
            end case;
800 2 wfjm
          end if;
801
        end if;
802 27 wfjm
 
803
      when sl_rxaddrl =>                -- sl_rxaddrl: wait for addr lsb -----
804 2 wfjm
        ibusy := '0';                     -- accept input
805 27 wfjm
        n.addr(f_byte0) := idi8;          -- latch addr lsb (follow till valid)
806 9 wfjm
        if RL_ENA = '1' then
807 27 wfjm
          if is_comma = '1' then          -- if comma 
808
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
809
            n.state   := sl_txnak;          -- next: send nak,
810
         else
811
            icrcena  := '1';              -- update input crc
812
            n.state := sl_rxaddrh;          -- next: read addr msb
813
          end if;
814
        end if;
815
 
816
      when sl_rxaddrh =>                -- sl_rxaddrh: wait for addr msb -----
817
        ibusy := '0';                     -- accept input
818
        n.addr(f_byte1) := idi8;          -- latch addr msb (follow till valid)
819
        if RL_ENA = '1' then
820 2 wfjm
          if is_comma = '1' then          -- if comma
821 27 wfjm
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
822
            n.state   := sl_txnak;          -- next: send nak
823 2 wfjm
          else
824
            icrcena  := '1';              -- update input crc
825 9 wfjm
            case r.rcmd(c_rlink_cmd_rbf_code) is
826
              when c_rlink_cmd_rreg =>      -- for rreg command
827 27 wfjm
                n.state := sl_rxccrcl;        -- next: read command crc low
828 9 wfjm
              when c_rlink_cmd_wreg |
829
                   c_rlink_cmd_init =>      -- for wreg, init command
830 27 wfjm
                n.state := sl_rxdatl;         -- next: read data lsb
831 9 wfjm
              when others =>                -- for rblk or wblk
832 27 wfjm
                n.state := sl_rxcntl;         -- next: read count lsb
833 2 wfjm
            end case;
834
          end if;
835
        end if;
836
 
837 27 wfjm
      when sl_rxdatl =>                 -- sl_rxdatl: wait for data low ------
838 2 wfjm
        ibusy := '0';                     -- accept input
839 27 wfjm
        n.din(f_byte0) := idi8;           -- latch data lsb (follow till valid)
840 9 wfjm
        if RL_ENA = '1' then
841 2 wfjm
          if is_comma = '1' then          -- if comma 
842 27 wfjm
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
843
            n.state   := sl_txnak;          -- next: send nak
844 2 wfjm
         else
845
            icrcena  := '1';              -- update input crc
846 27 wfjm
            n.state := sl_rxdath;         -- next: read data msb
847 2 wfjm
          end if;
848
        end if;
849 27 wfjm
 
850
      when sl_rxdath =>                 -- sl_rxdath: wait for data high -----
851 2 wfjm
        ibusy := '0';                     -- accept input
852 27 wfjm
        n.din(f_byte1) := idi8;           -- latch data msb (follow till valid)
853 9 wfjm
        if RL_ENA = '1' then
854 2 wfjm
          if is_comma = '1' then          -- if comma
855 27 wfjm
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
856
            n.state   := sl_txnak;          -- next: send nak
857 2 wfjm
          else
858
            icrcena  := '1';              -- update input crc
859 27 wfjm
            n.state := sl_rxccrcl;        -- next: read command crc low
860 2 wfjm
          end if;
861 27 wfjm
        end if;
862
 
863
      when sl_rxcntl =>                 -- sl_rxcntl: wait for count lsb -----
864
        ibusy := '0';                     -- accept input
865
        n.cnt(f_byte0) := idi8;           -- latch count lsb (follow till valid)
866
        if RL_ENA = '1' then
867
          if is_comma = '1' then            -- if comma
868
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
869
            n.state   := sl_txnak;            -- next: send nak
870
          else
871
            icrcena  := '1';              -- update input crc
872
            n.state := sl_rxcnth;         -- next: read count msb
873
          end if;
874 2 wfjm
        end if;
875 27 wfjm
 
876
      when sl_rxcnth =>                 -- sl_rxcnth: wait for count msb -----
877 2 wfjm
        ibusy := '0';                     -- accept input
878 27 wfjm
        n.cnt(f_byte1) := idi8;           -- latch count lsb (follow till valid)
879 9 wfjm
        if RL_ENA = '1' then
880 2 wfjm
          if is_comma = '1' then            -- if comma
881 27 wfjm
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
882
            n.state   := sl_txnak;            -- next: send nak
883 2 wfjm
          else
884
            icrcena  := '1';              -- update input crc
885 27 wfjm
            if unsigned(idi8(7 downto cntawidth-8)) = 0 then  -- if cnt ok
886
              n.state := sl_rxccrcl;        -- next: read command crc low
887
            else
888
              n.nakcode := c_rlink_nakcode_cnt; -- signal bad cnt
889
              n.state := sl_txnak;              -- next: send nak
890
            end if;
891 2 wfjm
          end if;
892 27 wfjm
        end if;
893 2 wfjm
 
894 27 wfjm
      when sl_rxccrcl =>                -- sl_rxccrcl: wait for command crc low
895 2 wfjm
        ibusy := '0';                     -- accept input
896 9 wfjm
        if RL_ENA = '1' then
897 2 wfjm
          if is_comma = '1' then            -- if comma
898 27 wfjm
            n.nakcode := c_rlink_nakcode_frame;  -- signal framing error
899
            n.state   := sl_txnak;               -- next: send nak
900 2 wfjm
          else
901 27 wfjm
            if idi8 /= ICRC_OUT(f_byte0) then    -- if crc error (lsb)
902
              n.nakcode := c_rlink_nakcode_ccrc; -- signal bad ccrc
903
              n.state := sl_txnak;            -- next: send nak
904 2 wfjm
            else                            -- if crc ok
905 27 wfjm
              n.state := sl_rxccrch;          -- next: wait for command crc high
906 2 wfjm
            end if;
907
          end if;
908
        end if;
909
 
910 27 wfjm
      when sl_rxccrch =>                -- sl_rxccrcl: wait for command crc high
911
        ibusy := '0';                     -- accept input
912
        if RL_ENA = '1' then
913
          if is_comma = '1' then            -- if comma
914
            n.nakcode := c_rlink_nakcode_frame;  -- signal framing error
915
            n.state   := sl_txnak;               -- next: send nak
916
          else
917
            if idi8 /= ICRC_OUT(f_byte1) then   -- if crc error (msb)
918
              n.nakcode := c_rlink_nakcode_ccrc; -- signal bad ccrc
919
              n.state := sl_txnak;            -- next: send nak
920
            else                            -- if crc ok
921
              n.state := sl_txcmd;            -- next: echo command
922
            end if;
923
          end if;
924
        end if;
925
 
926
      when sl_txcmd =>                  -- sl_txcmd: send cmd -----------------
927 2 wfjm
        ido := '0' & r.rcmd;              -- send read command
928
        ival := '1';
929 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
930 27 wfjm
          irtwea  := '1';
931
          ocrcena := '1';                  -- update output crc
932
          ibcmd   := c_bcmd_stat;          -- latch external status bits
933
          ibgo    := '1';
934 9 wfjm
 
935
          case r.rcmd(c_rlink_cmd_rbf_code) is -- main command dispatcher
936
            when c_rlink_cmd_rreg  =>          -- rreg ----------------
937 27 wfjm
              n.state := sl_rstart;              -- next: start rreg
938 9 wfjm
            when c_rlink_cmd_rblk =>           -- rblk ----------------
939 27 wfjm
              n.babo := '0';                    -- clear babo flag
940
              n.state := sl_txcntl;
941 9 wfjm
            when c_rlink_cmd_wreg =>           -- wreg ----------------
942 27 wfjm
              ibcmd := c_bcmd_wblk;
943
              ibgo  := '1';
944
              n.state := sl_wwait0;              -- next: wait for wdone
945 9 wfjm
            when c_rlink_cmd_wblk =>           -- wblk ----------------
946 27 wfjm
              n.babo := '0';                    -- clear babo flag
947
              if cnt_iszero = '0' then            -- if cnt /= 0
948
                n.state := sl_wblk;                 -- next: read wblk data
949
              else                                -- otherwise cnt = 0
950
                n.state := sl_rxdcrcl;              -- next: wait for dcrc low
951
              end if;
952
            when c_rlink_cmd_labo =>           -- labo ----------------
953
              n.state := sl_txlabo;
954 9 wfjm
            when c_rlink_cmd_attn =>           -- attn ----------------
955 27 wfjm
              n.state := sl_attn;
956 9 wfjm
            when c_rlink_cmd_init =>           -- init ----------------
957 27 wfjm
              ibcmd := c_bcmd_init;
958
              ibgo  := '1';
959
              n.state := sl_txstat;
960 2 wfjm
 
961
            when others =>                    -- '111' ---------------
962 27 wfjm
              n.nakcode := c_rlink_nakcode_cmd; -- signal bad cmd
963
              n.state := sl_txnak;              -- send NAK on reserved command
964 2 wfjm
          end case;
965
        end if;
966 27 wfjm
 
967
      when sl_txcntl =>                 -- sl_txcntl: send cnt lsb ------------
968
        ido := '0' & r.cnt(f_byte0);      -- send cnt lsb
969 2 wfjm
        ival := '1';
970 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
971 27 wfjm
          irtwea := not r.anact;            -- no rtbuf for attn notify
972 9 wfjm
          ocrcena  := '1';                  -- update output crc
973 27 wfjm
          n.state  := sl_txcnth;            -- next: send cnt msb
974 2 wfjm
        end if;
975
 
976 27 wfjm
      when sl_txcnth =>                 -- sl_txcnth: send cnt msb ------------
977
        ido := '0' & r.cnt(f_byte1);      -- send cnt msb
978 2 wfjm
        ival := '1';
979 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
980 27 wfjm
          irtwea := not r.anact;            -- no rtbuf for attn notify
981
          ocrcena  := '1';                  -- update output crc
982
          if r.anact = '1' then              -- if in attn notify
983
            n.state := sl_txcrcl;             -- next: send crc low
984
          elsif r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk
985
            if cnt_iszero = '0' then            -- if cnt /= 0
986
              n.state := sl_rstart;               -- next: start rblk
987
            else                                -- otherwise cnt = 0
988
              n.state := sl_txdcntl;              -- next: send dcnt lsb
989
            end if;
990
          else                                -- otherwise, must be attn
991
            n.state  := sl_txstat;            -- next: send stat
992
          end if;
993 2 wfjm
        end if;
994 27 wfjm
 
995
      when sl_rstart =>                 -- sl_rstart: start rreg or rblk -----
996
        ibcmd := c_bcmd_rblk;
997
        ibgo  := '1';
998
        bcnt_load := '1';
999
        bcnt_val  := r.cnt(cnt_f_dat) & '0';   -- 2*cnt
1000
        n.state := sl_txdat;
1001
 
1002
      when sl_txdat =>                  -- sl_txdat: send data ---------------
1003
        ido := '0' & DOFIFO_DO;
1004
        if DOFIFO_VAL = '1'  then         -- wait for input
1005
          ival := '1';
1006
          if RL_HOLD = '0' then             -- wait for accept
1007
            idohold := '0';
1008
            irtwea  := '1';
1009
            ocrcena := '1';                   -- update output crc
1010
            bcnt_dec := '1';
1011
            if bcnt_end = '1' then
1012
              if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk
1013
                n.state := sl_txdcntl;
1014
              else
1015
                n.state := sl_txstat;
1016
              end if;
1017
            end if;
1018 2 wfjm
          end if;
1019
        end if;
1020
 
1021 27 wfjm
      when sl_wblk =>                   -- sl_wblk: setup rx wblk data -------
1022
        addrb_load := '1';                -- must be done here because addra
1023
        addrb_sela := '1';                -- is incremented in _txcmd 
1024
        bcnt_load  := '1';
1025
        bcnt_val   := r.cnt(cnt_f_dat) & '0';   -- 2*cnt
1026
        n.state := sl_rxwblk;
1027 9 wfjm
 
1028 27 wfjm
      when sl_rxwblk =>                 -- sl_rxwblk: wait for wblk data -----
1029
        ibusy := '0';                     -- accept input
1030
        if RL_ENA = '1' then
1031
          if is_comma = '1' then            -- if comma
1032
            n.nakcode := c_rlink_nakcode_frame; -- signal framing error
1033
            n.state   := sl_txnak;            -- next: send nak
1034
          else
1035
            icrcena := '1';               -- update input crc
1036
            irtweb  := '1';               -- write into rtbuf via b port
1037
            bcnt_dec := '1';
1038
            if bcnt_end = '1' then        -- if all done
1039
              n.state := sl_rxdcrcl;        -- next: wait for data crc low
1040
            end if;
1041 2 wfjm
          end if;
1042
        end if;
1043
 
1044 27 wfjm
      when sl_rxdcrcl =>                -- sl_rxdcrcl: wait for data crc low -
1045
        ibusy := '0';                     -- accept input
1046
        bcnt_val  := r.cnt(cnt_f_dat) & '0';   -- 2 * cnt
1047
        addrb_sela := '1';
1048
        if RL_ENA = '1' then
1049
          if is_comma = '1' then            -- if comma
1050
            n.nakcode := c_rlink_nakcode_frame;  -- signal framing error
1051
            n.state   := sl_txnak;               -- next: send nak
1052
          else
1053
            if idi8 /= ICRC_OUT(f_byte0) then    -- if crc error lsb
1054
              n.nakcode := c_rlink_nakcode_dcrc; -- signal bad dcrc
1055
              n.state := sl_txnak;            -- next: send nak
1056
            else                            -- if crc ok
1057
              n.state := sl_rxdcrch;           -- next: wait for data crc high
1058
            end if;
1059 2 wfjm
          end if;
1060
        end if;
1061
 
1062 27 wfjm
      when sl_rxdcrch =>                -- sl_rxdcrch: wait for data crc high
1063 2 wfjm
        ibusy := '0';                     -- accept input
1064 27 wfjm
        bcnt_val  := r.cnt(cnt_f_dat) & '0';   -- 2 * cnt
1065
        addrb_sela := '1';
1066 9 wfjm
        if RL_ENA = '1' then
1067 2 wfjm
          if is_comma = '1' then            -- if comma
1068 27 wfjm
            n.nakcode := c_rlink_nakcode_frame;  -- signal framing error
1069
            n.state   := sl_txnak;               -- next: send nak
1070 2 wfjm
          else
1071 27 wfjm
            if idi8 /= ICRC_OUT(f_byte1) then    -- if crc error msb
1072
              n.nakcode := c_rlink_nakcode_dcrc; -- signal bad dcrc
1073
              n.state := sl_txnak;            -- next: send nak
1074
            else                            -- if crc ok
1075
              addrb_load := '1';
1076
              bcnt_load  := '1';
1077
              if r.rtaddrb_bad = '0' then     -- if rtbuf ok
1078
                n.state := sl_wblk0;            -- next: start wblk pipe
1079
              else                            -- else rtbuf ovfl
1080
                n.nakcode := c_rlink_nakcode_rtwblk; -- signal ovfl in wblk
1081
                n.state := sl_txnak;            -- next: send nak
1082
              end if;
1083 2 wfjm
            end if;
1084
          end if;
1085
        end if;
1086
 
1087 27 wfjm
      when sl_wblk0 =>                  -- sl_wblk0: start wblk pipe ---------
1088
        if cnt_iszero = '0' then            -- if cnt /= 0
1089
          irtreb := '1';                    -- request next byte
1090
          n.state := sl_wblk1;              -- next: start data lsb
1091
        else                                -- otherwise cnt = 0
1092
          n.state := sl_txdcntl;              -- next: send dcnt lsb
1093
        end if;
1094 2 wfjm
 
1095 27 wfjm
      when sl_wblk1 =>                  -- sl_wblk1: start wblk data lsb -----
1096
        n.dinl := RTBUF_DOB;              -- latch data lsb
1097
        irtreb := '1';                    -- request next byte
1098
        bcnt_dec := '1';
1099
        n.state := sl_wblk2;              -- next: start data msb
1100
 
1101
      when sl_wblk2 =>                  -- sl_wblk2: start wblk data msb -----
1102
        n.din := RTBUF_DOB & r.dinl;      -- setup din
1103
        bcnt_dec := '1';
1104
        ibcmd := c_bcmd_wblk;             -- start rbus sequencer
1105
        ibgo  := '1';
1106
        if bcnt_end = '0' then            -- if not yet done
1107
          irtreb := '1';                    -- request next byte
1108
          n.state := sl_wblkl;              -- next: enter wblk pipe
1109
        else                              -- all done
1110
          n.state := sl_wwait0;             -- next: wait for wdone
1111
        end if;
1112
 
1113
      when sl_wblkl =>                  -- sl_wblkl: pipe wblk data lsb ------
1114
        n.dinl := RTBUF_DOB;              -- latch data lsb
1115
        irtreb := '1';                    -- request next byte
1116
        bcnt_dec := '1';
1117
        n.state := sl_wblkh;              -- next: pipe msb
1118
 
1119
      when sl_wblkh =>                  -- sl_wblkh: pipe wblk data msb ------
1120
        if B2L_WDONE = '1' then           -- if last write done
1121
          n.din := RTBUF_DOB & r.dinl;      -- setup next din
1122
          bcnt_dec := '1';
1123
          if bcnt_end = '0' then            -- if not yet done
1124
            irtreb := '1';
1125
            n.state := sl_wblkl;              -- next: pipe lsb
1126
          else                              -- all done
1127
            n.state := sl_wwait0;             -- next: wait last wdone
1128
          end if;
1129
        end if;
1130
 
1131
      when sl_wwait0 =>                 -- sl_wwait0: wait for wdone ---------
1132
        if B2L_WDONE = '1' then
1133
          if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_wblk then  -- if wblk
1134
            n.state := sl_wwait1;             -- next: wait for dcnt
1135
          else
1136
            n.state := sl_txstat;             -- next: send stat
1137
          end if;
1138
        end if;
1139
 
1140
      when sl_wwait1 =>                 -- sl_wwait1: wait for dcnt ----------
1141
        n.state := sl_txdcntl;            -- next: send dcnt lsb
1142
 
1143
      when sl_txdcntl =>                -- sl_txdcntl: send dcnt lsb ---------
1144 28 wfjm
        n.babo := R_BREGS.blkabo;         -- remember blk abort
1145 27 wfjm
        ido := '0' & R_BREGS.dcnt(f_byte0); -- send dcnt lsb
1146 2 wfjm
        ival := '1';
1147 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
1148 27 wfjm
          irtwea := '1';
1149 2 wfjm
          ocrcena  := '1';                -- update output crc
1150 27 wfjm
          n.state := sl_txdcnth;          -- next: send dcnt msb
1151 2 wfjm
        end if;
1152
 
1153 27 wfjm
      when sl_txdcnth =>                -- sl_txdcnth: send dcnt msb ---------
1154
        ido := (others=>'0');             -- send dcnt msb
1155
        ido(cntawidth-9 downto 0) := R_BREGS.dcnt(cntawidth-1 downto 8);
1156
        ival := '1';
1157
        if RL_HOLD = '0' then             -- wait for accept
1158
          irtwea := '1';
1159
          ocrcena  := '1';                -- update output crc
1160
          n.state := sl_txstat;           -- next: send stat
1161
        end if;
1162
 
1163
      when sl_txlabo =>                 -- sl_txlabo: send labo flag ---------
1164
        ido := '0' & "0000000" & r.babo;   -- send babo
1165
        ival := '1';
1166
        if RL_HOLD = '0' then             -- wait for accept
1167
          irtwea := '1';
1168
          ocrcena  := '1';                -- update output crc
1169
          n.state := sl_txstat;           -- next: send stat
1170
        end if;
1171
 
1172
      when sl_attn =>                   -- sl_attn: handle attention flags ---
1173
        n.cnt := r.attn;                  -- use cnt to latch attn status
1174
        n.attn := RB_LAM;                 -- LAM in current cycle send next time
1175
        n.arpend := '0';                  -- reenable attn nofification
1176
        n.anreq := '0';                   -- cancel pending notify requests
1177
        n.state := sl_txcntl;             -- next: send cnt lsb (holding attn)
1178
 
1179
      when sl_txstat =>                 -- sl_txstat: send status ------------
1180 28 wfjm
        ido(c_rlink_stat_rbf_stat)   := R_BREGS.stat;
1181
        ido(c_rlink_stat_rbf_attn)   := has_attn;
1182
        ido(c_rlink_stat_rbf_rbtout) := R_BREGS.rbtout;
1183
        ido(c_rlink_stat_rbf_rbnak)  := R_BREGS.rbnak;
1184
        ido(c_rlink_stat_rbf_rberr)  := R_BREGS.rberr;
1185 2 wfjm
        ival := '1';
1186 9 wfjm
        if RL_HOLD  ='0' then             -- wait for accept
1187 27 wfjm
          irtwea := '1';
1188 2 wfjm
          ocrcena  := '1';                -- update output crc
1189 27 wfjm
          n.state := sl_txcrcl;           -- next: send crc low
1190 2 wfjm
        end if;
1191
 
1192 27 wfjm
      when sl_txcrcl =>                 -- sl_txcrcl: send crc low -----------
1193
        ido := "0" & OCRC_OUT(f_byte0);   -- send crc code low
1194 2 wfjm
        ival := '1';
1195 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
1196 27 wfjm
          irtwea := not r.anact;            -- no rtbuf for attn notify
1197
          n.state := sl_txcrch;             -- next: send crc high
1198
        end if;
1199
 
1200
      when sl_txcrch =>                 -- sl_txcrch: send crc high ----------
1201
        ido := "0" & OCRC_OUT(f_byte1);   -- send crc code high
1202
        -- here check for rtbuf overflow
1203
        -- if space for 1 byte complete command and write crc
1204
        if r.rtaddra_red = '0' then       -- if space for 1 byte
1205
          n.lcmd  := r.rcmd;                -- latch current command in lcmd
1206
          ival := '1';
1207
          if RL_HOLD = '0' then             -- wait for accept
1208
            irtwea := not r.anact;            -- no rtbuf for attn notify
1209
            -- if this was attn notify, back to idle
1210
            if r.anact = '1' then
1211
              n.state := sl_txeop;           -- next: send eop
1212
            -- here handle labo: if labo cmd and babo set, eat rest of list
1213
            elsif r.rcmd(c_rlink_cmd_rbf_code)=c_rlink_cmd_labo and
1214
                  r.babo='1' then
1215
              n.state := sl_rxeop;              -- next: wait for eop
1216
            else
1217
              n.state := sl_rxcmd;              -- next: read command or eop
1218
            end if;
1219 9 wfjm
          end if;
1220 27 wfjm
        else
1221
          n.nakcode := c_rlink_nakcode_rtovfl; -- signal rtbuf ovfl
1222
          n.state := sl_txnak;            -- next: send nak
1223 2 wfjm
        end if;
1224 27 wfjm
 
1225 2 wfjm
      when others => null;              -- <> --------------------------------
1226 27 wfjm
 
1227 2 wfjm
    end case;
1228
 
1229 27 wfjm
    -- addra logic (write pointer)
1230
    if addra_clear = '1' then           -- clear
1231
      n.rtaddra := (others=>'0');
1232
      n.rtaddra_red := '0';
1233
      n.rtaddra_bad := '0';
1234 2 wfjm
    else
1235 27 wfjm
      if irtwea = '1' then                -- inc when write on port a
1236
        if r.rtaddra_red = '1' then         -- if already red
1237
          n. rtaddra_bad := '1';              -- than flag bad
1238
        else                                -- still ok
1239
          n.rtaddra := slv(unsigned(r.rtaddra) + 1);  -- inc
1240
          if r.rtaddra = rtaddr_tred then             -- if inc'ed to red
1241
            n. rtaddra_red := '1';                      -- flag red
1242
          end if;
1243
        end if;
1244
      end if;
1245 2 wfjm
    end if;
1246 27 wfjm
 
1247
    -- addrb logic (write and read pointer)
1248
    if addrb_load = '1' then            -- load
1249
      if addrb_sela = '1' then
1250
        n.rtaddrb := r.rtaddra;
1251
        n.rtaddrb_red := r.rtaddra_red;
1252
        n.rtaddrb_bad := r.rtaddra_bad;
1253
      else
1254
        n.rtaddrb := (others=>'0');
1255
        n.rtaddrb_red := '0';
1256
        n.rtaddrb_bad := '0';
1257
      end if;
1258 2 wfjm
    else
1259 27 wfjm
      if irtreb = '1' or irtweb = '1' then  -- inc when read/write on port b
1260
        if r.rtaddrb_red = '1' then           -- if already red
1261
          n. rtaddrb_bad := '1';                -- than flag bad
1262
        else                                  -- still ok
1263
          n.rtaddrb := slv(unsigned(r.rtaddrb) + 1);  -- inc
1264
          if r.rtaddrb = rtaddr_tred then             -- if inc'ed to red
1265
            n. rtaddrb_red := '1';                      -- flag red
1266
          end if;
1267
        end if;
1268 2 wfjm
      end if;
1269
    end if;
1270
 
1271 27 wfjm
    -- bcnt logic
1272
    if bcnt_load = '1' then
1273
      n.bcnt := bcnt_val;
1274
    else
1275
      if bcnt_dec ='1' then
1276
        n.bcnt := slv(unsigned(r.bcnt) - 1);
1277
      end if;
1278
    end if;
1279 9 wfjm
 
1280 27 wfjm
    N_LREGS <= n;
1281
 
1282
    RL_BUSY_L <= ibusy;
1283
    RL_DO_L   <= ido;
1284
    RL_VAL_L  <= ival;
1285
 
1286 9 wfjm
    RL_MONI.eop  <= r.moneop;
1287
    RL_MONI.attn <= r.monattn;
1288 27 wfjm
    RL_MONI.lamp <= r.arpend;
1289
 
1290
    DOFIFO_HOLD <= idohold;
1291 2 wfjm
 
1292 27 wfjm
    RTBUF_WEA <= irtwea;
1293
    RTBUF_DIA <= ido(d_f_data);
1294
    RTBUF_ENB <= irtreb or irtweb;
1295
    RTBUF_WEB <= irtweb;
1296
    RTBUF_DIB <= idi8;
1297
 
1298 2 wfjm
    CRC_RESET <= crcreset;
1299
    ICRC_ENA  <= icrcena;
1300
    OCRC_ENA  <= ocrcena;
1301 27 wfjm
    OCRC_IN   <= ido(d_f_data);
1302 2 wfjm
 
1303 27 wfjm
    L2B_CMD <= ibcmd;
1304
    L2B_GO  <= ibgo;
1305
 
1306
  end process proc_lnext;
1307
 
1308
  -- bus FSM =================================================================
1309 2 wfjm
 
1310 27 wfjm
  proc_bnext: process (R_BREGS, R_LREGS,
1311
                       RB_STAT, RB_SRES_TOT,
1312
                       DOFIFO_SIZE,
1313
                       L2B_CMD, L2B_GO)
1314
 
1315
    variable r : bregs_type := bregs_init;
1316
    variable n : bregs_type := bregs_init;
1317
 
1318
    variable bto_go : slbit := '0';
1319
    variable bto_end : slbit := '0';
1320
    variable cnt_load : slbit := '0';
1321
    variable cnt_dec  : slbit := '0';
1322
    variable cnt_end  : slbit := '0';
1323
    variable dcnt_clear : slbit := '0';
1324
    variable dcnt_inc   : slbit := '0';
1325
    variable ival   : slbit := '0';
1326
    variable ido    : slv8 := (others=>'0');
1327
    variable iwdone : slbit := '0';
1328
 
1329
  begin
1330
 
1331
    r := R_BREGS;
1332
    n := R_BREGS;
1333
 
1334
    bto_go := '0';                      -- default: keep rbus timeout in reset
1335
    bto_end := '0';
1336
    if unsigned(r.btocnt) = 0 then      -- if rbus timeout count at zero
1337
      bto_end := '1';                   -- signal expiration
1338
    end if;
1339
 
1340
    cnt_load := '0';
1341
    cnt_dec  := '0';
1342
    cnt_end  := '0';
1343
    if unsigned(r.cnt) = 0 then
1344
      cnt_end := '1';
1345
    end if;
1346
 
1347
    dcnt_clear := '0';
1348
    dcnt_inc   := '0';
1349
 
1350
    ival := '0';
1351
    ido  := (others=>'0');
1352
 
1353
    iwdone := '0';
1354
 
1355
    -- FIXME: what is proper almost full limit ?
1356
    if unsigned(DOFIFO_SIZE) >= 28 then   -- almost full
1357
      n.wfifo := '1';
1358
    elsif unsigned(DOFIFO_SIZE) <= 2 then -- almost empty
1359
      n.wfifo := '0';
1360
    end if;
1361
 
1362
    n.rbinit  := '0';                   -- clear rb(init|aval|re|we) by default
1363
    n.rbaval  := '0';                   --   they must always be set by the
1364
    n.rbre    := '0';                   --   'previous state'
1365
    n.rbwe    := '0';                   -- 
1366
 
1367
    case r.state is
1368
 
1369
      when sb_idle =>                   -- sb_idle: wait for cmd ------------
1370
        if L2B_GO = '1' then              -- if cmd seen 
1371
          n.stat := RB_STAT;                -- always latch external status bits
1372 28 wfjm
          n.rbtout := '0';
1373
          n.rbnak  := '0';
1374
          n.rberr  := '0';
1375 27 wfjm
          n.blkabo := '0';
1376
          n.dathpend := '0';
1377
          dcnt_clear := '1';
1378
          cnt_load := '1';
1379
          case L2B_CMD is
1380
            when c_bcmd_stat =>           -- stat ---------------------
1381
              null;                         -- nothing else todo
1382
            when c_bcmd_init =>           -- init ---------------------
1383
              n.rbinit := '1';              -- send init pulse
1384
            when c_bcmd_rblk =>           -- rblk ---------------------
1385
              n.rbaval := '1';              -- start aval chunk
1386
              n.state := sb_rstart;         -- next: start rblk
1387
            when c_bcmd_wblk =>           -- wblk ---------------------
1388
              n.rbaval := '1';              -- start aval chunk
1389
              n.state := sb_wstart;         -- next: start wblk
1390
            when others => null;
1391
          end case;
1392
        end if;
1393
 
1394
      when sb_rstart =>                 -- sb_rstart: start rblk -------------
1395
        n.rbaval := '1';                  -- extend aval
1396
        n.rbre := '1';                    -- start read cycle
1397
        n.state := sb_rreg0;              -- next: do rreg
1398
 
1399
      when sb_rreg0 =>                  -- sb_rreg0: rbus read cycle ---------
1400
        ido  := r.rbdout(f_byte1);
1401
        n.stat := RB_STAT;                -- follow external status bits
1402
        if r.dathpend = '1' then          -- if pending data msb
1403
          ival := '1';
1404
          n.dathpend := '0';
1405
        end if;
1406
        n.rbaval := '1';                  -- extend aval
1407
        bto_go := '1';                    -- activate rbus timeout counter
1408
        if RB_SRES_TOT.err = '1' then       -- latch rbus error flag
1409 28 wfjm
          n.rberr  := '1';
1410 27 wfjm
          n.blkabo := '1';
1411
        end if;
1412
        n.rbdout := RB_SRES_TOT.dout;       -- latch data (follow till valid)
1413
        if RB_SRES_TOT.busy='0' or bto_end='1' then -- wait non-busy or timeout
1414
          if RB_SRES_TOT.busy='1' and bto_end='1' then -- if timeout and busy
1415 28 wfjm
            n.rbtout := '1';                    -- set rbus timeout flag
1416 27 wfjm
            n.blkabo := '1';
1417
          elsif RB_SRES_TOT.ack = '0' then    -- if non-busy and no ack
1418
            n.rbnak := '1';                     -- set rbus nak flag            
1419
            n.blkabo := '1';
1420
          end if;
1421
          cnt_dec := '1';
1422
          n.state := sb_rreg1;              -- next: send data lsb
1423
        else                              -- otherwise rbus read continues
1424
          n.rbre   := '1';                  -- extend read cycle
1425
        end if;
1426
 
1427
      when sb_rreg1 =>                  -- sb_rreg1: send read data ----------
1428
        ido  := r.rbdout(f_byte0);
1429
        ival := '1';                      -- send lsb
1430
        n.dathpend := '1';                -- signal mdb pending
1431
        dcnt_inc := not r.blkabo;         -- inc dcnt if no error
1432
        if cnt_end = '0' then             -- if not yet done
1433
          if r.blkabo = '0' then            -- if no errors
1434
            if r.wfifo = '0' then             -- if fifo fine
1435
              n.rbaval := '1';                  -- extend aval
1436
              n.rbre := '1';                    -- start read cycle
1437
              n.state := sb_rreg0;              -- next: do rreg
1438
            else                              -- fifo is full
1439
              n.state := sb_rwait;              -- next: fifo wait
1440
            end if;
1441
          else                              -- errors seen, rblk abort
1442
            n.state := sb_rabo1;              -- next: send rblk abort msb data
1443
          end if;
1444
        else                              -- all done
1445
          n.state := sb_rend;
1446
        end if;
1447
 
1448
      when sb_rwait =>                  -- sb_rwait: wait for fifo -----------
1449
        if r.wfifo = '0' then             -- if fifo fine
1450
          n.rbaval := '1';                  -- start aval chunk
1451
          n.state := sb_rstart;             -- restart rblk
1452
        end if;
1453
 
1454
      when sb_rend =>                   -- sb_rend: send last read data ------
1455
        ido  := r.rbdout(f_byte1);
1456
        ival := '1';                      -- send msb
1457
        n.dathpend := '0';
1458
        n.state := sb_idle;               -- next: idle
1459
 
1460
      when sb_rabo0 =>                  -- sb_rabo0: rblk abort, lsb data ----
1461
        ido  := (others=>'0');
1462
        ival := '1';
1463
        cnt_dec := '1';
1464
        n.state := sb_rabo1;              -- next: send rblk abort, msb data
1465
 
1466
      when sb_rabo1 =>                  -- sb_rabo1: rblk abort, msb data ----
1467
        ido  := (others=>'0');
1468
        if r.wfifo = '0' then
1469
          n.dathpend := '0';              -- cancel msb pend
1470
          ival := '1';
1471
          if cnt_end = '0' then           -- if not yet done
1472
            n.state := sb_rabo0;            -- next: send rblk abort, lsb data
1473
          else                            -- all done
1474
            n.state := sb_idle;             -- next: idle
1475
          end if;
1476
        end if;
1477
 
1478
      when sb_wstart =>                 -- sb_wstart: start wblk
1479
        n.rbaval := '1';                  -- start aval chunk
1480
        n.rbwe := '1';                    -- start write cycle
1481
        n.state := sb_wreg0;
1482
 
1483
      when sb_wreg0 =>                  -- sb_wreg0: rbus write cycle
1484
        n.stat := RB_STAT;                -- follow external status bits
1485
        n.rbaval := '1';                  -- extend aval
1486
        bto_go := '1';                    -- activate rbus timeout counter
1487
        if RB_SRES_TOT.err = '1' then     -- latch rbus error flag
1488 28 wfjm
          n.rberr  := '1';
1489 27 wfjm
          n.blkabo := '1';
1490
        end if;
1491
        if RB_SRES_TOT.busy='0' or bto_end='1' then -- wait non-busy or timeout
1492
          if RB_SRES_TOT.busy='1' and bto_end='1' then -- if timeout and busy
1493 28 wfjm
            n.rbtout := '1';                     -- set rbus timeout flag
1494 27 wfjm
            n.blkabo := '1';
1495
          elsif RB_SRES_TOT.ack='0' then       -- if non-busy and no ack
1496
            n.rbnak := '1';                      -- set rbus nak flag            
1497
            n.blkabo := '1';
1498
          end if;
1499
          cnt_dec := '1';
1500
          iwdone := '1';
1501
          n.state := sb_wreg1;
1502
        else                              -- otherwise rbus write continues
1503
          n.rbwe   := '1';                  -- extend write cycle
1504
        end if;
1505
 
1506
      when sb_wreg1 =>                  -- sb_wreg1: wait write data
1507
        dcnt_inc := not r.blkabo;         -- inc dcnt if no error
1508
        if cnt_end = '0' then             -- if not yet done
1509
          if r.blkabo = '0' then            -- if no errors
1510
            n.rbaval := '1';                  -- extend aval
1511
            n.rbwe := '1';                    -- start write cycle
1512
            n.state := sb_wreg0;
1513
          else                              -- errors seen, rblk abort
1514
            n.state := sb_wabo0;              -- next: drop wblk rest
1515
          end if;
1516
        else                              -- all done
1517
          n.state := sb_idle;               -- next: idle
1518
        end if;
1519
 
1520
      when sb_wabo0 =>                  -- sb_wabo0: wblk abort, drop data --
1521
        iwdone := '1';                    -- drop data
1522
        cnt_dec := '1';
1523
        n.state := sb_wabo1;              -- next: wblk abort, wair
1524
 
1525
      when sb_wabo1 =>                  -- sb_wabo1: wblk abort, wait --------
1526
        if cnt_end = '0' then             -- if not yet done
1527
          n.state := sb_wabo0;              -- next: wblk abort, drop 
1528
        else                              -- all done
1529
          n.state := sb_idle;               -- next: idle
1530
        end if;
1531
 
1532
      when others => null;              -- <> --------------------------------
1533
 
1534
    end case;
1535
 
1536
    if bto_go = '0' then                -- handle access timeout counter
1537
      n.btocnt := btocnt_init;          -- if bto_go=0, keep in reset
1538
    else
1539
      n.btocnt := slv(unsigned(r.btocnt) - 1);-- otherwise count down
1540
    end if;
1541
 
1542
    if cnt_load = '1' then
1543
      n.cnt := R_LREGS.cnt(cnt_f_dat);
1544
    else
1545
      if cnt_dec ='1' then
1546
        n.cnt := slv(unsigned(r.cnt) - 1);
1547
      end if;
1548
    end if;
1549
 
1550
    if dcnt_clear = '1' then
1551
      n.dcnt := (others=>'0');
1552
    else
1553
      if dcnt_inc ='1' then
1554
        n.dcnt := slv(unsigned(r.dcnt) + 1);
1555
      end if;
1556
    end if;
1557
 
1558
    N_BREGS <= n;
1559
 
1560
    DOFIFO_DI  <= ido;
1561
    DOFIFO_ENA <= ival;
1562
 
1563
    B2L_WDONE <= iwdone;
1564
 
1565
  end process proc_bnext;
1566
 
1567
  -- config rbus iface =======================================================
1568
 
1569
  proc_cnext: process (R_CREGS, R_LREGS, RBSEL, RB_MREQ_L)
1570
 
1571
    variable r : cregs_type := cregs_init;
1572
    variable n : cregs_type := cregs_init;
1573
    variable irb_ack  : slbit := '0';
1574
    variable irb_dout : slv16 := (others=>'0');
1575
 
1576
  begin
1577
 
1578
    r := R_CREGS;
1579
    n := R_CREGS;
1580
 
1581
    irb_ack  := '0';
1582
    irb_dout := (others=>'0');
1583
 
1584
    -- rbus transactions
1585
    if RBSEL = '1' then
1586
      irb_ack := RB_MREQ_L.re or RB_MREQ_L.we;
1587
 
1588
      -- config register writes
1589
      if RB_MREQ_L.we = '1' then
1590
        case RB_MREQ_L.addr(1 downto 0) is
1591
          when rbaddr_cntl =>
1592
            n.anena  := RB_MREQ_L.din(cntl_rbf_anena);
1593
            n.atoena := RB_MREQ_L.din(cntl_rbf_atoena);
1594
            n.atoval := RB_MREQ_L.din(cntl_rbf_atoval);
1595
          when others => null;
1596
        end case;
1597
      end if;
1598
 
1599
      -- rbus output driver
1600
      case RB_MREQ_L.addr(1 downto 0) is
1601
        when rbaddr_cntl =>
1602
          irb_dout(cntl_rbf_anena)  := r.anena;
1603
          irb_dout(cntl_rbf_atoena) := r.atoena;
1604
          irb_dout(cntl_rbf_atoval) := r.atoval;
1605
        when rbaddr_stat =>
1606
          irb_dout(stat_rbf_lcmd)   := R_LREGS.lcmd;
1607
          irb_dout(stat_rbf_babo)   := R_LREGS.babo;
1608
          irb_dout(stat_rbf_arpend) := R_LREGS.arpend;
1609
          irb_dout(stat_rbf_rbsize) := slv(to_unsigned(RTAWIDTH-10,3));
1610
        when rbaddr_id0  =>
1611
          irb_dout := SYSID(15 downto  0);
1612
        when rbaddr_id1  =>
1613
          irb_dout := SYSID(31 downto 16);
1614
        when others => null;
1615
      end case;
1616
 
1617
    end if;
1618
 
1619
    N_CREGS <= n;
1620
 
1621
    RB_SRES_CONF.dout <= irb_dout;
1622
    RB_SRES_CONF.ack  <= irb_ack;
1623
    RB_SRES_CONF.err  <= '0';
1624
    RB_SRES_CONF.busy <= '0';
1625
 
1626
  end process proc_cnext;
1627
 
1628
  -- rbus driver -----------------------------------------------------
1629
 
1630
  proc_mreq: process (R_LREGS, R_BREGS)
1631
  begin
1632
 
1633
    RB_MREQ_L      <= rb_mreq_init;
1634
    RB_MREQ_L.aval <= R_BREGS.rbaval;
1635
    RB_MREQ_L.re   <= R_BREGS.rbre;
1636
    RB_MREQ_L.we   <= R_BREGS.rbwe;
1637
    RB_MREQ_L.init <= R_BREGS.rbinit;
1638
    RB_MREQ_L.addr <= R_LREGS.addr;
1639
    RB_MREQ_L.din  <= R_LREGS.din;
1640
 
1641
  end process proc_mreq;
1642
 
1643
  RB_MREQ <= RB_MREQ_L;
1644
 
1645
  RL_BUSY <= RL_BUSY_L;
1646
  RL_DO   <= RL_DO_L;
1647
  RL_VAL  <= RL_VAL_L;
1648
 
1649
-- synthesis translate_off
1650
 
1651
  RLMON: if ENAPIN_RLMON >= 0  generate
1652
    MON : rlink_mon_sb
1653
      generic map (
1654
        DWIDTH => RL_DI'length,
1655
        ENAPIN => ENAPIN_RLMON)
1656
      port map (
1657
        CLK     => CLK,
1658
        RL_DI   => RL_DI,
1659
        RL_ENA  => RL_ENA,
1660
        RL_BUSY => RL_BUSY_L,
1661
        RL_DO   => RL_DO_L,
1662
        RL_VAL  => RL_VAL_L,
1663
        RL_HOLD => RL_HOLD
1664
      );
1665
  end generate RLMON;
1666
 
1667
  RBMON: if ENAPIN_RBMON >= 0  generate
1668
    MON : rb_mon_sb
1669
      generic map (
1670
        DBASE  => 8,
1671
        ENAPIN => ENAPIN_RBMON)
1672
      port map (
1673
        CLK     => CLK,
1674
        RB_MREQ => RB_MREQ_L,
1675
        RB_SRES => RB_SRES_TOT,
1676
        RB_LAM  => RB_LAM,
1677
        RB_STAT => RB_STAT
1678
      );
1679
  end generate RBMON;
1680
 
1681
-- synthesis translate_on
1682
 
1683 2 wfjm
end syn;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.