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;
|