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

Subversion Repositories w11

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

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

Line No. Rev Author Line
1 9 wfjm
-- $Id: rlink_core.vhd 350 2010-12-28 16:40:11Z mueller $
2 2 wfjm
--
3
-- Copyright 2007-2010 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
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
-- Description:    rlink core with 9bit interface
17 2 wfjm
--
18
-- Dependencies:   comlib/crc8
19
--
20 9 wfjm
-- Test bench:     tb/tb_rlink_direct
21
--                 tb/tb_rlink_serport
22
--                 tb/tb_rlink_tba_ttcombo
23 2 wfjm
--
24
-- Target Devices: generic
25 9 wfjm
-- Tool versions:  xst 8.1, 8.2, 9.1, 9.2, 11.4, 12.1; ghdl 0.18-0.29
26 2 wfjm
--
27
-- Synthesized (xst):
28
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
29 9 wfjm
-- 2010-12-04   343 12.1    M53d xc3s1000-4   155  322    0  199 s  8.9
30
-- 2010-06-06   302 11.4    L68  xc3s1000-4   151  323    0  197 s  8.9
31
-- 2010-04-03   274 11.4    L68  xc3s1000-4   148  313    0  190 s  8.0
32
-- 2009-07-11   232 10.1.03 K39  xc3s1000-4   147  321    0  197 s  8.3
33 2 wfjm
--
34
-- Revision History: 
35
-- Date         Rev Version  Comment
36 9 wfjm
-- 2010-12-25   348   3.1.2  drop RL_FLUSH support, add RL_MONI for rlink_core;
37
-- 2010-12-24   347   3.1.1  rename: CP_*->RL->*
38
-- 2010-12-22   346   3.1    wblk dcrc error: send nak, transit to s_error now;
39
--                           rename stat flags: [cd]crc->[cd]err, ioto->rbnak,
40
--                           ioerr->rberr; '111' cmd now aborts via s_txnak and
41
--                           sets cerr flag; set [cd]err on eop/nak aborts;
42
-- 2010-12-04   343   3.0    renamed rri_ -> rlink_; rbus V3 interface: use now
43
--                           aval,re,we; add new states: s_rstart, s_wstart
44 2 wfjm
-- 2010-06-20   308   2.6    use rbinit,rbreq,rbwe state flops to drive rb_mreq;
45
--                           now nak on reserved cmd 111; use do_comma_abort();
46
-- 2010-06-18   306   2.5.1  rename rbus data fields to _rbf_
47
-- 2010-06-06   302   2.5    use sop/eop framing instead of soc+chaining
48
-- 2010-06-03   299   2.1.2  drop unneeded unsigned casts; change init encoding
49
-- 2010-05-02   287   2.1.1  ren CE_XSEC->CE_INT,RP_STAT->RB_STAT,AP_LAM->RB_LAM
50
--                           drop RP_IINT signal from interfaces
51
-- 2010-04-03   274   2.1    add CP_FLUSH output
52
-- 2009-07-12   233   2.0.1  remove snoopers
53
-- 2008-08-24   162   2.0    with new rb_mreq/rb_sres interface
54
-- 2008-03-02   121   1.1.1  comment out snoopers
55
-- 2007-11-24    98   1.1    new internal init handling (addr=11111111)
56
-- 2007-10-12    88   1.0.1  avoid ieee.std_logic_unsigned, use cast to unsigned
57
-- 2007-09-15    82   1.0    Initial version, fully functional
58
-- 2007-06-17    58   0.5    First preliminary version
59
------------------------------------------------------------------------------
60
--
61
-- Overall protocol:
62
--   _idle : expect
63
--             sop   -> _txsop    (echo sop,     , to _txsop, _rxcmd)
64
--             eop   -> _txeop    (send nak,eop  , to _txnak, _txeop, _idle)
65
--             nak   -> _txnak    (silently ignore nak)
66
--             attn  -> _txito    (send ito      , to _idle)
67
--             data  -> _idle     (silently ignore data)
68
--   _error: expect
69
--             sop   -> _txnak    (send nak      , to _txnak, _error)
70
--             eop   -> _txeop    (echo eop      , to _txeop, _idle)
71
--             nak   -> _txnak    (echo nak      , to _txnak, _error)
72
--             attn  -> _txito    (silently ignore attn)
73
--             data  -> _idle     (silently ignore data)
74
--   _rxcmd: expect
75
--             sop   -> _txnak    (send nak      , to _txnak, _error)
76
--             eop   -> _txeop    (echo eop      , to _txeop, _idle)
77
--             nak   -> _txnak    (echo nak      , to _txnak, _error)
78
--             attn  -> _txito    (silently ignore attn)
79
--             data  -> _idle     (decode command)
80
--   _rx...: expect
81
--             sop   -> _txnak    (send nak      , to _txnak, _error)
82
--             eop   -> _txnak    (send nak,eop  , to _txnak, _txeop, _idle)
83
--             nak   -> _txnak    (echo nak      , to _txnak, _error)
84
--             attn  -> _txito    (silently ignore attn)
85
--             data  -> _idle     (decode data)
86
--
87
--  7 supported commands:
88
--
89
--   000 read reg (rreg):
90
--        rx: cmd addr ccrc
91
--        tx: cmd dl dh stat crc
92
--       seq: _rxcmd _rxaddr _rxccrc (_txcmd|_txnak)
93 9 wfjm
--            _rstart _rreg _txdatl _txdath _txstat _txcrc -> _rxcmd
94 2 wfjm
--
95
--   001 read blk (rblk):
96
--        rx: cmd addr cnt ccrc
97
--        tx: cmd cnt dl dh ... stat crc
98
--       seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak) _txcnt
99 9 wfjm
--            {_rstart _rreg _txdatl _txdath _blk}*
100
--            _txstat _txcrc -> _rxcmd
101 2 wfjm
--
102
--   010 write reg (wreg):
103
--        rx: cmd addr dl dh ccrc
104
--        tx: cmd stat crc
105
--       seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak)
106 9 wfjm
--            _wstart _wreg _txstat _txcrc -> _rxcmd
107 2 wfjm
--
108
--   011 write blk (wblk):
109
--        rx: cmd addr cnt ccrc dl dh ... dcrc
110
--        tx: cmd stat crc
111
--       seq: _rxcmd _rxaddr _rxcnt _rxccrc (_txcmd|_txnak)
112 9 wfjm
--            {_rxdatl _rxdath _wstart _wreg _blk}*
113
--            _rxdcrc _txstat _txcrc -> (_rxcmd|_txnak)
114 2 wfjm
--
115
--   100 read stat (stat):
116
--        rx: cmd ccrc
117
--        tx: cmd ccmd dl dh stat crc
118
--       seq: _rxcmd _rxccrc (_txcmd|_txnak)
119 9 wfjm
--            _txccmd _txdatl _txdath _txstat _txcrc -> _rxcmd
120 2 wfjm
--
121
--   101 read attn (attn):
122
--        rx: cmd ccrc
123
--        tx: cmd dl dh stat crc
124
--       seq: _rxcmd _rxccrc (_txcmd|_txnak)
125 9 wfjm
--            _attn _txdatl _txdath _txstat _txcrc -> _rxcmd
126 2 wfjm
--
127
--   110 write init (init):
128
--        rx: cmd addr dl dh ccrc
129
--        tx: cmd stat crc
130
--       seq: _rxcmd _rxaddr _rxdatl _rxdath _rxccrc (_txcmd|_txnak)
131 9 wfjm
--            _txstat _txcrc -> _rxcmd
132 2 wfjm
--       like wreg, but no rp_we - rp_hold, just a 1 cycle rp_init pulse
133
--
134
--   111 is currently not a legal command and causes a nak
135
--       seq: _txnak
136
--
137 9 wfjm
-- The state bits nakcerr and nakderr determine whether cerr/derr is set
138
-- when s_txnak is entered. cerr is '1' during command receive, derr is '1'
139
-- during data wblk data receive phase:
140
--   nakcerr set in s_rxcmd  (when command received, unless it's stat)
141
--           clr in s_txcmd  (when wblk)
142
--           clr in s_txnak
143
--           clr in s_txcrc  (for sucessful completion)
144
--   nakderr set in s_txcmd  (when wblk)
145
--           clr in s_txnak
146
--           clr in s_txcrc  (for sucessful completion)
147
--
148 2 wfjm
-- The different rbus cycle types are encoded as:
149
--
150 9 wfjm
--        init aval re we
151
--          0    0   0  0   idle
152
--          0    0   1  0   not allowed
153
--          0    0   0  1   not allowed
154
--          0    1   1  0   read 
155
--          0    1   0  1   write
156
--          1    0   0  0   internal init
157
--          1    0   0  1   external init
158
--          1    0   1  0   not allowed
159
--          *    *   1  1   not allowed
160
--          1    1   *  *   not allowed
161 2 wfjm
--
162
 
163
library ieee;
164
use ieee.std_logic_1164.all;
165
use ieee.std_logic_arith.all;
166
 
167
use work.slvtypes.all;
168
use work.comlib.all;
169 9 wfjm
use work.rblib.all;
170
use work.rlinklib.all;
171 2 wfjm
 
172 9 wfjm
entity rlink_core is                    -- rlink core with 9bit interface
173 2 wfjm
  generic (
174
    ATOWIDTH : positive :=  5;          -- access timeout counter width
175
    ITOWIDTH : positive :=  6);         -- idle timeout counter width
176
  port (
177
    CLK  : in slbit;                    -- clock      
178
    CE_INT : in slbit := '0';           -- rri ito time unit clock enable
179
    RESET  : in slbit;                  -- reset
180 9 wfjm
    RL_DI : in slv9;                    -- rlink 9b: data in
181
    RL_ENA : in slbit;                  -- rlink 9b: data enable
182
    RL_BUSY : out slbit;                -- rlink 9b: data busy
183
    RL_DO : out slv9;                   -- rlink 9b: data out
184
    RL_VAL : out slbit;                 -- rlink 9b: data valid
185
    RL_HOLD : in slbit;                 -- rlink 9b: data hold
186
    RL_MONI : out rl_moni_type;         -- rlink: monitor port
187 2 wfjm
    RB_MREQ : out rb_mreq_type;         -- rbus: request
188
    RB_SRES : in rb_sres_type;          -- rbus: response
189
    RB_LAM : in slv16;                  -- rbus: look at me
190
    RB_STAT : in slv3                   -- rbus: status flags
191
  );
192 9 wfjm
end entity rlink_core;
193 2 wfjm
 
194
 
195 9 wfjm
architecture syn of rlink_core is
196 2 wfjm
 
197
  type state_type is (
198
    s_idle,                             -- s_idle: wait for sop
199
    s_txito,                            -- s_txito: send timeout symbol
200
    s_txsop,                            -- s_txsop: send sop
201
    s_txnak,                            -- s_txnak: send nak
202
    s_txeop,                            -- s_txeop: send eop
203
    s_error,                            -- s_error: wait for eop
204
    s_rxcmd,                            -- s_rxcmd: wait for cmd
205
    s_rxaddr,                           -- s_rxaddr: wait for addr
206
    s_rxdatl,                           -- s_rxdatl: wait for data low
207
    s_rxdath,                           -- s_rxdath: wait for data high
208
    s_rxcnt,                            -- s_rxcnt: wait for count
209
    s_rxccrc,                           -- s_rxccrc: wait for command crc
210
    s_txcmd,                            -- s_txcmd: send cmd
211
    s_txcnt,                            -- s_txcnt: send cnt
212 9 wfjm
    s_rstart,                           -- s_rstart: start reg or blk read
213
    s_rreg,                             -- s_rreg:   do reg or blk read
214 2 wfjm
    s_txdatl,                           -- s_txdatl: send data low
215
    s_txdath,                           -- s_txdath: send data high
216 9 wfjm
    s_wstart,                           -- s_wstart: start reg or blk write
217
    s_wreg,                             -- s_wreg:   do reg or blk write
218 2 wfjm
    s_blk,                              -- s_blk: block count handling
219
    s_rxdcrc,                           -- s_rxdcrc: wait for data crc
220
    s_attn,                             -- s_attn: handle attention flags
221
    s_txccmd,                           -- s_txccmd: send last command
222
    s_txstat,                           -- s_txstat: send status
223
    s_txcrc                             -- s_txcrc: send crc
224
  );
225
 
226
  type regs_type is record
227
    state : state_type;                 -- state
228
    rcmd : slv8;                        -- received command
229
    ccmd : slv8;                        -- current command
230
    addr : slv8;                        -- register address
231
    dil : slv8;                         -- input data, lsb
232
    dih : slv8;                         -- input data, msb
233
    dol : slv8;                         -- output data, lsb
234
    doh : slv8;                         -- output data, msb
235
    cnt : slv8;                         -- block transfer count
236
    attn : slv16;                       -- attn mask
237
    atocnt : slv(ATOWIDTH-1 downto 0);  -- access timeout counter
238
    itocnt : slv(ITOWIDTH-1 downto 0);  -- idle timeout counter
239
    itoval : slv(ITOWIDTH-1 downto 0);  -- idle timeout value
240
    itoena : slbit;                     -- idle timeout enable flag
241
    anena : slbit;                      -- attn notification enable flag
242
    andone : slbit;                     -- attn notification done
243 9 wfjm
    cerr : slbit;                       -- stat: command error
244
    derr : slbit;                       -- stat: data error
245
    rbnak: slbit;                       -- stat: rbus no ack or timeout
246
    rberr : slbit;                      -- stat: rbus err bit set
247 2 wfjm
    nakeop : slbit;                     -- send eop after nak
248 9 wfjm
    nakcerr : slbit;                    -- set cerr after nak
249
    nakderr : slbit;                    -- set derr after nak
250 2 wfjm
    rbinit : slbit;                     -- rbus init signal
251 9 wfjm
    rbaval : slbit;                     -- rbus aval signal
252
    rbre : slbit;                       -- rbus re signal
253 2 wfjm
    rbwe : slbit;                       -- rbus we signal
254 9 wfjm
    moneop : slbit;                     -- rl_moni: eop send pulse
255
    monattn : slbit;                    -- rl_moni: attn send pulse
256
    monlamp : slbit;                    -- rl_moni: attn pending state
257 2 wfjm
    stat : slv3;                        -- external status flags
258
  end record regs_type;
259
 
260
  constant atocnt_init : slv(ATOWIDTH-1 downto 0) := (others=>'1');
261
  constant itocnt_init : slv(ITOWIDTH-1 downto 0) := (others=>'0');
262
 
263
  constant c_idle : slv4 := "0000";
264
  constant c_sop  : slv4 := "0001";
265
  constant c_eop  : slv4 := "0010";
266
  constant c_nak  : slv4 := "0011";
267
  constant c_attn : slv4 := "0100";
268
 
269
  constant regs_init : regs_type := (
270
    s_idle,                             --
271
    (others=>'0'),                      -- rcmd
272
    (others=>'0'),                      -- ccmd
273
    (others=>'0'),                      -- addr
274
    (others=>'0'),                      -- dil
275
    (others=>'0'),                      -- dih
276
    (others=>'0'),                      -- dol
277
    (others=>'0'),                      -- doh
278
    (others=>'0'),                      -- cnt
279
    (others=>'0'),                      -- attn
280
    atocnt_init,                        -- atocnt
281
    itocnt_init,                        -- itocnt
282
    itocnt_init,                        -- itoval
283
    '0',                                -- itoena
284
    '0','0',                            -- anena, andone
285
    '0','0','0','0',                    -- stat flags
286 9 wfjm
    '0','0','0',                        -- nakeop,nakcerr,nakderr
287
    '0','0','0','0',                    -- rbinit,rbaval,rbre,rbwe
288
    '0','0','0',                        -- moneop,monattn,monlamp
289 2 wfjm
    (others=>'0')                       -- stat
290
  );
291
 
292
  signal R_REGS : regs_type := regs_init;  -- state registers
293
  signal N_REGS : regs_type := regs_init;  -- next value state regs
294
 
295
  signal CRC_RESET : slbit := '0';
296
  signal ICRC_ENA : slbit := '0';
297
  signal OCRC_ENA : slbit := '0';
298
  signal ICRC_OUT : slv8 := (others=>'0');
299
  signal OCRC_OUT : slv8 := (others=>'0');
300
  signal OCRC_IN : slv8 := (others=>'0');
301
 
302
begin
303
 
304
  assert ITOWIDTH<=8
305
    report "assert(ITOWIDTH<=8): max byte size ITO counter supported"
306
    severity failure;
307
 
308
  ICRC : crc8                           -- crc generator for input data
309
  port map (
310
    CLK   => CLK,
311
    RESET => CRC_RESET,
312
    ENA   => ICRC_ENA,
313 9 wfjm
    DI    => RL_DI(7 downto 0),
314 2 wfjm
    CRC   => ICRC_OUT
315
  );
316
 
317
  OCRC : crc8                           -- crc generator for output data
318
  port map (
319
    CLK   => CLK,
320
    RESET => CRC_RESET,
321
    ENA   => OCRC_ENA,
322
    DI    => OCRC_IN,
323
    CRC   => OCRC_OUT
324
  );
325
 
326
  proc_regs: process (CLK)
327
  begin
328
 
329
    if CLK'event and CLK='1' then
330
      if RESET = '1' then
331
        R_REGS <= regs_init;
332
      else
333
        R_REGS <= N_REGS;
334
      end if;
335
    end if;
336
 
337
  end process proc_regs;
338
 
339 9 wfjm
  proc_next: process (R_REGS, CE_INT, RL_DI, RL_ENA, RL_HOLD, RB_LAM,
340 2 wfjm
                      RB_SRES, RB_STAT, ICRC_OUT, OCRC_OUT)
341
 
342
    variable r : regs_type := regs_init;
343
    variable n : regs_type := regs_init;
344
 
345
    variable ival : slbit := '0';
346
    variable ibusy : slbit := '0';
347
    variable ido : slv9 := (others=>'0');
348
    variable ato_go : slbit := '0';
349
    variable ato_end : slbit := '0';
350
    variable ito_go : slbit := '0';
351
    variable ito_end : slbit := '0';
352
    variable crcreset : slbit := '0';
353
    variable icrcena : slbit := '0';
354
    variable ocrcena : slbit := '0';
355
    variable has_attn : slbit := '0';
356 9 wfjm
    variable snd_attn : slbit := '0';
357 2 wfjm
    variable idi8 : slv8 := (others=>'0');
358
    variable is_comma : slbit := '0';
359
    variable comma_typ : slv4 := "0000";
360
 
361
    procedure do_comma_abort(nstate  : inout state_type;
362
                             nnakeop : inout slbit;
363
                             comma_typ  : in slv4) is
364
    begin
365
      if comma_typ=c_sop or comma_typ=c_eop or comma_typ=c_nak then
366
        if comma_typ = c_eop then
367
          nnakeop := '1';
368
        end if;
369
        nstate  := s_txnak;             -- next: send nak
370
      end if;
371
    end procedure do_comma_abort;
372
 
373
  begin
374
 
375
    r := R_REGS;
376
    n := R_REGS;
377
 
378 9 wfjm
    idi8      := RL_DI(7 downto 0);     -- get data part of RL_DI
379
    is_comma  := RL_DI(8);              -- get comma marker
380
    comma_typ := RL_DI(3 downto 0);     -- get comma type
381 2 wfjm
 
382 9 wfjm
    n.rbinit  := '0';                   -- clear rb(init|aval|re|we) by default
383
    n.rbaval  := '0';                   --   they must always be set by the
384
    n.rbre    := '0';                   --   'previous state'
385
    n.rbwe    := '0';                   -- 
386 2 wfjm
 
387 9 wfjm
    n.moneop  := '0';                   -- default '0', only set by states
388
    n.monattn := '0';                   -- "
389
    n.monlamp := '0';                   -- 
390 2 wfjm
 
391
    ibusy := '1';                       -- default is to hold input
392
    ival := '0';
393
    ido  := (others=>'0');
394
 
395
    crcreset := '0';
396
    icrcena  := '0';
397
    ocrcena  := '0';
398
 
399
    for i in RB_LAM'range loop          -- handle attention "LAM's"
400
      if RB_LAM(i) = '1' then           -- if LAM bit set
401
        n.attn(i) := '1';               -- set attention bit
402
      end if;
403
    end loop;
404
 
405
    has_attn := '0';
406 9 wfjm
    snd_attn := '0';
407
 
408 2 wfjm
    if unsigned(r.attn) /= 0 then       -- is any of the attn bits set ?
409 9 wfjm
      has_attn  := '1';
410
      if r.anena='1' and r.andone='0' then -- is attn notification to be send ?
411
        snd_attn := '1';
412
        n.monlamp := '1';                    -- set lamp flag in rl_moni
413
      end if;
414 2 wfjm
    end if;
415 9 wfjm
 
416 2 wfjm
    ato_go := '0';                      -- default: keep access timeout in reset
417
    ato_end := '0';
418
    if unsigned(r.atocnt) = 0 then      -- if access timeout count at zero
419
      ato_end := '1';                   -- signal expiration
420
    end if;
421
 
422
    ito_go := '0';                      -- default: keep idle timeout in reset
423
    ito_end := '0';
424
    if unsigned(r.itocnt) = 0 then      -- if idle timeout count at zero
425
      ito_end := '1';                   -- signal expiration
426
    end if;
427
 
428
    case r.state is
429
      when s_idle =>                    -- s_idle: wait for sop --------------
430
        ito_go := '1';                    -- idle timeout active
431 9 wfjm
        if snd_attn = '1' then            -- if attn notification to be send
432
          n.state := s_txito;               -- next: send ito byte
433 2 wfjm
        else
434
          ibusy := '0';                   -- accept input
435 9 wfjm
          if RL_ENA = '1' then            -- if input
436 2 wfjm
            if is_comma = '1' then          -- if comma
437
              case comma_typ is
438
                when c_sop =>                 -- if sop
439
                  crcreset := '1';              -- reset crc generators
440
                  n.state := s_txsop;           -- next: echo it
441
                when c_eop =>                 -- if eop (unexpected)
442
                  n.nakeop := '1';              -- send nak,eop
443 9 wfjm
                  n.state   := s_txnak;         -- next: send nak
444 2 wfjm
                when c_attn =>                -- if attn
445
                  n.state := s_txito;           -- next: send ito byte
446
                when others => null;          -- other commas: silently ignore
447
              end case;
448
            else                             -- if normal data
449
              n.state := s_idle;               -- silently dropped
450
            end if;
451
          elsif (r.itoena='1' and             -- if ito enable, expired and XSEC
452
                 ito_end='1' and CE_INT='1') then
453
            n.state := s_txito;             -- next: send ito byte
454
          end if;
455
        end if;
456
 
457
      when s_txito =>                   -- s_txito: send timeout symbol ------
458
        if has_attn = '1' then
459 9 wfjm
          ido := c_rlink_dat_attn;        -- if attn pending: send attn symbol
460 2 wfjm
          n.andone := '1';
461
        else
462 9 wfjm
          ido := c_rlink_dat_idle;        -- otherwise: send idle symbol
463 2 wfjm
        end if;
464
        ival := '1';
465 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
466
          n.monattn := has_attn;            -- signal on rl_moni
467
          n.state := s_idle;                -- next: wait for sop
468 2 wfjm
        end if;
469
 
470
      when s_txsop =>                   -- s_txsop: send sop -----------------
471 9 wfjm
        ido := c_rlink_dat_sop;           -- send sop character
472 2 wfjm
        ival := '1';
473 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
474 2 wfjm
          n.state := s_rxcmd;             -- next: read first command
475
        end if;
476
 
477
      when s_txnak =>                   -- s_txnak: send nak -----------------
478 9 wfjm
        ido := c_rlink_dat_nak;           -- send nak character
479 2 wfjm
        ival := '1';
480 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
481
          n.nakeop  := '0';               -- clear all 'do on nak' state flags
482
          n.nakcerr := '0';
483
          n.nakderr := '0';
484
          if r.nakcerr = '1' then         -- if setting cerr requested
485
            n.cerr := '1';                  -- do it
486
          end if;
487
          if r.nakderr = '1' then         -- if settung derr requested
488
            n.derr := '1';                  -- do it
489
          end if;
490
          if r.nakeop = '1' then           -- if eop after nak requested
491 2 wfjm
            n.state := s_txeop;             -- next: send eop
492
          else
493
            n.state := s_error;             -- next: error state, wait for eop
494
          end if;
495
        end if;
496
 
497
      when s_txeop =>                   -- s_txeop: send eop -----------------
498 9 wfjm
        ido := c_rlink_dat_eop;           -- send eop character
499 2 wfjm
        ival := '1';
500 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
501
          n.moneop := '1';                  -- signal on rl_moni
502 2 wfjm
          n.state := s_idle;                -- next: idle state, wait for sop
503
        end if;
504
 
505
      when s_error =>                   -- s_error: wait for eop -------------
506
        ibusy := '0';                     -- accept input
507 9 wfjm
        if RL_ENA = '1' then
508 2 wfjm
          if is_comma = '1' then          -- if comma
509
            case comma_typ is
510
              when c_sop =>                 -- if sop (unexpected)
511
                n.state  := s_txnak;          -- next: send nak
512
              when c_eop =>                 -- if eop
513
                n.state  := s_txeop;          -- next: echo eop
514
              when c_nak =>                 -- if nak
515
                n.state  := s_txnak;          -- next: echo nak
516
              when others => null;          -- other commas: silently ignore
517
            end case;
518
          else                             -- if normal data
519
            n.state := s_error;              -- silently dropped
520
          end if;
521
        end if;
522
 
523
      when s_rxcmd =>                   -- s_rxcmd: wait for cmd -------------
524
        ibusy := '0';                     -- accept input
525 9 wfjm
        if RL_ENA = '1' then
526 2 wfjm
          if is_comma = '1' then          -- if comma
527
            case comma_typ is
528
              when c_sop =>                 -- if sop (unexpected)
529
                n.state  := s_txnak;          -- next: send nak
530
              when c_eop =>                 -- if eop
531
                n.state  := s_txeop;          -- next: echo eop
532
              when c_nak =>                 -- if nak
533
                n.state  := s_txnak;          -- next: echo nak
534
              when others => null;          --other commas: silently ignore
535
            end case;
536 9 wfjm
          else                            -- if not comma
537
            icrcena   := '1';               -- update input crc
538
            n.rcmd    := idi8;              -- latch received command code
539
                                            -- unless the command is stat
540
            if RL_DI(c_rlink_cmd_rbf_code) /= c_rlink_cmd_stat then
541
              n.nakcerr := '1';               -- set cerr on eop/nak abort
542
            end if;
543
            case RL_DI(c_rlink_cmd_rbf_code) is
544
              when c_rlink_cmd_rreg |
545
                   c_rlink_cmd_rblk |
546
                   c_rlink_cmd_wreg |
547
                   c_rlink_cmd_wblk |
548
                   c_rlink_cmd_init =>      -- for commands needing addr(data)
549
                n.state := s_rxaddr;          -- next: read address
550
              when c_rlink_cmd_stat |
551
                   c_rlink_cmd_attn =>      -- stat and attn commands
552
                n.state := s_rxccrc;          -- next: read command crc
553 2 wfjm
              when others =>
554 9 wfjm
                n.state := s_txnak;           -- next: send nak
555 2 wfjm
            end case;                     -- rcmd,ccmd always hold good cmd 
556
          end if;
557
        end if;
558
 
559
      when s_rxaddr =>                  -- s_rxaddr: wait for addr -----------
560
        ibusy := '0';                     -- accept input
561 9 wfjm
        if RL_ENA = '1' then
562 2 wfjm
          if is_comma = '1' then          -- if comma
563
            do_comma_abort(n.state, n.nakeop, comma_typ);
564
          else
565
            icrcena  := '1';              -- update input crc
566
            n.addr := idi8;               -- latch read address
567 9 wfjm
            case r.rcmd(c_rlink_cmd_rbf_code) is
568
              when c_rlink_cmd_rreg =>      -- for rreg command
569
                n.state := s_rxccrc;          -- next: read command crc
570
              when c_rlink_cmd_wreg |
571
                   c_rlink_cmd_init =>      -- for wreg, init command
572
                n.state := s_rxdatl;          -- next: read data lsb
573
              when others =>                -- for rblk or wblk
574
                n.state := s_rxcnt;           -- next: read count
575 2 wfjm
            end case;
576
          end if;
577
        end if;
578
 
579
      when s_rxdatl =>                  -- s_rxdatl: wait for data low -------
580
        ibusy := '0';                     -- accept input
581 9 wfjm
        if RL_ENA = '1' then
582 2 wfjm
          if is_comma = '1' then          -- if comma 
583
            do_comma_abort(n.state, n.nakeop, comma_typ);
584
         else
585
            icrcena  := '1';              -- update input crc
586
            n.dil := idi8;                -- latch data lsb part
587
            n.state := s_rxdath;          -- next: read data msb
588
          end if;
589
        end if;
590
 
591
      when s_rxdath =>                  -- s_rxdath: wait for data high ------
592
        ibusy := '0';                     -- accept input
593 9 wfjm
        if RL_ENA = '1' then
594 2 wfjm
          if is_comma = '1' then          -- if comma
595
            do_comma_abort(n.state, n.nakeop, comma_typ);
596
          else
597
            icrcena  := '1';              -- update input crc
598
            n.dih := idi8;                -- latch data msb part
599 9 wfjm
            if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_wblk then  -- if wblk
600
              n.rbaval := '1';              -- prepare rbus cycle
601
              n.state  := s_wstart;         -- next: start write reg
602 2 wfjm
           else                           -- otherwise
603
             n.state := s_rxccrc;         -- next: read command crc
604
           end if;
605
          end if;
606
        end if;
607
 
608
      when s_rxcnt =>                   -- s_rxcnt: wait for count -----------
609
        ibusy := '0';                     -- accept input
610 9 wfjm
        if RL_ENA = '1' then
611 2 wfjm
          if is_comma = '1' then            -- if comma
612
            do_comma_abort(n.state, n.nakeop, comma_typ);
613
          else
614
            icrcena  := '1';              -- update input crc
615
            n.cnt := idi8;                -- latch count
616
            n.state := s_rxccrc;          -- next: read command crc
617
          end if;
618
        end if;
619
 
620
      when s_rxccrc =>                  -- s_rxccrc: wait for command crc ----
621
        ibusy := '0';                     -- accept input
622 9 wfjm
        if RL_ENA = '1' then
623 2 wfjm
          if is_comma = '1' then            -- if comma
624
            do_comma_abort(n.state, n.nakeop, comma_typ);
625
          else
626
            if idi8 /= ICRC_OUT then        -- if crc error
627 9 wfjm
                                              -- unless the command is stat
628
              if r.rcmd(c_rlink_cmd_rbf_code) /= c_rlink_cmd_stat then
629
                n.cerr := '1';                   -- set command error flag
630
              end if;
631 2 wfjm
              n.state  := s_txnak;            -- next: send nak
632
            else                            -- if crc ok
633
              n.state := s_txcmd;             -- next: echo command
634
            end if;
635
          end if;
636
        end if;
637
 
638
      when s_txcmd =>                   -- s_txcmd: send cmd -----------------
639
        ido := '0' & r.rcmd;              -- send read command
640
        ival := '1';
641 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
642 2 wfjm
          ocrcena  := '1';                  -- update output crc
643 9 wfjm
          if r.rcmd(c_rlink_cmd_rbf_code) /= c_rlink_cmd_stat then --unless stat
644
            n.ccmd  := r.rcmd;                -- latch current command in ccmd
645
            n.stat  := RB_STAT;               -- latch external status bits
646
            n.cerr  := '0';
647
            n.derr  := '0';
648
            n.rbnak := '0';
649
            n.rberr := '0';
650 2 wfjm
          end if;
651 9 wfjm
          n.nakcerr := '0';                 -- all command rx done up to here
652
 
653
          case r.rcmd(c_rlink_cmd_rbf_code) is -- main command dispatcher
654
            when c_rlink_cmd_rreg  =>          -- rreg ----------------
655
              n.rbaval := '1';                   -- prepare rbus cycle
656
              n.state := s_rstart;               -- next: start read reg
657
            when c_rlink_cmd_rblk =>           -- rblk ----------------
658 2 wfjm
              n.state := s_txcnt;
659 9 wfjm
            when c_rlink_cmd_wreg =>           -- wreg ----------------
660
              n.rbaval := '1';                   -- prepare rbus cycle
661
              n.state := s_wstart;               -- next: start write reg
662
            when c_rlink_cmd_wblk =>           -- wblk ----------------
663
              n.nakderr := '1';                  -- set derr on eop/nak abort
664 2 wfjm
              n.state := s_rxdatl;
665 9 wfjm
            when c_rlink_cmd_stat =>           -- stat ----------------
666 2 wfjm
              n.state := s_txccmd;
667 9 wfjm
            when c_rlink_cmd_attn =>           -- attn ----------------
668 2 wfjm
              n.state := s_attn;
669
 
670 9 wfjm
            when c_rlink_cmd_init =>           -- init ----------------
671 2 wfjm
              n.rbinit := '1';                   -- send init pulse
672
              if r.addr(7 downto 3) = "11111" then   -- is internal init
673
                if r.addr(2 downto 0) = "111" then     -- is rri init 
674 9 wfjm
                  n.anena  := r.dih(c_rlink_iint_rbf_anena  - 8);
675
                  n.itoena := r.dih(c_rlink_iint_rbf_itoena - 8);
676 2 wfjm
                  n.itoval := r.dil(ITOWIDTH-1 downto 0);
677
                                            -- note: itocnt will load in next
678
                                            -- cycle because ito_go=0, so no
679
                                            -- action required here
680
 
681
                end if;
682
              else                                -- is external init
683
                n.rbwe := '1';                      -- send init with we
684
              end if;
685
              n.state := s_txstat;
686
 
687
            when others =>                    -- '111' ---------------
688
              n.state := s_txnak;               -- send NAK on reserved command
689
          end case;
690
        end if;
691
 
692
      when s_txcnt =>                   -- s_txcnt: send cnt -----------------
693
        ido := '0' & r.cnt;               -- send cnt
694
        ival := '1';
695 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
696
          ocrcena  := '1';                  -- update output crc
697
          n.rbaval := '1';                  -- prepare rbus cycle
698
          n.state  := s_rstart;             -- next: start first read reg
699 2 wfjm
        end if;
700
 
701 9 wfjm
      when s_rstart =>                  -- s_rstart: start reg or blk read ---
702
        n.rbaval := '1';                  -- start actual read cycle
703
        n.rbre   := '1';
704
        n.state  := s_rreg;               -- next: reg read 
705
 
706
      when s_rreg =>                    -- s_rreg: do reg or blk read --------
707
        -- this state handles all rbus reads
708 2 wfjm
        ato_go := '1';                    -- activate timeout counter
709 9 wfjm
        if RB_SRES.err = '1' then         -- latch rbus error flag
710
          n.rberr := '1';
711 2 wfjm
        end if;
712
        n.doh := RB_SRES.dout(15 downto 8); -- latch data
713
        n.dol := RB_SRES.dout( 7 downto 0);
714
        n.stat := RB_STAT;                -- latch external status bits
715
        if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout
716
          if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy
717 9 wfjm
            n.rbnak := '1';                   -- set rbus nak flag
718 2 wfjm
          elsif RB_SRES.ack = '0' then      -- if non-busy and no ack
719 9 wfjm
            n.rbnak := '1';                    -- set rbus nak flag            
720 2 wfjm
          end if;
721
          n.state := s_txdatl;              -- next: send data lsb
722
        else                              -- otherwise rbus read continues
723 9 wfjm
          n.rbaval := '1';                  -- extend cycle
724
          n.rbre   := '1';
725 2 wfjm
        end if;
726 9 wfjm
 
727 2 wfjm
      when s_txdatl =>                  -- s_txdatl: send data low -----------
728
        ido := '0' & r.dol;               -- send data
729
        ival := '1';
730 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
731 2 wfjm
          ocrcena  := '1';                -- update output crc
732
          n.state := s_txdath;            -- next: send data msb
733
        end if;
734
 
735
      when s_txdath =>                  -- s_txdath: send data high
736
        ido := '0' & r.doh;               -- send data
737
        ival := '1';
738 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
739 2 wfjm
          ocrcena  := '1';                -- update output crc
740 9 wfjm
          if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk
741 2 wfjm
            n.state := s_blk;             -- next: block count handling
742
          else                            -- otherwise
743
            n.state := s_txstat;          -- next: send stat
744
          end if;
745
        end if;
746
 
747 9 wfjm
      when s_wstart =>                  -- s_wstart: start reg or blk write --
748
        n.rbaval := '1';                  -- start actual write cycle
749
        n.rbwe   := '1';
750
        n.state  := s_wreg;               -- next: reg write 
751
 
752
      when s_wreg =>                    -- s_wreg: do reg or blk write -------
753
        -- this state handles all rbus writes
754 2 wfjm
        ato_go := '1';                    -- activate timeout counter
755 9 wfjm
        if RB_SRES.err = '1' then         -- latch rbus error flag
756
          n.rberr := '1';
757 2 wfjm
        end if;
758
        n.stat := RB_STAT;                -- latch external status bits
759
        if RB_SRES.busy='0' or ato_end='1' then -- wait for non-busy or timeout
760
          if RB_SRES.busy='1' and ato_end='1' then -- if timeout and still busy
761 9 wfjm
            n.rbnak := '1';                    -- set rbus nak flag
762 2 wfjm
          elsif RB_SRES.ack='0' then        -- if non-busy and no ack
763 9 wfjm
            n.rbnak := '1';                    -- set rbus nak flag            
764 2 wfjm
          end if;
765 9 wfjm
          if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_wblk then   -- if wblk
766 2 wfjm
            n.state := s_blk;               -- next: block count handling
767
          else                              -- otherwise
768
            n.state := s_txstat;            -- next: send stat
769
          end if;
770
        else                              -- otherwise rbus write continues
771 9 wfjm
          n.rbaval := '1';                  -- extend cycle
772
          n.rbwe   := '1';
773 2 wfjm
        end if;
774
 
775
      when s_blk =>                     -- s_blk: block count handling -------
776
        n.cnt := unsigned(r.cnt) - 1;     -- decrement transfer count
777
        if unsigned(r.cnt) = 0 then       -- if last transfer 
778 9 wfjm
          if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then -- if rblk
779 2 wfjm
            n.state := s_txstat;          -- next: send stat
780
          else                            -- otherwise
781
            n.state := s_rxdcrc;          -- next: read data crc
782
          end if;
783
 
784
        else                              -- otherwise more to transfer
785 9 wfjm
          if r.rcmd(c_rlink_cmd_rbf_code) = c_rlink_cmd_rblk then   -- if rblk
786
            n.rbaval := '1';                -- prepare rbus cycle
787
            n.state := s_rstart;            -- next: start read blk
788 2 wfjm
          else                            -- otherwise
789 9 wfjm
            n.state := s_rxdatl;            -- next: read data
790 2 wfjm
          end if;
791
        end if;
792
 
793
      when s_rxdcrc =>                  -- s_rxdcrc: wait for data crc -------
794
        ibusy := '0';                     -- accept input
795 9 wfjm
        if RL_ENA = '1' then
796 2 wfjm
          if is_comma = '1' then            -- if comma
797
            do_comma_abort(n.state, n.nakeop, comma_typ);
798
          else
799
            if idi8 /= ICRC_OUT then        -- if crc error
800 9 wfjm
              n.derr := '1';                  -- set data error flag
801 2 wfjm
            end if;
802
            n.state := s_txstat;          -- next: echo command
803
          end if;
804
        end if;
805
 
806
      when s_attn =>                    -- s_attn: handle attention flags ----
807
        n.dol := r.attn(7 downto 0);      -- move attention flags to do buffer
808
        n.doh := r.attn(15 downto 8);
809
        n.attn := RB_LAM;                 -- LAM in current cycle send next time
810
        n.andone := '0';                  -- reenable attn nofification
811
        n.state := s_txdatl;              -- next: send data lsb
812
 
813
      when s_txccmd =>                  -- s_txccmd: send last command
814
        ido := '0' & r.ccmd;              -- send last accepted command
815
        ival := '1';
816 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
817 2 wfjm
          ocrcena  := '1';                -- update output crc
818
          n.state := s_txdatl;            -- next: send last data lsb
819
        end if;
820
 
821
      when s_txstat =>                  -- s_txstat: send status -------------
822
        ido := (others=>'0');
823 9 wfjm
        ido(c_rlink_stat_rbf_stat)  := r.stat;
824
        ido(c_rlink_stat_rbf_attn)  := has_attn;
825
        ido(c_rlink_stat_rbf_cerr)  := r.cerr;
826
        ido(c_rlink_stat_rbf_derr)  := r.derr;
827
        ido(c_rlink_stat_rbf_rbnak) := r.rbnak;
828
        ido(c_rlink_stat_rbf_rberr) := r.rberr;
829 2 wfjm
        ival := '1';
830 9 wfjm
        if RL_HOLD  ='0' then             -- wait for accept
831 2 wfjm
          ocrcena  := '1';                -- update output crc
832
          n.state := s_txcrc;             -- next: send crc
833
        end if;
834
 
835
      when s_txcrc =>                   -- s_txcrc: send crc -----------------
836
        ido := "0" & OCRC_OUT;            -- send crc code
837
        ival := '1';
838 9 wfjm
        if RL_HOLD = '0' then             -- wait for accept
839
                                            -- if dcrc seen in wblk
840
          if r.rcmd(c_rlink_cmd_rbf_code)=c_rlink_cmd_wblk and r.derr='1' then
841
            n.state := s_txnak;             -- next: send nak
842
          else                            -- otherwise
843
            n.nakcerr := '0';               -- clear 'set on nak' requests
844
            n.nakderr := '0';
845
            n.state := s_rxcmd;             -- next: read command or eop
846
          end if;
847 2 wfjm
        end if;
848
 
849
      when others => null;              -- <> --------------------------------
850
    end case;
851
 
852
    if ato_go = '0' then                -- handle access timeout counter
853
      n.atocnt := atocnt_init;          -- if ato_go=0, keep in reset
854
    else
855
      n.atocnt := unsigned(r.atocnt) - 1;-- otherwise count down
856
    end if;
857
 
858
    if ito_go = '0' then                -- handle idle timeout counter
859
      n.itocnt := r.itoval;             -- if ito_go=0, keep at start value
860
    else
861
      if CE_INT = '1' then
862
        n.itocnt := unsigned(r.itocnt) - 1;-- otherwise count down every CE_INT
863
      end if;
864
    end if;
865
 
866
    N_REGS <= n;
867
 
868 9 wfjm
    RL_BUSY  <= ibusy;
869
    RL_DO    <= ido;
870
    RL_VAL   <= ival;
871
 
872
    RL_MONI.eop  <= r.moneop;
873
    RL_MONI.attn <= r.monattn;
874
    RL_MONI.lamp <= r.monlamp;
875 2 wfjm
 
876
    RB_MREQ      <= rb_mreq_init;
877 9 wfjm
    RB_MREQ.aval <= r.rbaval;
878
    RB_MREQ.re   <= r.rbre;
879 2 wfjm
    RB_MREQ.we   <= r.rbwe;
880
    RB_MREQ.init <= r.rbinit;
881
    RB_MREQ.addr <= r.addr;
882
    RB_MREQ.din  <= r.dih & r.dil;
883
 
884
    CRC_RESET <= crcreset;
885
    ICRC_ENA  <= icrcena;
886
    OCRC_ENA  <= ocrcena;
887
    OCRC_IN   <= ido(7 downto 0);
888
 
889
  end process proc_next;
890
 
891
end syn;

powered by: WebSVN 2.1.0

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