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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.5/] [rtl/] [vlib/] [rri/] [rri_core.vhd] - Blame information for rev 7

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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