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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [ibus/] [ibdr_rhrp.vhd] - Blame information for rev 37

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

Line No. Rev Author Line
1 37 wfjm
-- $Id: ibdr_rhrp.vhd 784 2016-07-09 22:17:01Z mueller $
2 30 wfjm
--
3 36 wfjm
-- Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 30 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
-- Module Name:    ibdr_rhrp - syn
16
-- Description:    ibus dev(rem): RHRP
17
--
18
-- Dependencies:   ram_1swar_gen
19
-- Test bench:     -
20
-- Target Devices: generic
21 36 wfjm
-- Tool versions:  ise 14.7; viv 2014.4-2016.1; ghdl 0.31-0.33
22 30 wfjm
--
23
-- Synthesized (xst):
24
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
25 32 wfjm
-- 2015-06-20   692 14.7  131013 xc6slx16-2   212  406    8  142 s  8.7
26 30 wfjm
-- 2015-05-14   680 14.7  131013 xc6slx16-2   211  408    8  131 s  8.8
27
-- 2015-04-06   664 14.7  131013 xc6slx16-2   177  331    8  112 s  8.7
28
--
29
-- Revision History: 
30
-- Date         Rev Version  Comment
31 37 wfjm
-- 2016-05-22   767   1.0.4  don't init N_REGS (vivado fix for fsm inference)
32 32 wfjm
-- 2015-06-20   692   1.0.3  BUGFIX: fix func-go when drive/init busy checks
33
-- 2015-06-05   690   1.0.2  use 'not unit' for lsb of rpsn to avoid SI detect
34
--                           BUGFIX: set rmr only for write to busy unit
35 31 wfjm
-- 2015-05-15   682   1.0.1  correct ibsel range select logic
36 30 wfjm
-- 2015-05-14   680   1.0    Initial version
37
-- 2015-03-15   658   0.1    First draft
38
------------------------------------------------------------------------------
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
use ieee.numeric_std.all;
43
 
44
use work.slvtypes.all;
45
use work.memlib.all;
46
use work.iblib.all;
47
 
48
-- ----------------------------------------------------------------------------
49
entity ibdr_rhrp is                     -- ibus dev(rem): RH+RP
50
                                        -- fixed address: 176700
51
  port (
52
    CLK : in slbit;                     -- clock
53
    CE_USEC : in slbit;                 -- usec pulse
54
    BRESET : in slbit;                  -- ibus reset
55
    ITIMER : in slbit;                  -- instruction timer
56
    RB_LAM : out slbit;                 -- remote attention
57
    IB_MREQ : in ib_mreq_type;          -- ibus request
58
    IB_SRES : out ib_sres_type;         -- ibus response
59
    EI_REQ : out slbit;                 -- interrupt request
60
    EI_ACK : in slbit                   -- interrupt acknowledge
61
  );
62
 
63
  -- by default xst uses a binary encoding for the main fsm.
64
  -- that give quite sub-optimal results, so force one-hot
65
  attribute fsm_encoding : string;
66
  attribute fsm_encoding of ibdr_rhrp : entity is "one-hot";
67
 
68
end entity ibdr_rhrp;
69
 
70
architecture syn of ibdr_rhrp is
71
 
72
  constant ibaddr_rhrp : slv16 := slv(to_unsigned(8#176700#,16));
73
 
74
                                          --  nam  rw mb  rp     rm     storage
75
  constant ibaddr_cs1 : slv5 := "00000";  --  cs1  rw  0  rpcs1  rmcs1  m d,6+r
76
  constant ibaddr_wc  : slv5 := "00001";  --   wc  rw  -  rpwc   rmwc   m 0,7
77
  constant ibaddr_ba  : slv5 := "00010";  --   ba  rw  -  rpba   rmba   m 1,7
78
  constant ibaddr_da  : slv5 := "00011";  --   da  rw  5  rpda   rmda   m d,0
79
  constant ibaddr_cs2 : slv5 := "00100";  --  cs2  rw  -  rpcs2  rmcs2  r cs2*
80
  constant ibaddr_ds  : slv5 := "00101";  --   ds  r-  1  rpds   rmds   r ds*
81
  constant ibaddr_er1 : slv5 := "00110";  --  er1  rw  2  rper1  rmer1  r er1*
82
  constant ibaddr_as  : slv5 := "00111";  --   as  rw  4  rpas   rmas   r as*
83
  constant ibaddr_la  : slv5 := "01000";  --   la  r-  7  rpla   rmla   r sc
84
  constant ibaddr_db  : slv5 := "01001";  --   db  r?  -  rpdb   rmdb   m 2,7
85
  constant ibaddr_mr1 : slv5 := "01010";  --  mr1  rw  3  rpmr1  rmmr1  m d,3
86
  constant ibaddr_dt  : slv5 := "01011";  --   dt  r-  6  rpdt   rmdt   r dt*+map
87
  constant ibaddr_sn  : slv5 := "01100";  --   sn  r- 10  rpsn   rmsn   <map>
88
  constant ibaddr_of  : slv5 := "01101";  --   of  rw 11  rpof   rmof   m d,1
89
  constant ibaddr_dc  : slv5 := "01110";  --   dc  rw 12  rpdc   rmdc   m d,2
90
  constant ibaddr_m13 : slv5 := "01111";  --  m13  rw 13  rpcc          m =dc!
91
                                          --       rw 13         rmhr   m d,4
92
  constant ibaddr_m14 : slv5 := "10000";  --  m14  rw 14  rper2         =0
93
                                          --       rw 14         rmmr2  m d,5
94
  constant ibaddr_m15 : slv5 := "10001";  --  m15  rw 15  rper3         =0
95
                                          --       rw 15         rmer2  =0
96
  constant ibaddr_ec1 : slv5 := "10010";  --  ec1  r- 16  rpec1  rmec1  =0
97
  constant ibaddr_ec2 : slv5 := "10011";  --  ec1  r- 17  rpec2  rmec2  =0
98
  constant ibaddr_bae : slv5 := "10100";  --  bae  rw  -  rpbae  rmbae  r bae
99
  constant ibaddr_cs3 : slv5 := "10101";  --  cs3  rw  -  rpcs3  rmcs3  r cs3*
100
 
101
  constant omux_cs1  : slv4 := "0000";
102
  constant omux_cs2  : slv4 := "0001";
103
  constant omux_ds   : slv4 := "0010";
104
  constant omux_er1  : slv4 := "0011";
105
  constant omux_as   : slv4 := "0100";
106
  constant omux_la   : slv4 := "0101";
107
  constant omux_dt   : slv4 := "0110";
108
  constant omux_sn   : slv4 := "0111";
109
  constant omux_bae  : slv4 := "1000";
110
  constant omux_cs3  : slv4 := "1001";
111
  constant omux_mem  : slv4 := "1010";
112
  constant omux_zero : slv4 := "1111";
113
 
114
  constant amapc_da  : slv3 := "000";
115
  constant amapc_mr1 : slv3 := "011";
116
  constant amapc_of  : slv3 := "001";
117
  constant amapc_dc  : slv3 := "010";
118
  constant amapc_hr  : slv3 := "100";
119
  constant amapc_mr2 : slv3 := "101";
120
  constant amapc_cs1 : slv3 := "110";
121
  constant amapc_ext : slv3 := "111";
122
 
123
  constant amapr_wc  : slv2 := "00";
124
  constant amapr_ba  : slv2 := "01";
125
  constant amapr_db  : slv2 := "10";
126
 
127
  subtype  amap_f_unit     is integer range  4 downto  3;  -- unit part
128
  subtype  amap_f_reg      is integer range  2 downto  0;  -- reg  part
129
 
130
  constant clrmode_breset : slv2 := "00";
131
  constant clrmode_cs2clr : slv2 := "01";
132
  constant clrmode_fdclr  : slv2 := "10";
133
  constant clrmode_fpres  : slv2 := "11";
134
 
135
  constant cs1_ibf_sc    : integer := 15;     -- special condition
136
  constant cs1_ibf_tre   : integer := 14;     -- transfer error
137
  constant cs1_ibf_dva   : integer := 11;     -- drive available
138
  subtype  cs1_ibf_bae     is integer range  9 downto  8;  -- bus addr ext (1:0)
139
  constant cs1_ibf_rdy   : integer :=  7;     -- controller ready
140
  constant cs1_ibf_ie    : integer :=  6;     -- interrupt enable
141
  subtype  cs1_ibf_func    is integer range  5 downto  1;  -- function code
142
  constant cs1_ibf_go    : integer :=  0;     -- interrupt enable
143
 
144
  constant func_noop  : slv5 := "00000";   -- func: noop
145
  constant func_unl   : slv5 := "00001";   -- func: unload
146
  constant func_seek  : slv5 := "00010";   -- func: seek
147
  constant func_recal : slv5 := "00011";   -- func: recalibrate
148
  constant func_dclr  : slv5 := "00100";   -- func: drive clear
149
  constant func_pore  : slv5 := "00101";   -- func: port release
150
  constant func_offs  : slv5 := "00110";   -- func: offset
151
  constant func_retc  : slv5 := "00111";   -- func: return to center
152
  constant func_pres  : slv5 := "01000";   -- func: readin preset
153
  constant func_pack  : slv5 := "01001";   -- func: pack acknowledge
154
  constant func_sear  : slv5 := "01100";   -- func: search
155 32 wfjm
  constant func_xfer  : slv5 := "10100";   -- used to check for xfer type funcs
156 30 wfjm
  constant func_wcd   : slv5 := "10100";   -- func: write check data
157
  constant func_wchd  : slv5 := "10101";   -- func: write check header&data
158
  constant func_write : slv5 := "11000";   -- func: write 
159
  constant func_whd   : slv5 := "11001";   -- func: write header&data
160
  constant func_read  : slv5 := "11100";   -- func: read  
161
  constant func_rhd   : slv5 := "11101";   -- func: read header&data
162
 
163
  constant rfunc_wunit : slv5 := "00001";   -- rem func: write runit
164
  constant rfunc_cunit : slv5 := "00010";   -- rem func: copy funit->runit
165
  constant rfunc_done  : slv5 := "00011";   -- rem func: done (set rdy)
166
  constant rfunc_widly : slv5 := "00100";   -- rem func: write idly
167
 
168
  -- cs1 usage for rem functions
169
  subtype  cs1_ibf_runit   is integer range  9 downto  8;  -- new runit (_wunit)
170
  constant cs1_ibf_rata  : integer := 8;                   -- use ata   (_done)
171
  subtype  cs1_ibf_ridly   is integer range 15 downto  8;  -- new idly  (_widly)
172
 
173
  subtype  da_ibf_ta       is integer range 12 downto  8;  -- track  addr
174
  subtype  da_ibf_sa       is integer range  5 downto  0;  -- sector addr
175
 
176
  constant cs2_ibf_rwco  : integer := 15;     -- rem: write check odd word
177
  constant cs2_ibf_wce   : integer := 14;     -- write check error
178 32 wfjm
  constant cs2_ibf_ned   : integer := 12;     -- non-existent drive
179
  constant cs2_ibf_nem   : integer := 11;     -- non-existent memory
180 30 wfjm
  constant cs2_ibf_pge   : integer := 10;     -- programming error
181
  constant cs2_ibf_mxf   : integer :=  9;     -- missed transfer
182
  constant cs2_ibf_or    : integer :=  7;     -- output ready
183
  constant cs2_ibf_ir    : integer :=  6;     -- input ready
184
  constant cs2_ibf_clr   : integer :=  5;     -- clear controller
185
  constant cs2_ibf_pat   : integer :=  4;     -- parity test
186
  constant cs2_ibf_bai   : integer :=  3;     -- bus address inhibit
187
  constant cs2_ibf_unit2 : integer :=  2;     -- unit select msb
188
  subtype  cs2_ibf_unit    is integer range  1 downto  0;  -- unit select
189
 
190
  constant ds_ibf_ata    : integer := 15;     -- attention
191
  constant ds_ibf_erp    : integer := 14;     -- any errors in er1 or er2
192
  constant ds_ibf_pip    : integer := 13;     -- positioning in progress
193
  constant ds_ibf_mol    : integer := 12;     -- medium online (ATTACHED)
194
  constant ds_ibf_wrl    : integer := 11;     -- write locked
195
  constant ds_ibf_lbt    : integer := 10;     -- last block transfered
196
  constant ds_ibf_dpr    : integer :=  8;     -- drive present (ENABLED)
197
  constant ds_ibf_dry    : integer :=  7;     -- drive ready
198
  constant ds_ibf_vv     : integer :=  6;     -- volume valid
199
  constant ds_ibf_om     : integer :=  0;     -- offset mode
200
 
201
  constant er1_ibf_uns   : integer := 14;     -- drive unsafe
202
  constant er1_ibf_wle   : integer := 11;     -- write lock error
203
  constant er1_ibf_iae   : integer := 10;     -- invalid address error
204
  constant er1_ibf_aoe   : integer :=  9;     -- address overflow error
205
  constant er1_ibf_rmr   : integer :=  2;     -- register modification refused
206
  constant er1_ibf_ilf   : integer :=  0;     -- illegal function
207
 
208
  subtype  la_ibf_sc       is integer range 11 downto  6;  -- current sector
209
 
210
  constant dt_ibf_rm     : integer :=  2;     -- rm cntl
211
  constant dt_ibf_e1     : integer :=  1;     -- encoded type bit 1
212
  constant dt_ibf_e0     : integer :=  0;     -- encoded type bit 0
213
 
214
  constant dte_rp04      : slv3 :=  "000";    -- encoded dt for rp04 rm=0
215
  constant dte_rp06      : slv3 :=  "001";    -- encoded dt for rp06 rm=0
216
  constant dte_rm03      : slv3 :=  "100";    -- encoded dt for rm03 rm=1
217
  constant dte_rm80      : slv3 :=  "101";    -- encoded dt for rm80 rm=1
218
  constant dte_rm05      : slv3 :=  "110";    -- encoded dt for rm05 rm=1
219
  constant dte_rp07      : slv3 :=  "111";    -- encoded dt for rp07 rm=1
220
 
221
  subtype  dc_ibf_ca       is integer range  9 downto  0;  -- cyclinder addr
222
 
223
  subtype  bae_ibf_bae     is integer range  5 downto  0;  -- bus addr ext.
224
 
225
  constant cs3_ibf_wco       : integer := 12;     -- write check odd
226
  constant cs3_ibf_wce       : integer := 11;     -- write check even
227
  constant cs3_ibf_ie        : integer :=  6;     -- interrupt enable
228
  constant cs3_ibf_rseardone : integer :=  3;     -- rem: sear done flag
229
  constant cs3_ibf_rpackdone : integer :=  2;     -- rem: pack done flag
230
  constant cs3_ibf_rporedone : integer :=  1;     -- rem: pore done flag
231
  constant cs3_ibf_rseekdone : integer :=  0;     -- rem: seek done flag
232
 
233
  -- RP controller type disks
234
  constant rp04_dtyp   : slv6  := slv(to_unsigned(  8#20#,  6));
235
  constant rp04_camax  : slv10 := slv(to_unsigned(  411-1, 10));
236
  constant rp04_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
237
  constant rp04_samax  : slv6  := slv(to_unsigned(   22-1,  6));
238
 
239
  constant rp06_dtyp   : slv6  := slv(to_unsigned(  8#22#,  6));
240
  constant rp06_camax  : slv10 := slv(to_unsigned(  815-1, 10));
241
  constant rp06_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
242
  constant rp06_samax  : slv6  := slv(to_unsigned(   22-1,  6));
243
 
244
  -- RM controller type disks (Note: rp07 has a RM stype controller!)
245
  constant rm03_dtyp   : slv6  := slv(to_unsigned(  8#24#,  6));
246
  constant rm03_camax  : slv10 := slv(to_unsigned(  823-1, 10));
247
  constant rm03_tamax  : slv5  := slv(to_unsigned(    5-1,  5));
248
  constant rm03_samax  : slv6  := slv(to_unsigned(   32-1,  6));
249
 
250
  constant rm80_dtyp   : slv6  := slv(to_unsigned(  8#26#,  6));
251
  constant rm80_camax  : slv10 := slv(to_unsigned(  559-1, 10));
252
  constant rm80_tamax  : slv5  := slv(to_unsigned(   14-1,  5));
253
  constant rm80_samax  : slv6  := slv(to_unsigned(   31-1,  6));
254
 
255
  constant rm05_dtyp   : slv6  := slv(to_unsigned(  8#27#,  6));
256
  constant rm05_camax  : slv10 := slv(to_unsigned(  823-1, 10));
257
  constant rm05_tamax  : slv5  := slv(to_unsigned(   19-1,  5));
258
  constant rm05_samax  : slv6  := slv(to_unsigned(   32-1,  6));
259
 
260
  constant rp07_dtyp   : slv6  := slv(to_unsigned(  8#42#,  6));
261
  constant rp07_camax  : slv10 := slv(to_unsigned(  630-1, 10));
262
  constant rp07_tamax  : slv5  := slv(to_unsigned(   32-1,  5));
263
  constant rp07_samax  : slv6  := slv(to_unsigned(   50-1,  6));
264
 
265
  type state_type is (
266
    s_idle,                             -- idle: handle ibus
267
    s_wcs1,                             -- wcs1: write cs1
268
    s_wcs2,                             -- wcs2: write cs2
269
    s_wcs3,                             -- wcs3: write cs3
270
    s_wer1,                             -- wer1: write er1 (rem only)
271
    s_was,                              -- was:  write as
272
    s_wdt,                              -- wdt:  write dt  (rem only)
273
    s_wds,                              -- wdt:  write ds  (rem only)
274
    s_wbae,                             -- wbae: write bae
275
    s_wmem,                             -- wmem: write mem (DA,MR1,OF,DC,MR2)
276
    s_wmembe,                           -- wmem: write mem with be (WC,BA,DB)
277
    s_whr,                              -- whr:  write hr (holding reg only)
278 32 wfjm
    s_funcchk,                          -- funcchk: check function go
279 30 wfjm
    s_funcgo,                           -- funcgo: handle function go
280
    s_chkdc,                            -- chkdc: handle dc check
281
    s_chkda,                            -- chksa: handle da check
282
    s_chkdo,                            -- chkdo: execute function
283
    s_read,                             -- read: all register reads
284
    s_setrmr,                           -- set rmr flag
285
    s_oot_clr0,                         -- OOT clr0: state 0
286
    s_oot_clr1,                         -- OOT clr1: state 1
287
    s_oot_clr2                          -- OOT clr2: state 2
288
  );
289
 
290
  type regs_type is record              -- state registers
291
    ibsel   : slbit;                    -- ibus select
292
    state   : state_type;               -- state
293
    amap    : slv5;                     -- mem mapped address
294
    omux    : slv4;                     -- omux select
295
    dinmsk  : slv16;                    -- mbreq.din masked
296
    dtrm    : slv4;                     -- dt: drive rm controller
297
    dte1    : slv4;                     -- dt: drive type bit 1
298
    dte0    : slv4;                     -- dt: drive type bit 0
299
    bae     : slv6;                     -- bae: bus addr extension (in cs1&bae)
300
    cs1sc   : slbit;                    -- cs1: special condition
301
    cs1tre  : slbit;                    -- cs1: transfer error
302
    cs1rdy  : slbit;                    -- cs1: controller ready
303
    cs1ie   : slbit;                    -- cs1: interrupt enable
304
    ffunc   : slv5;                     -- func code (frozen on ext func go)
305
    fxfer   : slbit;                    -- func is xfer
306
    cs2wce  : slbit;                    -- cs2: write check error
307 32 wfjm
    cs2ned  : slbit;                    -- cs2: non-existent drive
308
    cs2nem  : slbit;                    -- cs2: non-existent memory
309 30 wfjm
    cs2pge  : slbit;                    -- cs2: programming error
310
    cs2mxf  : slbit;                    -- cs2: missed transfer
311
    cs2pat  : slbit;                    -- cs2: parity test
312
    cs2bai  : slbit;                    -- cs2: bus address inhibit
313
    cs2unit2: slbit;                    -- cs2: unit lsb
314
    cs2unit : slv2;                     -- unit (ibus view)
315
    funit   : slv2;                     -- unit (frozen on ext func go)
316
    runit   : slv2;                     -- unit (remote view)
317
    eunit   : slv2;                     -- unit (effective)
318
    dsata   : slv4;                     -- ds: attention
319
    dserp   : slv4;                     -- ds: error summary (or of er1+er2)
320
    dspip   : slv4;                     -- ds: positioning in progress
321
    dsmol   : slv4;                     -- ds: medium online (ATTACHED)
322
    dswrl   : slv4;                     -- ds: write locked
323
    dslbt   : slv4;                     -- ds: last block transfered
324
    dsdpr   : slv4;                     -- ds: drive present (ENABLED)
325
    dsvv    : slv4;                     -- ds: volume valid
326
    dsom    : slv4;                     -- ds: offset mode
327
    er1uns  : slv4;                     -- er1: dive unsafe
328
    er1wle  : slv4;                     -- er1: write lock error
329
    er1iae  : slv4;                     -- er1: invalid address error
330
    er1aoe  : slv4;                     -- er1: address overflow error
331
    er1rmr  : slv4;                     -- er1: register modificaton refused
332
    er1ilf  : slv4;                     -- er1: illegal function
333
    cs3wco  : slbit;                    -- cs3: write check  odd word
334
    idlyval : slv8;                     -- int delay value
335
    idlycnt : slv8;                     -- int delay counter
336
    seekdone: slbit;                    -- cs3 rem: seek     done
337
    poredone: slbit;                    -- cs3 rem: port rel done
338
    packdone: slbit;                    -- cs3 rem: pack ack done
339
    seardone: slbit;                    -- cs3 rem: search   done
340 32 wfjm
    ned     : slbit;                    -- current drive non-existent
341 30 wfjm
    cerm    : slbit;                    -- current eff. drive rm controller
342
    dtyp    : slv6;                     -- current drive type (5:0)
343
    camax   : slv10;                    -- current max cylinder address
344
    tamax   : slv5;                     -- current max track  address
345
    samax   : slv6;                     -- current max sector address
346
    uscnt   : slv7;                     -- usec counter
347
    sc      : slv6;                     -- current sector counter
348
    clrmode : slv2;                     -- clear: mode
349
    clrreg  : slv3;                     -- clear: register counter
350
    ireq    : slbit;                    -- interrupt request flag
351
  end record regs_type;
352
 
353
  constant regs_init : regs_type := (
354
    '0',                                -- ibsel
355
    s_idle,                             -- state
356
    (others=>'0'),                      -- amap,
357
    (others=>'0'),                      -- omux,
358
    (others=>'0'),                      -- dinmsk,
359
    (others=>'0'),                      -- dtrm
360
    (others=>'0'),                      -- dte1
361
    (others=>'0'),                      -- dte0
362
    (others=>'0'),                      -- bae,
363
    '0','0','1','0',                    -- cs1sc,cs1tre,cs1rdy,cs1ie
364
    (others=>'0'),                      -- ffunc
365
    '0',                                -- fxfer
366
    '0','0','0','0',                    -- cs2wce,cs2ned,cs2nem,cs2pge
367
    '0','0','0',                        -- cs2mxf,cs2pat,cs2bai
368
    '0',                                -- cs2unit2
369
    (others=>'0'),                      -- cs2unit
370
    (others=>'0'),                      -- funit
371
    (others=>'0'),                      -- runit
372
    (others=>'0'),                      -- eunit
373
    (others=>'0'),                      -- dsata
374
    (others=>'0'),                      -- dserp
375
    (others=>'0'),                      -- dspip
376
    (others=>'0'),                      -- dsmol
377
    (others=>'0'),                      -- dswrl
378
    (others=>'0'),                      -- dslbt
379
    (others=>'0'),                      -- dsdpr
380
    (others=>'0'),                      -- dsvv
381
    (others=>'0'),                      -- dsom
382
    (others=>'0'),                      -- er1uns
383
    (others=>'0'),                      -- er1wle
384
    (others=>'0'),                      -- er1iae
385
    (others=>'0'),                      -- er1aoe
386
    (others=>'0'),                      -- er1rmr
387
    (others=>'0'),                      -- er1ilf
388
    '0',                                -- cs3wco
389
    x"0a",                              -- idlyval  (default delay=10)
390
    (others=>'0'),                      -- idlycnt
391
    '0','0','0','0',                    -- seekdone,poredone,packdone,seardone
392
    '0','0',                            -- ned,cerm
393
    (others=>'0'),                      -- dtyp
394
    (others=>'0'),                      -- camax
395
    (others=>'0'),                      -- tamax
396
    (others=>'0'),                      -- samax
397
    (others=>'0'),                      -- uscnt
398
    (others=>'0'),                      -- sc
399
    (others=>'0'),                      -- clrmode
400
    (others=>'0'),                      -- clrreg
401
    '0'                                 -- ireq
402
  );
403
 
404
  signal R_REGS : regs_type := regs_init;
405 36 wfjm
  signal N_REGS : regs_type;            -- don't init (vivado fix for fsm infer)
406 30 wfjm
 
407
  signal MEM_1_WE : slbit := '0';
408
  signal MEM_0_WE : slbit := '0';
409
  signal MEM_ADDR : slv5  := (others=>'0');
410
  signal MEM_DIN  : slv16 := (others=>'0');
411
  signal MEM_DOUT : slv16 := (others=>'0');
412
 
413
  -- the following is unfortunately not accepted by xst:
414
  -- attribute fsm_encoding : string;
415
  -- attribute fsm_encoding of R_REGS.state : signal is "one-hot";
416
 
417
begin
418
 
419
  MEM_1 : ram_1swar_gen
420
    generic map (
421
      AWIDTH =>  5,
422
      DWIDTH =>  8)
423
    port map (
424
      CLK  => CLK,
425
      WE   => MEM_1_WE,
426
      ADDR => MEM_ADDR,
427
      DI   => MEM_DIN(ibf_byte1),
428
      DO   => MEM_DOUT(ibf_byte1));
429
 
430
  MEM_0 : ram_1swar_gen
431
    generic map (
432
      AWIDTH =>  5,
433
      DWIDTH =>  8)
434
    port map (
435
      CLK  => CLK,
436
      WE   => MEM_0_WE,
437
      ADDR => MEM_ADDR,
438
      DI   => MEM_DIN(ibf_byte0),
439
      DO   => MEM_DOUT(ibf_byte0));
440
 
441
  proc_regs: process (CLK)
442
  begin
443
    -- BRESET handled in main fsm, not here !!
444
    if rising_edge(CLK) then
445
      R_REGS <= N_REGS;
446
    end if;
447
  end process proc_regs;
448
 
449
  proc_next : process (R_REGS, CE_USEC, BRESET, ITIMER, IB_MREQ, MEM_DOUT,
450
                       EI_ACK)
451
    variable r : regs_type := regs_init;
452
    variable n : regs_type := regs_init;
453
    variable ibhold : slbit := '0';
454
    variable idout  : slv16 := (others=>'0');
455
    variable ibrem  : slbit := '0';
456
    variable ibreq  : slbit := '0';
457
    variable ibrd   : slbit := '0';
458
    variable ibw0   : slbit := '0';
459
    variable ibw1   : slbit := '0';
460
    variable ibwrem : slbit := '0';
461
    variable ilam   : slbit := '0';
462
    variable iei_req : slbit := '0';
463
 
464
    variable imem_we0 : slbit := '0';
465
    variable imem_we1 : slbit := '0';
466
    variable imem_addr : slv5 := (others=>'0');
467
    variable imem_din : slv16 := (others=>'0');
468
 
469
    variable ieunit  : slv2 := (others=>'0');
470
 
471
    variable iomux  : slv4  := (others=>'0');   -- omux select
472
    variable iamap  : slv5  := (others=>'0');   -- mem mapped address
473
    variable imask  : slv16 := (others=>'0');   -- implemented bits mask
474
    variable imbreg : slbit := '0';             -- massbus register
475
    variable inormr : slbit := '0';             -- inhibit rmr protect
476
 
477
    variable idte   : slv3  := (others=>'0');   -- encoded drive type
478
    variable idtyp  : slv6  := (others=>'0');   -- drive type (5:0)
479
    variable icamax : slv10 := (others=>'0');   -- max cylinder address
480
    variable itamax : slv5  := (others=>'0');   -- max track    address
481
    variable isamax : slv6  := (others=>'0');   -- max sector   address
482
 
483 32 wfjm
    variable ined   : slbit := '0';     -- non-existent drive
484 30 wfjm
    variable icerm  : slbit := '0';     -- effectiv drive is rm
485
 
486
    variable iclrreg : slbit := '0';    -- clr enable
487
 
488
    variable iscinc  : slbit := '0';    -- increment r.sc enable
489
 
490
  begin
491
 
492
    r := R_REGS;
493
    n := R_REGS;
494
 
495
    ibhold := '0';
496
    idout  := (others=>'0');
497
    ibrem  := IB_MREQ.racc;
498
    ibreq  := IB_MREQ.re or IB_MREQ.we;
499
    ibrd   := IB_MREQ.re;
500
    ibw0   := IB_MREQ.we and IB_MREQ.be0;
501
    ibw1   := IB_MREQ.we and IB_MREQ.be1;
502
    ibwrem := IB_MREQ.we and ibrem;
503
    ilam   := '0';
504
    iei_req  := '0';
505
 
506
    imem_we0  := '0';
507
    imem_we1  := '0';
508
    imem_addr := r.amap;                -- default address (from mapper)
509
    imem_din  := r.dinmsk;              -- default input   (from masker)
510
 
511
    ieunit := (others=>'0');
512
 
513
    iomux  := (others=>'0');
514
    iamap  := (others=>'0');
515
    imask  := (others=>'1');            -- default: all bits ok
516
    imbreg := '0';
517
    inormr := '0';
518
 
519
    idte   := (others=>'0');
520
    idtyp  := (others=>'0');
521
    icamax := (others=>'0');
522
    itamax := (others=>'0');
523
    isamax := (others=>'0');
524
 
525
    ined   := '0';
526
    icerm  := '0';
527
 
528
    iclrreg := '0';
529
 
530
    iscinc  := '0';
531
 
532
    -- ibus address decoder, accept only offsets 0 to ibaddr_cs3
533
    n.ibsel := '0';
534
    if IB_MREQ.aval = '1' and
535
       IB_MREQ.addr(12 downto 6) = ibaddr_rhrp(12 downto 6) and
536 31 wfjm
       unsigned(IB_MREQ.addr(5 downto 1)) <= unsigned(ibaddr_cs3) then
537 30 wfjm
      n.ibsel := '1';
538
    end if;
539
 
540
    -- internal state machine
541
    case r.state is
542
      when s_idle =>                    -- idle: handle ibus -----------------
543
 
544
        if r.ibsel='1' then               -- selected
545
 
546
          -- determine effective unit number
547
          if ibrem = '1' then
548
            ieunit := r.runit;
549
          else
550
            ieunit := r.cs2unit;
551
          end if;
552
          n.eunit := ieunit;
553
 
554
          -- determine drive properties (always via iunit) FIXME: correct ??
555
          idte(2) := r.dtrm(to_integer(unsigned(r.cs2unit)));
556
          idte(1) := r.dte1(to_integer(unsigned(r.cs2unit)));
557
          idte(0) := r.dte0(to_integer(unsigned(r.cs2unit)));
558
          case idte is
559
            when dte_rp04 =>            -- RP04
560
              idtyp  := rp04_dtyp;
561
              icamax := rp04_camax;
562
              itamax := rp04_tamax;
563
              isamax := rp04_samax;
564
            when dte_rp06 =>            -- RP06
565
              idtyp  := rp06_dtyp;
566
              icamax := rp06_camax;
567
              itamax := rp06_tamax;
568
              isamax := rp06_samax;
569
            when dte_rm03 =>            -- RM03
570
              idtyp  := rm03_dtyp;
571
              icamax := rm03_camax;
572
              itamax := rm03_tamax;
573
              isamax := rm03_samax;
574
            when dte_rm80 =>            -- RM80
575
              idtyp  := rm80_dtyp;
576
              icamax := rm80_camax;
577
              itamax := rm80_tamax;
578
              isamax := rm80_samax;
579
            when dte_rm05 =>            -- RM05
580
              idtyp  := rm05_dtyp;
581
              icamax := rm05_camax;
582
              itamax := rm05_tamax;
583
              isamax := rm05_samax;
584
            when dte_rp07 =>            -- RP07
585
              idtyp  := rp07_dtyp;
586
              icamax := rp07_camax;
587
              itamax := rp07_tamax;
588
              isamax := rp07_samax;
589
            when others =>
590
              idtyp  := (others=>'0');
591
              icamax := (others=>'0');
592
              itamax := (others=>'0');
593
              isamax := (others=>'0');
594
          end case; -- case idte
595
          n.dtyp  := idtyp;
596
          n.camax := icamax;
597
          n.tamax := itamax;
598
          n.samax := isamax;
599
 
600 32 wfjm
          -- consider drive non-existent if not 'DPR' or unit>=4 selected
601 30 wfjm
          if r.dsdpr(to_integer(unsigned(r.cs2unit))) = '0' or
602
             r.cs2unit2 = '1' then
603
            ined := '1';
604
          end if;
605
          n.ned := ined;
606
 
607
          icerm   := r.dtrm(to_integer(unsigned(ieunit)));
608
          n.cerm  := icerm;
609
 
610
          -- setup mapper 
611
          case IB_MREQ.addr(5 downto 1) is
612
 
613
            when ibaddr_cs1  =>             -- RxCS1 control reg 1 
614
              -- cs1 not flagged mbreg !! ned handling done explicitely
615
              iamap  := ieunit & amapc_cs1;
616
              iomux  := omux_cs1;
617
 
618
            when ibaddr_wc   =>             -- RxWC  word count 
619
              iamap  := amapr_wc & amapc_ext;
620
              iomux  := omux_mem;
621
 
622
            when ibaddr_ba   =>             -- RxBA  bus address 
623
              imask  := "1111111111111110";     -- lsb ignored
624
              iamap  := amapr_ba & amapc_ext;
625
              iomux  := omux_mem;
626
 
627
            when ibaddr_da   =>             -- RxDA  disk address 
628
              imask  := "0001111100111111";    -- 000t tttt 00ss ssss
629
              iamap  := ieunit & amapc_da;
630
              iomux  := omux_mem;
631
              imbreg := '1';                   -- mb 5
632
 
633
            when ibaddr_cs2  =>             -- RxCS2 control reg 2
634
              iomux  := omux_cs2;
635
 
636
            when ibaddr_ds   =>             -- RxDS  drive status 
637
              iomux  := omux_ds;
638
              imbreg := '1';                   -- mb 1
639
 
640
            when ibaddr_er1  =>             -- RxER1 error status 1 
641
              iomux  := omux_er1;
642
              imbreg := '1';                  -- mb 2
643
 
644
            when ibaddr_as   =>             -- RxAS  attention summary 
645
              iomux  := omux_as;
646
              imbreg := '1';                  -- mb 4
647
              inormr := '1';                  -- AS writes allowed when RDY=0
648
 
649
            when ibaddr_la   =>             -- RxLA  look ahead 
650
              iomux  := omux_la;
651
              imbreg := '1';                  -- mb 7
652
 
653
            when ibaddr_db   =>             -- RxDB  data buffer 
654
              iamap  := amapr_db & amapc_ext;
655
              iomux  := omux_mem;
656
 
657
            when ibaddr_mr1  =>             -- RxMR1 maintenance reg 1 
658
              iamap  := ieunit & amapc_mr1;
659
              iomux  := omux_mem;
660
              imbreg := '1';                  -- mb 3
661
              inormr := '1';                  -- MR1 writes allowed when RDY=0
662
 
663
            when ibaddr_dt   =>             -- RxDT  drive type 
664
              iomux  := omux_dt;
665
              imbreg := '1';                  -- mb 6
666
 
667
            when ibaddr_sn   =>             -- RxSN  serial number 
668
              iomux  := omux_sn;
669
              imbreg := '1';                  -- mb 10
670
 
671
            when ibaddr_of   =>             -- RxOF  offset reg 
672
              imask  := "0001110011111111";   -- 000f eh00 d??? ????
673
              iamap  := ieunit & amapc_of;
674
              iomux  := omux_mem;
675
              imbreg := '1';                  -- mb 11
676
 
677
            when ibaddr_dc   =>             -- RxDC  desired cylinder 
678
              imask  := "0000001111111111";   -- 0000 00cc cccc cccc
679
              iamap  := ieunit & amapc_dc;
680
              iomux  := omux_mem;
681
              imbreg := '1';                  -- mb 12
682
 
683
            when ibaddr_m13  =>
684
              if icerm = '1' then
685
                iamap := ieunit & amapc_hr;  -- RMHR  holding reg
686
              else
687
                iamap := ieunit & amapc_dc;  -- RPDC  current cylinder
688
              end if;
689
              iomux  := omux_mem;
690
              imbreg := '1';                   -- mb 13
691
 
692
            when ibaddr_m14  =>
693
              if icerm = '1' then
694
                iamap := ieunit & amapc_mr2; -- RMMR2 maintenance reg 2
695
                iomux := omux_mem;
696
              else
697
                iomux := omux_zero;            -- RPER2 error status 2
698
              end if;
699
              imbreg := '1';                  -- mb 14
700
 
701
            when ibaddr_m15  =>             -- RxER3 error status 3/2
702
              iomux  := omux_zero;
703
              imbreg := '1';                  -- mb 15
704
 
705
            when ibaddr_ec1  =>             -- RxEC1 ecc status 1 
706
              iomux  := omux_zero;
707
              imbreg := '1';                  -- mb 16
708
 
709
            when ibaddr_ec2  =>             -- RxEC2 ecc status 2 
710
              iomux  := omux_zero;
711
              imbreg := '1';                  -- mb 17
712
 
713
            when ibaddr_bae  =>             -- RxBAE bus addr extension
714
              iomux  := omux_bae;
715
 
716
            when ibaddr_cs3  =>             -- RxCS3 control reg 3 
717
              iomux  := omux_cs3;
718
 
719 31 wfjm
            when others => null;            -- doesn't happen, ibsel only for
720
                                            -- subrange up to cs3, and all
721
                                            -- 22 regs are decoded above
722 30 wfjm
 
723
          end case; -- case IB_MREQ.addr
724
          n.amap   := iamap;
725
          n.omux   := iomux;
726
          n.dinmsk := imask and IB_MREQ.din;
727
 
728
          if IB_MREQ.we = '1' then          -- write request
729
            ibhold := '1';                    -- assume follow-up state taken
730
            case IB_MREQ.addr(5 downto 1) is
731
 
732
              when ibaddr_cs1  => n.state := s_wcs1;   -- RxCS1
733
              when ibaddr_wc   => n.state := s_wmembe; -- RxWC
734
              when ibaddr_ba   => n.state := s_wmembe; -- RxBA
735
              when ibaddr_da   => n.state := s_wmem;   -- RxDA
736
              when ibaddr_cs2  => n.state := s_wcs2;   -- RxCS2
737
              when ibaddr_ds   => n.state := s_wds;    -- RxDS  (read-only)
738
              when ibaddr_er1  => n.state := s_wer1;   -- RxER1 (read-only)
739
              when ibaddr_as   => n.state := s_was;    -- RxAS
740
              when ibaddr_la   => n.state := s_whr;    -- RxLA  (read-only)
741
              when ibaddr_db   => n.state := s_wmembe; -- RxDB
742
              when ibaddr_mr1  => n.state := s_wmem;   -- RxMR1
743
              when ibaddr_dt   => n.state := s_wdt;    -- RxDT  (read-only)
744
              when ibaddr_sn   => n.state := s_whr;    -- RxSN  (read-only)
745
              when ibaddr_of   => n.state := s_wmem;   -- RxOF
746
              when ibaddr_dc   => n.state := s_wmem;   -- RxDC
747
              when ibaddr_m13  => n.state := s_whr;    -- RPCC|RMHR (fits both)
748
              when ibaddr_m14  =>
749
                if icerm = '1' then
750
                  n.state := s_wmem;                   -- RMMR2
751
                else
752
                  n.state := s_whr;                    -- RPER2
753
                end if;
754
              when ibaddr_m15  => n.state := s_whr;    -- RPER3|RMER2 (fits both)
755
              when ibaddr_ec1  => n.state := s_whr;    -- RxEC1
756
              when ibaddr_ec2  => n.state := s_whr;    -- RxEC2
757
              when ibaddr_bae  => n.state := s_wbae;   -- RxBAE
758
              when ibaddr_cs3  => n.state := s_wcs3;   -- RxCS3
759
 
760
              when others => null;           -- doesn't happen, ibsel only for
761
                                             -- subrange up to cs3, and all
762
                                             -- 22 regs are decoded above
763
 
764
            end case; -- case IB_MREQ.addr
765
 
766
            -- some general error catchers
767
            if ibrem = '0' and imbreg='1' then     -- local massbus write
768
                                                   --   for cs1: imbreg=0 !!
769 32 wfjm
              -- write to non-existent drives
770 30 wfjm
              if ined = '1' then
771
                n.cs2ned := '1';
772 32 wfjm
              -- write to a busy unit, can be a search/seek or a transfer
773
              elsif inormr='0' and                   -- rmr protected reg
774
                (r.dspip(to_integer(unsigned(r.cs2unit)))='1' or -- busy pip
775
                 (r.cs1rdy='0' and (r.funit = r.cs2unit))        -- busy xfer
776
                ) then
777 30 wfjm
                n.state := s_setrmr;
778
              end if;
779
            end if;
780
 
781
          elsif IB_MREQ.re = '1' then   -- read request
782 31 wfjm
            if ibrem='0' and imbreg='1' and ined='1' then
783
              n.cs2ned := '1';            -- signal error
784 30 wfjm
            else
785 31 wfjm
              ibhold  := '1';
786
              n.state := s_read;
787 30 wfjm
            end if;
788
 
789
          end if; --  if IB_MREQ.we .. elsif IB_MREQ.re 
790
 
791
        -- BRESET and ITIMER can be handled in the 'else' because both can
792
        -- never come during an ibus transaction. Done here to keep logic
793
        -- path in the 'if' short.
794
        else -- if r.ibsel='1'
795
          if BRESET = '1' then
796
            n.eunit   := "00";
797
            n.clrmode := clrmode_breset;
798
            n.state   := s_oot_clr0;             -- OOT state, no hold!
799
          end if;
800
 
801
          if unsigned(r.idlycnt) = 0 then     -- interrupt delay expired
802
            n.dsata := r.dsata or r.dspip;      -- convert pip's to ata's
803
            n.dspip := (others=>'0');           -- and mark them done
804
          else
805
            if ITIMER = '1' then             -- not expired and ITIMER
806
              n.idlycnt := slv(unsigned(r.idlycnt) - 1); -- count down
807
            end if;
808
          end if;
809
 
810
        end if; -- if r.ibsel='1'
811
 
812
        -- s_idle goes up to here !!
813
 
814
      when s_wcs1 =>                    -- wcs1: write cs1 -------------------
815
        n.state := s_idle;                -- in general return to s_idle
816
        imem_addr := r.amap;              -- use mapped address
817
        imem_din  := r.dinmsk;            -- use masked input
818
 
819
        if ibrem = '0' then               -- loc write access
820
 
821
          if IB_MREQ.be1 = '1' then
822
            if IB_MREQ.din(cs1_ibf_tre) = '1' then  -- TRE=1 -> clear errors
823
              n.cs2wce := '0';
824
              n.cs2ned := '0';
825
              n.cs2nem := '0';
826
              n.cs2pge := '0';
827
              n.cs2mxf := '0';
828
            end if;
829
            if r.cs1rdy = '1' then              -- only if RDY
830
              n.bae(1 downto 0) := IB_MREQ.din(cs1_ibf_bae);  -- update bae
831
            end if;
832
          end if; -- IB_MREQ.be1 = '1'
833
 
834
          if IB_MREQ.be0 = '1' then
835
            n.cs1ie   := IB_MREQ.din(cs1_ibf_ie);
836
            if IB_MREQ.din(cs1_ibf_ie) = '1' and   -- if IE and RDY both 1
837
               IB_MREQ.din(cs1_ibf_rdy) = '1'then
838
              n.ireq := '1';                         -- issue software interrupt
839
            end if;
840
 
841 32 wfjm
            if r.ned = '0' and                     -- drive on
842
               IB_MREQ.din(cs1_ibf_go) = '1' then  -- GO bit set
843
              ibhold  :=    '1';
844
              n.state := s_funcchk;
845
            end if;
846 30 wfjm
 
847 32 wfjm
            -- FIXME_code: that's likely not fully correct, cs1 func bits are
848
            --   stored before all error checks are done...
849 30 wfjm
            imem_we0 := IB_MREQ.be0;            -- remember func field per unit
850 32 wfjm
 
851 30 wfjm
            if r.ned = '1' then                 -- loc access and drive off
852
              n.cs2ned := '1';                    -- signal error
853
            end if;
854
 
855
          end if; -- IB_MREQ.be0 = '1'
856
 
857
        else                              -- rem write access. GO not checked
858
                                          --   always treated as remote function
859
          case IB_MREQ.din(cs1_ibf_func) is
860
 
861
            when rfunc_wunit =>             -- rfunc: wunit ---------------
862
              n.runit := IB_MREQ.din(cs1_ibf_runit);
863
 
864
            when rfunc_cunit =>             -- rfunc: cunit ---------------
865
              n.runit := r.funit;             -- use unit from last ext func go
866
 
867
            when rfunc_done  =>             -- rfunc: done ----------------
868
              n.cs1rdy := '1';
869
              if IB_MREQ.din(cs1_ibf_rata) = '0' then
870
                n.ireq   := r.cs1ie;          -- yes, ireq is set from ie !!
871
              else
872
                n.dsata(to_integer(unsigned(r.funit))) := '1';
873
              end if;
874
 
875
            when rfunc_widly =>             -- rfunc: widly ---------------
876
              n.idlyval := IB_MREQ.din(cs1_ibf_ridly);
877
 
878
            when others => null;
879
 
880
          end case;
881
        end if;
882
 
883
      when s_wcs2 =>                    -- wcs2: write cs2 -------------------
884
        n.state := s_idle;                -- in general return to s_idle
885
        if ibrem = '1' then                 -- rem access
886
          n.cs3wco := IB_MREQ.din(cs2_ibf_rwco);  -- cs3.wco rem set via cs2 !!
887
          n.cs2wce := IB_MREQ.din(cs2_ibf_wce);
888
          n.cs2nem := IB_MREQ.din(cs2_ibf_nem);
889
          n.cs2mxf := IB_MREQ.din(cs2_ibf_mxf);  -- FIXME: really used ???
890
        else
891
          if IB_MREQ.be0 = '1' then
892
            n.cs2pat   := IB_MREQ.din(cs2_ibf_pat);
893
            n.cs2bai   := IB_MREQ.din(cs2_ibf_bai);
894
            n.cs2unit2 := IB_MREQ.din(cs2_ibf_unit2);
895
            n.cs2unit  := IB_MREQ.din(cs2_ibf_unit);
896
            if IB_MREQ.din(cs2_ibf_clr) = '1' then
897
              n.eunit   := "00";
898
              n.clrmode := clrmode_cs2clr;
899
              n.state   := s_oot_clr0;             -- OOT state, no hold!
900
            end if;
901
          end if;
902
        end if;
903
 
904
      when s_wcs3 =>                    -- wcs3: write cs3 -------------------
905
        n.state := s_idle;                -- in general return to s_idle
906
        if ibrem = '0' then                 -- loc access
907
          if IB_MREQ.be0 = '1' then
908
            n.cs1ie  := IB_MREQ.din(cs3_ibf_ie);
909
          end if;
910
        end if;
911
 
912
      when s_wer1 =>                    -- wer1: write er1 (rem only) --------
913
        n.state := s_idle;                -- in general return to s_idle
914
        if ibrem = '1' then               -- rem access
915
          if IB_MREQ.din(er1_ibf_uns) = '1' then
916
            n.er1uns(to_integer(unsigned(r.eunit))) := '1';
917
          end if;
918
          if IB_MREQ.din(er1_ibf_wle) = '1' then
919
            n.er1wle(to_integer(unsigned(r.eunit))) := '1';
920
          end if;
921
          if IB_MREQ.din(er1_ibf_iae) = '1' then
922
            n.er1iae(to_integer(unsigned(r.eunit))) := '1';
923
          end if;
924
          if IB_MREQ.din(er1_ibf_aoe) = '1' then
925
            n.er1aoe(to_integer(unsigned(r.eunit))) := '1';
926
          end if;
927
          if IB_MREQ.din(er1_ibf_ilf) = '1' then
928
            n.er1ilf(to_integer(unsigned(r.eunit))) := '1';
929
          end if;
930
        else                              -- loc access
931
          ibhold  := '1';
932
          n.state := s_whr;
933
        end if;
934
 
935
      when s_was =>                     -- was: write as ---------------------
936
        n.state := s_idle;                -- in general return to s_idle
937
        -- clear the attention bits marked as '1' in data word (loc and rem !!)
938
        n.dsata := r.dsata and not IB_MREQ.din(r.dsata'range);
939
        if ibrem = '0' then               -- loc access
940
          ibhold  := '1';
941
          n.state := s_whr;
942
        end if;
943
 
944
      when s_wdt =>                     -- wdt: write dt ---------------------
945
        n.state := s_idle;                -- in general return to s_idle
946
        if ibrem = '1' then               -- rem access
947
          n.dtrm(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_rm);
948
          n.dte1(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e1);
949
          n.dte0(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e0);
950
          n.state := s_idle;
951
        else                              -- loc access
952
          ibhold  := '1';
953
          n.state := s_whr;
954
        end if;
955
 
956
      when s_wds =>                     -- wdt: write ds ---------------------
957
        n.state := s_idle;                -- in general return to s_idle
958
        if ibrem = '1' then               -- rem access
959
          n.dsmol(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_mol);
960
          n.dswrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_wrl);
961
          n.dslbt(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_lbt);
962
          n.dsdpr(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_dpr);
963
          if IB_MREQ.din(ds_ibf_ata) = '1' then -- set ata on demand
964
            n.dsata(to_integer(unsigned(r.runit))) := '1';
965
          end if;
966
          if IB_MREQ.din(ds_ibf_vv) = '1' then  -- clr vv on demand
967
            n.dsvv(to_integer(unsigned(r.runit))) := '0';
968
          end if;
969
          if IB_MREQ.din(ds_ibf_erp) = '1'  then -- clr er1 on demand
970
            n.er1uns(to_integer(unsigned(r.eunit))) := '0';  -- clr all er1
971
            n.er1wle(to_integer(unsigned(r.eunit))) := '0';  -- "
972
            n.er1iae(to_integer(unsigned(r.eunit))) := '0';  -- "
973
            n.er1aoe(to_integer(unsigned(r.eunit))) := '0';  -- "
974
            n.er1rmr(to_integer(unsigned(r.eunit))) := '0';  -- "
975
            n.er1ilf(to_integer(unsigned(r.eunit))) := '0';  -- "
976
          end if;
977
          n.state := s_idle;
978
        else                              -- loc access
979
          ibhold  := '1';                   -- read-only reg, thus noop
980
          n.state := s_whr;
981
        end if;
982
 
983
      when s_wbae =>                    -- wbae: write bae -------------------
984
        n.state := s_idle;                -- in general return to s_idle
985
        if IB_MREQ.be0 = '1' then
986
          n.bae := IB_MREQ.din(bae_ibf_bae);
987
        end if;
988
 
989
      when s_wmem =>                    -- wmem: write mem (DA,MR1,OF,DC,MR2)-
990
        --  this state only handles massbus registers
991
        n.state := s_idle;                -- in general return to s_idle
992
        imem_addr := r.amap;              -- use mapped address
993
        imem_din  := r.dinmsk;            -- use masked input
994
 
995
        if ibrem = '0' then               -- loc access
996
          imem_we0 := '1';                  -- write memory
997
          imem_we1 := '1';
998
          ibhold  := '1';
999
          n.state := s_whr;
1000
        else                              -- rem access
1001
          imem_we0 := '1';                  -- write memory
1002
          imem_we1 := '1';
1003
        end if;
1004
 
1005
      when s_wmembe =>                  -- wmem: write mem with be (WC,BA,DB)-
1006
        -- this state only handles controller registers --> no ned checking
1007
        n.state := s_idle;                -- in general return to s_idle
1008
        imem_we0 := IB_MREQ.be0;
1009
        imem_we1 := IB_MREQ.be1;
1010
        imem_addr := r.amap;
1011
        imem_din  := r.dinmsk;
1012
 
1013
      when s_whr =>                     -- whr: write hr ---------------------
1014
        n.state := s_idle;                -- in general return to s_idle
1015
        imem_addr := r.cs2unit & amapc_hr;  -- mem address of holding reg
1016
        imem_din  := not IB_MREQ.din;
1017
        if ibrem = '0' then               -- loc access
1018
          imem_we0 := '1';                  -- keep state
1019
          imem_we1 := '1';
1020
        end if;
1021
 
1022 32 wfjm
      when s_funcchk =>                 -- funcchk: check function go --------
1023
        n.state := s_idle;                -- in general return to s_idle
1024
        if r.cs1rdy = '0' and
1025
           unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_xfer) then
1026
          n.cs2pge := '1';                    --  issue program error
1027
        elsif IB_MREQ.din(cs1_ibf_func) = func_dclr then
1028
          n.eunit   := r.cs2unit;              -- for follow-up states
1029
          n.clrmode := clrmode_fdclr;
1030
          n.state   := s_oot_clr0;             -- OOT state, no hold!
1031
        elsif r.dserp(to_integer(unsigned(r.cs2unit))) = '1' then
1032
          n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1033
        else
1034
          ibhold  := '1';
1035
          n.state := s_funcgo;
1036
        end if;
1037
 
1038 30 wfjm
      when s_funcgo =>                  -- funcgo: handle function go --------
1039
        n.state := s_idle;                -- in general return to s_idle
1040
        n.dsata(to_integer(unsigned(r.cs2unit))) := '0';
1041
 
1042
        case IB_MREQ.din(cs1_ibf_func) is
1043
          when func_noop =>                    -- func: noop --------------
1044
            null;                                -- nothing done...
1045
 
1046
          when func_pore  =>                   -- func: port release-------
1047
            n.poredone := '1';                   -- take note in done flag
1048
 
1049
          when func_unl   =>                   -- func: unload ------------
1050
                                               -- only for RP, simply clears MOL
1051
            if r.dtrm(to_integer(unsigned(r.cs2unit))) = '0' then
1052
              n.dsmol(to_integer(unsigned(r.cs2unit))) := '0';
1053
              n.dswrl(to_integer(unsigned(r.cs2unit))) := '0';
1054
              n.dsvv(to_integer(unsigned(r.cs2unit)))  := '0';
1055
              n.dsom(to_integer(unsigned(r.cs2unit)))  := '0';
1056
            else
1057
              n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1058
            end if;
1059
            n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
1060
 
1061 32 wfjm
       -- when func_dclr  =>  now handled in funcchk !!
1062 30 wfjm
 
1063
          when func_offs  |                    -- func: offset ------------
1064
               func_retc  =>                   -- func: return to center --
1065
 
1066
            -- currently always immediate completion, so ata set here
1067
            n.dsata(to_integer(unsigned(r.cs2unit)))  := '1';
1068
 
1069
            if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
1070
              n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
1071
            else
1072
              if IB_MREQ.din(cs1_ibf_func) = func_offs then
1073
                n.dsom(to_integer(unsigned(r.cs2unit))) := '1';
1074
              else
1075
                n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
1076
              end if;
1077
            end if;
1078
 
1079
          when func_pres  =>                   -- func: readin preset -----
1080
            n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
1081
            n.eunit   := r.cs2unit;              -- for follow-up states
1082
            n.clrmode := clrmode_fpres;
1083
            n.state   := s_oot_clr0;             -- OOT state, no hold!
1084
 
1085
          when func_pack  =>                   -- func: pack acknowledge --
1086
            n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
1087
            n.packdone := '1';                   -- take note in done flag
1088
 
1089
          -- seek like and data transfer functions
1090
          when func_seek  |                    -- func: seek --------------
1091
               func_recal |                    -- func: recalibrate -------
1092
               func_sear  |                    -- func: search ------------
1093
               func_wcd   |                    -- func: write check data --
1094
               func_wchd  |                    -- func: write check h&d ---
1095
               func_write |                    -- func: write  ------------
1096
               func_whd   |                    -- func: write header&data -
1097
               func_read  |                    -- func: read --------------
1098
               func_rhd   =>                   -- func: read header&data --
1099
 
1100
            if  IB_MREQ.din(cs1_ibf_func) = func_seek then
1101
              n.seekdone := '1';                 -- take note in done flag
1102
            end if;
1103
            if  IB_MREQ.din(cs1_ibf_func) = func_sear then
1104
              n.seardone := '1';                 -- take note in done flag
1105
            end if;
1106
 
1107
            -- check for transfer functions
1108
            n.fxfer := '0';
1109
            if unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_wcd)  then
1110
              n.fxfer := '1';
1111
              -- in case of write, check for write lock
1112
              if IB_MREQ.din(cs1_ibf_func) = func_write or
1113
                 IB_MREQ.din(cs1_ibf_func) = func_whd   then
1114
                if r.dswrl(to_integer(unsigned(r.cs2unit))) = '1' then
1115
                  n.er1wle(to_integer(unsigned(r.cs2unit))) := '1';
1116
                end if;
1117
              end if;
1118
            end if;
1119
 
1120
            if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
1121
              n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
1122
              n.dsata(to_integer(unsigned(r.cs2unit)))  := '1';
1123
            else
1124
              ibhold  := '1';
1125
              n.state := s_chkdc;
1126
            end if;
1127
 
1128
          -- illegal function codes
1129
          when others =>
1130
            n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
1131
            n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
1132
 
1133
        end case; -- IB_MREQ.din(cs1_ibf_func)
1134
 
1135
      when s_chkdc =>                   -- chkdc: handle dc check ------------
1136
        imem_addr := r.cs2unit & amapc_dc; -- mem address of dc reg
1137
        if unsigned(MEM_DOUT(dc_ibf_ca)) > unsigned(r.camax) then
1138
          n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
1139
        end if;
1140
        ibhold  := '1';
1141
        n.state := s_chkda;
1142
 
1143
      when s_chkda =>                   -- chkda: handle da check ------------
1144
        imem_addr := r.cs2unit & amapc_da; -- mem address of da reg
1145
        if unsigned(MEM_DOUT(da_ibf_sa)) > unsigned(r.samax) or
1146
           unsigned(MEM_DOUT(da_ibf_ta)) > unsigned(r.tamax) then
1147
          n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
1148
        end if;
1149
        ibhold  := '1';
1150
        n.state := s_chkdo;
1151
 
1152
      when s_chkdo =>                   -- chkdo: execute function -----------
1153
        if r.er1iae(to_integer(unsigned(r.cs2unit))) = '1' or
1154
           r.er1wle(to_integer(unsigned(r.cs2unit))) = '1' then
1155
          n.dsata(to_integer(unsigned(r.cs2unit))) := '1'; -- ata and done
1156
        else
1157
          if r.fxfer = '0'  then            -- must be seek like function
1158
            n.dspip(to_integer(unsigned(r.cs2unit))) := '1'; -- pip
1159
            n.idlycnt := r.idlyval;                          -- start delay
1160
          else                              -- must be transfer function
1161
            n.ffunc  := IB_MREQ.din(cs1_ibf_func);  -- latch func
1162
            n.funit  := r.cs2unit;                  -- latch unit
1163
            n.cs1rdy := '0';                  -- controller busy
1164
            n.cs2wce := '0';                  -- clear errors
1165
            n.cs2ned := '0';
1166
            n.cs2nem := '0';
1167
            n.cs2pge := '0';
1168
            n.cs2mxf := '0';
1169
            ilam := '1';                      -- issue lam
1170
          end if;
1171
        end if;
1172
        n.state := s_idle;
1173
 
1174
      when s_read =>                    -- read: all register reads ----------
1175
        n.state := s_idle;                -- in general return to s_idle
1176
        imem_addr := r.amap;
1177
 
1178
        case r.omux is
1179
 
1180
          when omux_cs1 =>                -- omux: cs1 reg ---------------
1181
            idout(cs1_ibf_sc)   := r.cs1sc;
1182
            idout(cs1_ibf_tre)  := r.cs1tre;
1183
            idout(cs1_ibf_dva)  := '1';
1184
            idout(cs1_ibf_bae)  := r.bae(1 downto 0);
1185
            idout(cs1_ibf_rdy)  := r.cs1rdy;
1186
            idout(cs1_ibf_ie)   := r.cs1ie;
1187
            if ibrem = '0' then             -- loc access
1188
              idout(cs1_ibf_func) := MEM_DOUT(cs1_ibf_func); --func per unit
1189
              if r.ned = '1' then             -- drive off
1190
                n.cs2ned := '1';                -- signal error
1191
              end if;
1192
            else                            -- rem access
1193
              idout(cs1_ibf_func) := r.ffunc;
1194
            end if;
1195
 
1196
          when omux_cs2 =>                -- omux: cs2 reg ---------------
1197
            idout(cs2_ibf_wce)   := r.cs2wce;
1198
            idout(cs2_ibf_ned)   := r.cs2ned;
1199
            idout(cs2_ibf_nem)   := r.cs2nem;
1200
            idout(cs2_ibf_pge)   := r.cs2pge;
1201
            idout(cs2_ibf_mxf)   := r.cs2mxf;
1202
            idout(cs2_ibf_or)    := '1';
1203
            idout(cs2_ibf_ir)    := '1';
1204
            idout(cs2_ibf_pat)   := r.cs2pat;
1205
            idout(cs2_ibf_bai)   := r.cs2bai;
1206
            idout(cs2_ibf_unit2) := r.cs2unit2;
1207
            if ibrem = '0' then           -- loc access
1208
              idout(cs2_ibf_unit)  := r.cs2unit;
1209
            else                          -- rem access
1210
              idout(cs2_ibf_unit)  := r.funit;
1211
            end if;
1212
 
1213
          when omux_ds =>                 -- omux: ds  reg ---------------
1214
            idout(ds_ibf_ata)  := r.dsata(to_integer(unsigned(r.eunit)));
1215
            idout(ds_ibf_erp)  := r.dserp(to_integer(unsigned(r.eunit)));
1216
            idout(ds_ibf_pip)  := r.dspip(to_integer(unsigned(r.eunit)));
1217
            idout(ds_ibf_mol)  := r.dsmol(to_integer(unsigned(r.eunit)));
1218
            idout(ds_ibf_wrl)  := r.dswrl(to_integer(unsigned(r.eunit)));
1219
            idout(ds_ibf_lbt)  := r.dslbt(to_integer(unsigned(r.eunit)));
1220
            idout(ds_ibf_dpr)  := r.dsdpr(to_integer(unsigned(r.eunit)));
1221
 
1222
            -- ds.dry is 0 if mol=0 or if transfer or seek is active on unit
1223
            -- the logic below checks for the complement ...
1224
            if r.dsmol(to_integer(unsigned(r.eunit))) = '1' then
1225
              if (r.cs1rdy = '1' or r.funit /= r.eunit) and
1226
                 r.dspip(to_integer(unsigned(r.eunit))) = '0' then
1227
                idout(ds_ibf_dry)  := '1';
1228
              end if;
1229
            end if;
1230
 
1231
            idout(ds_ibf_vv)   := r.dsvv (to_integer(unsigned(r.eunit)));
1232
            idout(ds_ibf_om)   := r.dsom (to_integer(unsigned(r.eunit)));
1233
 
1234
          when omux_er1 =>                -- omux: er1 reg ---------------
1235
            idout(er1_ibf_uns)  := r.er1uns(to_integer(unsigned(r.eunit)));
1236
            idout(er1_ibf_wle)  := r.er1wle(to_integer(unsigned(r.eunit)));
1237
            idout(er1_ibf_iae)  := r.er1iae(to_integer(unsigned(r.eunit)));
1238
            idout(er1_ibf_aoe)  := r.er1aoe(to_integer(unsigned(r.eunit)));
1239
            idout(er1_ibf_rmr)  := r.er1rmr(to_integer(unsigned(r.eunit)));
1240
            idout(er1_ibf_ilf)  := r.er1ilf(to_integer(unsigned(r.eunit)));
1241
 
1242
          when omux_as =>                 -- omux: as  reg ---------------
1243
            idout(r.dsata'range) := r.dsata;
1244
 
1245
          when omux_la =>                 -- omux: la  reg ---------------
1246
            idout(la_ibf_sc)    := r.sc;
1247
 
1248
          when omux_dt =>                 -- omux: dt  reg ---------------
1249
            if ibrem = '0' then             -- loc access
1250
              idout(13) := '1';               -- set bit 020000 (movable head)
1251
              idout(r.dtyp'range) := r.dtyp;
1252
            else                            -- rem access (read back rem side)
1253
              idout(dt_ibf_rm) := r.dtrm(to_integer(unsigned(r.runit)));
1254
              idout(dt_ibf_e1) := r.dte1(to_integer(unsigned(r.runit)));
1255
              idout(dt_ibf_e0) := r.dte0(to_integer(unsigned(r.runit)));
1256
            end if;
1257
 
1258
          when omux_sn =>                 -- omux: sn  reg ---------------
1259
            -- the serial number is encoded as 4 digit BCD
1260
            --   digit 3: always 1
1261
            --   digit 2: 1 if RM type; 0 if RP type
1262
            --   digit 1: 0-3 based on encoded drive type
1263 32 wfjm
            --   digit 0: 0-3 taken as complement of unit
1264
            -- Note: the 3lsb are the *complement* of the unit number because
1265
            --       211bsd driver code contains a hack to detect SI and CDC
1266
            --       drives. For those drives the drive type is encode in the
1267
            --       sn register, and one convention is that the 3 lsb of sn
1268
            --       equal the unit numnber. To prevent that the SI/CDC hacks
1269
            --       are actived the 3lsb are set as complement of the unit !
1270 30 wfjm
            idout(12) := '1';
1271
            idout(8)  := r.dtrm(to_integer(unsigned(r.eunit)));
1272
            idout(5)  := r.dte1(to_integer(unsigned(r.eunit)));
1273
            idout(4)  := r.dte0(to_integer(unsigned(r.eunit)));
1274 32 wfjm
            idout(2)  := '1';
1275
            idout(1)  := not r.eunit(1);
1276
            idout(0)  := not r.eunit(0);
1277 30 wfjm
 
1278
          when omux_bae =>                -- omux: bae reg ---------------
1279
            idout(bae_ibf_bae) := r.bae;
1280
 
1281
          when omux_cs3 =>                -- omux: cs3 reg ---------------
1282
            idout(cs3_ibf_wco) := r.cs2wce and     r.cs3wco;
1283
            idout(cs3_ibf_wce) := r.cs2wce and not r.cs3wco;
1284
            idout(cs3_ibf_ie)  := r.cs1ie;
1285
            if ibrem = '1' then             -- rem access
1286
              idout(cs3_ibf_rseardone) := r.seardone;
1287
              idout(cs3_ibf_rpackdone) := r.packdone;
1288
              idout(cs3_ibf_rporedone) := r.poredone;
1289
              idout(cs3_ibf_rseekdone) := r.seekdone;
1290
              if IB_MREQ.re = '1' then        -- if read, do read & clear
1291
                n.seardone := '0';
1292
                n.packdone := '0';
1293
                n.poredone := '0';
1294
                n.seekdone := '0';
1295
              end if;
1296
            end if;
1297
 
1298
          when omux_mem =>                -- omux: mem output ------------
1299
            idout := MEM_DOUT;
1300
 
1301
          when omux_zero =>               -- omux: zero ------------------
1302
            idout := (others=>'0');
1303
 
1304
          when others => null;            -- nxr caught before in mapper !
1305
        end case;  -- case r.omux
1306
 
1307
      when s_setrmr =>                    -- set rmr flag ----------------------
1308
        n.er1rmr(to_integer(unsigned(r.cs2unit))) := '1';
1309
        n.state := s_idle;
1310
 
1311
      when s_oot_clr0 =>                  -- OOT clr0: state 0 -----------------
1312
        if r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr then
1313
          n.cs1rdy   := '1';                 -- clear cs1
1314
          n.cs1ie    := '0';
1315
          n.cs2wce   := '0';                 -- clear cs2
1316
          n.cs2ned   := '0';
1317
          n.cs2nem   := '0';
1318
          n.cs2pge   := '0';
1319
          n.cs2mxf   := '0';
1320
          n.cs2pat   := '0';
1321
          n.cs2bai   := '0';
1322
          n.cs2unit2 := '0';
1323
          n.cs2unit  := (others=>'0');
1324
          n.bae      := (others=>'0');       -- clear bae
1325
          n.ireq     := '0';                 -- clear iff
1326
        end if;
1327
 
1328
        if r.clrmode=clrmode_breset or r.clrmode=clrmode_fdclr then
1329
          n.er1uns(to_integer(unsigned(r.eunit))) := '0';  -- clr all er1
1330
          n.er1wle(to_integer(unsigned(r.eunit))) := '0';  -- "
1331
          n.er1iae(to_integer(unsigned(r.eunit))) := '0';  -- "
1332
          n.er1aoe(to_integer(unsigned(r.eunit))) := '0';  -- "
1333
          n.er1rmr(to_integer(unsigned(r.eunit))) := '0';  -- "
1334
          n.er1ilf(to_integer(unsigned(r.eunit))) := '0';  -- "
1335
        end if;
1336
 
1337
        n.cerm  := r.dtrm(to_integer(unsigned(ieunit)));
1338
 
1339
        n.clrreg := "000";
1340
        ibhold  := r.ibsel;                -- delay pending request
1341
        n.state := s_oot_clr1;
1342
 
1343
      when s_oot_clr1 =>                  -- OOT clr1: state 1 ----------------
1344
        imem_addr := r.eunit & r.clrreg;
1345
        imem_din  := (others=>'0');
1346
 
1347
        iclrreg := '0';
1348
        case r.clrmode is
1349
 
1350
          when clrmode_breset =>        -- BRESET -------------------------
1351
            iclrreg := '1';               -- simply clear all (cntl+drives)
1352
 
1353
          when clrmode_cs2clr =>        -- CS2.CLR (controller clr) -------
1354
            case r.clrreg is
1355
              when amapc_ext => iclrreg := '1';
1356
              when amapc_mr1 => iclrreg := r.cerm;
1357
              when others => null;
1358
            end case;
1359
 
1360
          when clrmode_fdclr =>         -- func=DCLR (drive clr) ----------
1361
            case r.clrreg is
1362
              when amapc_mr1 => iclrreg := r.cerm;
1363
              when others => null;
1364
            end case;
1365
 
1366
          when clrmode_fpres =>         -- func=PRESET --------------------
1367
            case r.clrreg is
1368
              when amapc_da  => iclrreg := '1';
1369
              when amapc_of  => iclrreg := '1';
1370
              when amapc_dc  => iclrreg := '1';
1371
              when others => null;
1372
            end case;
1373
 
1374
          when others => null;
1375
        end case;
1376
        if iclrreg = '1' then
1377
          imem_we0 := IB_MREQ.be0;
1378
          imem_we1 := IB_MREQ.be1;
1379
        end if;
1380
        n.clrreg := slv(unsigned(r.clrreg) + 1);
1381
 
1382
        ibhold := r.ibsel;                   -- delay pending request
1383
        if r.clrreg = "111" then             -- if last register done
1384
          n.state := s_oot_clr2;               -- proceed with clr2
1385
        end if;
1386
 
1387
      when s_oot_clr2 =>                  -- OOT clr2: state 2 ----------------
1388
        n.eunit := slv(unsigned(r.eunit) + 1);
1389
 
1390
        ibhold := r.ibsel;                   -- delay pending request, so that
1391
                                             -- s_idle can finally process it
1392
        if (r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr) and
1393
           r.eunit /= "11" then
1394
          n.state := s_oot_clr0;
1395
        else
1396
          n.state := s_idle;
1397
        end if;
1398
 
1399
      when others => null;                -- <> ------------------------------
1400
    end case;  -- case r.state
1401
 
1402
    -- update cs1tre and cs1sc
1403
    n.cs1tre := r.cs2wce or r.cs2ned or r.cs2nem or r.cs2pge or r.cs2mxf;
1404
    n.cs1sc  := n.cs1tre or r.dsata(0) or r.dsata(1) or r.dsata(2) or r.dsata(3);
1405
    -- update dserp
1406
    n.dserp  := r.er1uns or -- or all er1
1407
                r.er1wle or -- "
1408
                r.er1iae or -- "
1409
                r.er1aoe or -- "
1410
                r.er1rmr or -- "
1411
                r.er1ilf;   -- "
1412
 
1413
    -- handle current sector counter (for RxLA emulation)
1414
    -- advance every 128 usec, so generate a pulse every 128 usec
1415
    if CE_USEC = '1' then
1416
      n.uscnt := slv(unsigned(r.uscnt) + 1);
1417
      if unsigned(r.uscnt) = 0 then
1418
        iscinc := '1';
1419
      end if;
1420
    end if;
1421
 
1422
    -- if current sector larger or equal highest sector wrap to zero
1423
    -- note: iscinc is also '1' when unit changes, this ensures that
1424
    --       the sector counter is always in range when read to ibus.
1425
    if iscinc = '1' then
1426
      if unsigned(r.sc) >= unsigned(r.samax) then
1427
        n.sc := (others=>'0');
1428
      else
1429
        n.sc := slv(unsigned(r.sc) + 1);
1430
      end if;
1431
    end if;
1432
 
1433
    -- the RH70 interrupt logic is very unusual
1434
    --  1. done interrupts (rdy 0->1) are edge sensitive (via r.ireq)
1435
    --  2. done interrupts are not canceled when IE is cleared
1436
    --  3. attention interrupts are level sensitive      (via r.cs1sc)
1437
    --  4. IE is disabled on interrupt acknowledge
1438
 
1439
    iei_req := r.ireq or (r.cs1sc and r.cs1ie and r.cs1rdy);
1440
 
1441
    if EI_ACK = '1'  then               -- interrupt executed
1442
      n.ireq  := '0';                      -- cancel request
1443
      n.cs1ie := '0';                      -- disable interrupts
1444
    end if;
1445
 
1446
    N_REGS <= n;
1447
 
1448
    MEM_0_WE <= imem_we0;
1449
    MEM_1_WE <= imem_we1;
1450
    MEM_ADDR <= imem_addr;
1451
    MEM_DIN  <= imem_din;
1452
 
1453
    IB_SRES.dout <= idout;
1454
    IB_SRES.ack  <= r.ibsel and ibreq;
1455
    IB_SRES.busy <= ibhold  and ibreq;
1456
 
1457
    RB_LAM <= ilam;
1458
    EI_REQ <= iei_req;
1459
 
1460
  end process proc_next;
1461
 
1462
 
1463
end syn;

powered by: WebSVN 2.1.0

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