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 28

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

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

powered by: WebSVN 2.1.0

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