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 24

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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