-- $Id: ibdr_rhrp.vhd 692 2015-06-21 11:53:24Z mueller $
|
-- $Id: ibdr_rhrp.vhd 692 2015-06-21 11:53:24Z mueller $
|
--
|
--
|
-- Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
-- Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
--
|
--
|
-- This program is free software; you may redistribute and/or modify it under
|
-- This program is free software; you may redistribute and/or modify it under
|
-- the terms of the GNU General Public License as published by the Free
|
-- the terms of the GNU General Public License as published by the Free
|
-- Software Foundation, either version 2, or at your option any later version.
|
-- Software Foundation, either version 2, or at your option any later version.
|
--
|
--
|
-- This program is distributed in the hope that it will be useful, but
|
-- This program is distributed in the hope that it will be useful, but
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
-- for complete details.
|
-- for complete details.
|
--
|
--
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
-- Module Name: ibdr_rhrp - syn
|
-- Module Name: ibdr_rhrp - syn
|
-- Description: ibus dev(rem): RHRP
|
-- Description: ibus dev(rem): RHRP
|
--
|
--
|
-- Dependencies: ram_1swar_gen
|
-- Dependencies: ram_1swar_gen
|
-- Test bench: -
|
-- Test bench: -
|
-- Target Devices: generic
|
-- Target Devices: generic
|
-- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31
|
-- Tool versions: ise 14.7; viv 2014.4; ghdl 0.31
|
--
|
--
|
-- Synthesized (xst):
|
-- Synthesized (xst):
|
-- Date Rev ise Target flop lutl lutm slic t peri
|
-- Date Rev ise Target flop lutl lutm slic t peri
|
-- 2015-06-20 692 14.7 131013 xc6slx16-2 212 406 8 142 s 8.7
|
-- 2015-06-20 692 14.7 131013 xc6slx16-2 212 406 8 142 s 8.7
|
-- 2015-05-14 680 14.7 131013 xc6slx16-2 211 408 8 131 s 8.8
|
-- 2015-05-14 680 14.7 131013 xc6slx16-2 211 408 8 131 s 8.8
|
-- 2015-04-06 664 14.7 131013 xc6slx16-2 177 331 8 112 s 8.7
|
-- 2015-04-06 664 14.7 131013 xc6slx16-2 177 331 8 112 s 8.7
|
--
|
--
|
-- Revision History:
|
-- Revision History:
|
-- Date Rev Version Comment
|
-- Date Rev Version Comment
|
-- 2015-06-20 692 1.0.3 BUGFIX: fix func-go when drive/init busy checks
|
-- 2015-06-20 692 1.0.3 BUGFIX: fix func-go when drive/init busy checks
|
-- 2015-06-05 690 1.0.2 use 'not unit' for lsb of rpsn to avoid SI detect
|
-- 2015-06-05 690 1.0.2 use 'not unit' for lsb of rpsn to avoid SI detect
|
-- BUGFIX: set rmr only for write to busy unit
|
-- BUGFIX: set rmr only for write to busy unit
|
-- 2015-05-15 682 1.0.1 correct ibsel range select logic
|
-- 2015-05-15 682 1.0.1 correct ibsel range select logic
|
-- 2015-05-14 680 1.0 Initial version
|
-- 2015-05-14 680 1.0 Initial version
|
-- 2015-03-15 658 0.1 First draft
|
-- 2015-03-15 658 0.1 First draft
|
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
|
|
use work.slvtypes.all;
|
use work.slvtypes.all;
|
use work.memlib.all;
|
use work.memlib.all;
|
use work.iblib.all;
|
use work.iblib.all;
|
|
|
-- ----------------------------------------------------------------------------
|
-- ----------------------------------------------------------------------------
|
entity ibdr_rhrp is -- ibus dev(rem): RH+RP
|
entity ibdr_rhrp is -- ibus dev(rem): RH+RP
|
-- fixed address: 176700
|
-- fixed address: 176700
|
port (
|
port (
|
CLK : in slbit; -- clock
|
CLK : in slbit; -- clock
|
CE_USEC : in slbit; -- usec pulse
|
CE_USEC : in slbit; -- usec pulse
|
BRESET : in slbit; -- ibus reset
|
BRESET : in slbit; -- ibus reset
|
ITIMER : in slbit; -- instruction timer
|
ITIMER : in slbit; -- instruction timer
|
RB_LAM : out slbit; -- remote attention
|
RB_LAM : out slbit; -- remote attention
|
IB_MREQ : in ib_mreq_type; -- ibus request
|
IB_MREQ : in ib_mreq_type; -- ibus request
|
IB_SRES : out ib_sres_type; -- ibus response
|
IB_SRES : out ib_sres_type; -- ibus response
|
EI_REQ : out slbit; -- interrupt request
|
EI_REQ : out slbit; -- interrupt request
|
EI_ACK : in slbit -- interrupt acknowledge
|
EI_ACK : in slbit -- interrupt acknowledge
|
);
|
);
|
|
|
-- by default xst uses a binary encoding for the main fsm.
|
-- by default xst uses a binary encoding for the main fsm.
|
-- that give quite sub-optimal results, so force one-hot
|
-- that give quite sub-optimal results, so force one-hot
|
attribute fsm_encoding : string;
|
attribute fsm_encoding : string;
|
attribute fsm_encoding of ibdr_rhrp : entity is "one-hot";
|
attribute fsm_encoding of ibdr_rhrp : entity is "one-hot";
|
|
|
end entity ibdr_rhrp;
|
end entity ibdr_rhrp;
|
|
|
architecture syn of ibdr_rhrp is
|
architecture syn of ibdr_rhrp is
|
|
|
constant ibaddr_rhrp : slv16 := slv(to_unsigned(8#176700#,16));
|
constant ibaddr_rhrp : slv16 := slv(to_unsigned(8#176700#,16));
|
|
|
-- nam rw mb rp rm storage
|
-- nam rw mb rp rm storage
|
constant ibaddr_cs1 : slv5 := "00000"; -- cs1 rw 0 rpcs1 rmcs1 m d,6+r
|
constant ibaddr_cs1 : slv5 := "00000"; -- cs1 rw 0 rpcs1 rmcs1 m d,6+r
|
constant ibaddr_wc : slv5 := "00001"; -- wc rw - rpwc rmwc m 0,7
|
constant ibaddr_wc : slv5 := "00001"; -- wc rw - rpwc rmwc m 0,7
|
constant ibaddr_ba : slv5 := "00010"; -- ba rw - rpba rmba m 1,7
|
constant ibaddr_ba : slv5 := "00010"; -- ba rw - rpba rmba m 1,7
|
constant ibaddr_da : slv5 := "00011"; -- da rw 5 rpda rmda m d,0
|
constant ibaddr_da : slv5 := "00011"; -- da rw 5 rpda rmda m d,0
|
constant ibaddr_cs2 : slv5 := "00100"; -- cs2 rw - rpcs2 rmcs2 r cs2*
|
constant ibaddr_cs2 : slv5 := "00100"; -- cs2 rw - rpcs2 rmcs2 r cs2*
|
constant ibaddr_ds : slv5 := "00101"; -- ds r- 1 rpds rmds r ds*
|
constant ibaddr_ds : slv5 := "00101"; -- ds r- 1 rpds rmds r ds*
|
constant ibaddr_er1 : slv5 := "00110"; -- er1 rw 2 rper1 rmer1 r er1*
|
constant ibaddr_er1 : slv5 := "00110"; -- er1 rw 2 rper1 rmer1 r er1*
|
constant ibaddr_as : slv5 := "00111"; -- as rw 4 rpas rmas r as*
|
constant ibaddr_as : slv5 := "00111"; -- as rw 4 rpas rmas r as*
|
constant ibaddr_la : slv5 := "01000"; -- la r- 7 rpla rmla r sc
|
constant ibaddr_la : slv5 := "01000"; -- la r- 7 rpla rmla r sc
|
constant ibaddr_db : slv5 := "01001"; -- db r? - rpdb rmdb m 2,7
|
constant ibaddr_db : slv5 := "01001"; -- db r? - rpdb rmdb m 2,7
|
constant ibaddr_mr1 : slv5 := "01010"; -- mr1 rw 3 rpmr1 rmmr1 m d,3
|
constant ibaddr_mr1 : slv5 := "01010"; -- mr1 rw 3 rpmr1 rmmr1 m d,3
|
constant ibaddr_dt : slv5 := "01011"; -- dt r- 6 rpdt rmdt r dt*+map
|
constant ibaddr_dt : slv5 := "01011"; -- dt r- 6 rpdt rmdt r dt*+map
|
constant ibaddr_sn : slv5 := "01100"; -- sn r- 10 rpsn rmsn <map>
|
constant ibaddr_sn : slv5 := "01100"; -- sn r- 10 rpsn rmsn <map>
|
constant ibaddr_of : slv5 := "01101"; -- of rw 11 rpof rmof m d,1
|
constant ibaddr_of : slv5 := "01101"; -- of rw 11 rpof rmof m d,1
|
constant ibaddr_dc : slv5 := "01110"; -- dc rw 12 rpdc rmdc m d,2
|
constant ibaddr_dc : slv5 := "01110"; -- dc rw 12 rpdc rmdc m d,2
|
constant ibaddr_m13 : slv5 := "01111"; -- m13 rw 13 rpcc m =dc!
|
constant ibaddr_m13 : slv5 := "01111"; -- m13 rw 13 rpcc m =dc!
|
-- rw 13 rmhr m d,4
|
-- rw 13 rmhr m d,4
|
constant ibaddr_m14 : slv5 := "10000"; -- m14 rw 14 rper2 =0
|
constant ibaddr_m14 : slv5 := "10000"; -- m14 rw 14 rper2 =0
|
-- rw 14 rmmr2 m d,5
|
-- rw 14 rmmr2 m d,5
|
constant ibaddr_m15 : slv5 := "10001"; -- m15 rw 15 rper3 =0
|
constant ibaddr_m15 : slv5 := "10001"; -- m15 rw 15 rper3 =0
|
-- rw 15 rmer2 =0
|
-- rw 15 rmer2 =0
|
constant ibaddr_ec1 : slv5 := "10010"; -- ec1 r- 16 rpec1 rmec1 =0
|
constant ibaddr_ec1 : slv5 := "10010"; -- ec1 r- 16 rpec1 rmec1 =0
|
constant ibaddr_ec2 : slv5 := "10011"; -- ec1 r- 17 rpec2 rmec2 =0
|
constant ibaddr_ec2 : slv5 := "10011"; -- ec1 r- 17 rpec2 rmec2 =0
|
constant ibaddr_bae : slv5 := "10100"; -- bae rw - rpbae rmbae r bae
|
constant ibaddr_bae : slv5 := "10100"; -- bae rw - rpbae rmbae r bae
|
constant ibaddr_cs3 : slv5 := "10101"; -- cs3 rw - rpcs3 rmcs3 r cs3*
|
constant ibaddr_cs3 : slv5 := "10101"; -- cs3 rw - rpcs3 rmcs3 r cs3*
|
|
|
constant omux_cs1 : slv4 := "0000";
|
constant omux_cs1 : slv4 := "0000";
|
constant omux_cs2 : slv4 := "0001";
|
constant omux_cs2 : slv4 := "0001";
|
constant omux_ds : slv4 := "0010";
|
constant omux_ds : slv4 := "0010";
|
constant omux_er1 : slv4 := "0011";
|
constant omux_er1 : slv4 := "0011";
|
constant omux_as : slv4 := "0100";
|
constant omux_as : slv4 := "0100";
|
constant omux_la : slv4 := "0101";
|
constant omux_la : slv4 := "0101";
|
constant omux_dt : slv4 := "0110";
|
constant omux_dt : slv4 := "0110";
|
constant omux_sn : slv4 := "0111";
|
constant omux_sn : slv4 := "0111";
|
constant omux_bae : slv4 := "1000";
|
constant omux_bae : slv4 := "1000";
|
constant omux_cs3 : slv4 := "1001";
|
constant omux_cs3 : slv4 := "1001";
|
constant omux_mem : slv4 := "1010";
|
constant omux_mem : slv4 := "1010";
|
constant omux_zero : slv4 := "1111";
|
constant omux_zero : slv4 := "1111";
|
|
|
constant amapc_da : slv3 := "000";
|
constant amapc_da : slv3 := "000";
|
constant amapc_mr1 : slv3 := "011";
|
constant amapc_mr1 : slv3 := "011";
|
constant amapc_of : slv3 := "001";
|
constant amapc_of : slv3 := "001";
|
constant amapc_dc : slv3 := "010";
|
constant amapc_dc : slv3 := "010";
|
constant amapc_hr : slv3 := "100";
|
constant amapc_hr : slv3 := "100";
|
constant amapc_mr2 : slv3 := "101";
|
constant amapc_mr2 : slv3 := "101";
|
constant amapc_cs1 : slv3 := "110";
|
constant amapc_cs1 : slv3 := "110";
|
constant amapc_ext : slv3 := "111";
|
constant amapc_ext : slv3 := "111";
|
|
|
constant amapr_wc : slv2 := "00";
|
constant amapr_wc : slv2 := "00";
|
constant amapr_ba : slv2 := "01";
|
constant amapr_ba : slv2 := "01";
|
constant amapr_db : slv2 := "10";
|
constant amapr_db : slv2 := "10";
|
|
|
subtype amap_f_unit is integer range 4 downto 3; -- unit part
|
subtype amap_f_unit is integer range 4 downto 3; -- unit part
|
subtype amap_f_reg is integer range 2 downto 0; -- reg part
|
subtype amap_f_reg is integer range 2 downto 0; -- reg part
|
|
|
constant clrmode_breset : slv2 := "00";
|
constant clrmode_breset : slv2 := "00";
|
constant clrmode_cs2clr : slv2 := "01";
|
constant clrmode_cs2clr : slv2 := "01";
|
constant clrmode_fdclr : slv2 := "10";
|
constant clrmode_fdclr : slv2 := "10";
|
constant clrmode_fpres : slv2 := "11";
|
constant clrmode_fpres : slv2 := "11";
|
|
|
constant cs1_ibf_sc : integer := 15; -- special condition
|
constant cs1_ibf_sc : integer := 15; -- special condition
|
constant cs1_ibf_tre : integer := 14; -- transfer error
|
constant cs1_ibf_tre : integer := 14; -- transfer error
|
constant cs1_ibf_dva : integer := 11; -- drive available
|
constant cs1_ibf_dva : integer := 11; -- drive available
|
subtype cs1_ibf_bae is integer range 9 downto 8; -- bus addr ext (1:0)
|
subtype cs1_ibf_bae is integer range 9 downto 8; -- bus addr ext (1:0)
|
constant cs1_ibf_rdy : integer := 7; -- controller ready
|
constant cs1_ibf_rdy : integer := 7; -- controller ready
|
constant cs1_ibf_ie : integer := 6; -- interrupt enable
|
constant cs1_ibf_ie : integer := 6; -- interrupt enable
|
subtype cs1_ibf_func is integer range 5 downto 1; -- function code
|
subtype cs1_ibf_func is integer range 5 downto 1; -- function code
|
constant cs1_ibf_go : integer := 0; -- interrupt enable
|
constant cs1_ibf_go : integer := 0; -- interrupt enable
|
|
|
constant func_noop : slv5 := "00000"; -- func: noop
|
constant func_noop : slv5 := "00000"; -- func: noop
|
constant func_unl : slv5 := "00001"; -- func: unload
|
constant func_unl : slv5 := "00001"; -- func: unload
|
constant func_seek : slv5 := "00010"; -- func: seek
|
constant func_seek : slv5 := "00010"; -- func: seek
|
constant func_recal : slv5 := "00011"; -- func: recalibrate
|
constant func_recal : slv5 := "00011"; -- func: recalibrate
|
constant func_dclr : slv5 := "00100"; -- func: drive clear
|
constant func_dclr : slv5 := "00100"; -- func: drive clear
|
constant func_pore : slv5 := "00101"; -- func: port release
|
constant func_pore : slv5 := "00101"; -- func: port release
|
constant func_offs : slv5 := "00110"; -- func: offset
|
constant func_offs : slv5 := "00110"; -- func: offset
|
constant func_retc : slv5 := "00111"; -- func: return to center
|
constant func_retc : slv5 := "00111"; -- func: return to center
|
constant func_pres : slv5 := "01000"; -- func: readin preset
|
constant func_pres : slv5 := "01000"; -- func: readin preset
|
constant func_pack : slv5 := "01001"; -- func: pack acknowledge
|
constant func_pack : slv5 := "01001"; -- func: pack acknowledge
|
constant func_sear : slv5 := "01100"; -- func: search
|
constant func_sear : slv5 := "01100"; -- func: search
|
constant func_xfer : slv5 := "10100"; -- used to check for xfer type funcs
|
constant func_xfer : slv5 := "10100"; -- used to check for xfer type funcs
|
constant func_wcd : slv5 := "10100"; -- func: write check data
|
constant func_wcd : slv5 := "10100"; -- func: write check data
|
constant func_wchd : slv5 := "10101"; -- func: write check header&data
|
constant func_wchd : slv5 := "10101"; -- func: write check header&data
|
constant func_write : slv5 := "11000"; -- func: write
|
constant func_write : slv5 := "11000"; -- func: write
|
constant func_whd : slv5 := "11001"; -- func: write header&data
|
constant func_whd : slv5 := "11001"; -- func: write header&data
|
constant func_read : slv5 := "11100"; -- func: read
|
constant func_read : slv5 := "11100"; -- func: read
|
constant func_rhd : slv5 := "11101"; -- func: read header&data
|
constant func_rhd : slv5 := "11101"; -- func: read header&data
|
|
|
constant rfunc_wunit : slv5 := "00001"; -- rem func: write runit
|
constant rfunc_wunit : slv5 := "00001"; -- rem func: write runit
|
constant rfunc_cunit : slv5 := "00010"; -- rem func: copy funit->runit
|
constant rfunc_cunit : slv5 := "00010"; -- rem func: copy funit->runit
|
constant rfunc_done : slv5 := "00011"; -- rem func: done (set rdy)
|
constant rfunc_done : slv5 := "00011"; -- rem func: done (set rdy)
|
constant rfunc_widly : slv5 := "00100"; -- rem func: write idly
|
constant rfunc_widly : slv5 := "00100"; -- rem func: write idly
|
|
|
-- cs1 usage for rem functions
|
-- cs1 usage for rem functions
|
subtype cs1_ibf_runit is integer range 9 downto 8; -- new runit (_wunit)
|
subtype cs1_ibf_runit is integer range 9 downto 8; -- new runit (_wunit)
|
constant cs1_ibf_rata : integer := 8; -- use ata (_done)
|
constant cs1_ibf_rata : integer := 8; -- use ata (_done)
|
subtype cs1_ibf_ridly is integer range 15 downto 8; -- new idly (_widly)
|
subtype cs1_ibf_ridly is integer range 15 downto 8; -- new idly (_widly)
|
|
|
subtype da_ibf_ta is integer range 12 downto 8; -- track addr
|
subtype da_ibf_ta is integer range 12 downto 8; -- track addr
|
subtype da_ibf_sa is integer range 5 downto 0; -- sector addr
|
subtype da_ibf_sa is integer range 5 downto 0; -- sector addr
|
|
|
constant cs2_ibf_rwco : integer := 15; -- rem: write check odd word
|
constant cs2_ibf_rwco : integer := 15; -- rem: write check odd word
|
constant cs2_ibf_wce : integer := 14; -- write check error
|
constant cs2_ibf_wce : integer := 14; -- write check error
|
constant cs2_ibf_ned : integer := 12; -- non-existent drive
|
constant cs2_ibf_ned : integer := 12; -- non-existent drive
|
constant cs2_ibf_nem : integer := 11; -- non-existent memory
|
constant cs2_ibf_nem : integer := 11; -- non-existent memory
|
constant cs2_ibf_pge : integer := 10; -- programming error
|
constant cs2_ibf_pge : integer := 10; -- programming error
|
constant cs2_ibf_mxf : integer := 9; -- missed transfer
|
constant cs2_ibf_mxf : integer := 9; -- missed transfer
|
constant cs2_ibf_or : integer := 7; -- output ready
|
constant cs2_ibf_or : integer := 7; -- output ready
|
constant cs2_ibf_ir : integer := 6; -- input ready
|
constant cs2_ibf_ir : integer := 6; -- input ready
|
constant cs2_ibf_clr : integer := 5; -- clear controller
|
constant cs2_ibf_clr : integer := 5; -- clear controller
|
constant cs2_ibf_pat : integer := 4; -- parity test
|
constant cs2_ibf_pat : integer := 4; -- parity test
|
constant cs2_ibf_bai : integer := 3; -- bus address inhibit
|
constant cs2_ibf_bai : integer := 3; -- bus address inhibit
|
constant cs2_ibf_unit2 : integer := 2; -- unit select msb
|
constant cs2_ibf_unit2 : integer := 2; -- unit select msb
|
subtype cs2_ibf_unit is integer range 1 downto 0; -- unit select
|
subtype cs2_ibf_unit is integer range 1 downto 0; -- unit select
|
|
|
constant ds_ibf_ata : integer := 15; -- attention
|
constant ds_ibf_ata : integer := 15; -- attention
|
constant ds_ibf_erp : integer := 14; -- any errors in er1 or er2
|
constant ds_ibf_erp : integer := 14; -- any errors in er1 or er2
|
constant ds_ibf_pip : integer := 13; -- positioning in progress
|
constant ds_ibf_pip : integer := 13; -- positioning in progress
|
constant ds_ibf_mol : integer := 12; -- medium online (ATTACHED)
|
constant ds_ibf_mol : integer := 12; -- medium online (ATTACHED)
|
constant ds_ibf_wrl : integer := 11; -- write locked
|
constant ds_ibf_wrl : integer := 11; -- write locked
|
constant ds_ibf_lbt : integer := 10; -- last block transfered
|
constant ds_ibf_lbt : integer := 10; -- last block transfered
|
constant ds_ibf_dpr : integer := 8; -- drive present (ENABLED)
|
constant ds_ibf_dpr : integer := 8; -- drive present (ENABLED)
|
constant ds_ibf_dry : integer := 7; -- drive ready
|
constant ds_ibf_dry : integer := 7; -- drive ready
|
constant ds_ibf_vv : integer := 6; -- volume valid
|
constant ds_ibf_vv : integer := 6; -- volume valid
|
constant ds_ibf_om : integer := 0; -- offset mode
|
constant ds_ibf_om : integer := 0; -- offset mode
|
|
|
constant er1_ibf_uns : integer := 14; -- drive unsafe
|
constant er1_ibf_uns : integer := 14; -- drive unsafe
|
constant er1_ibf_wle : integer := 11; -- write lock error
|
constant er1_ibf_wle : integer := 11; -- write lock error
|
constant er1_ibf_iae : integer := 10; -- invalid address error
|
constant er1_ibf_iae : integer := 10; -- invalid address error
|
constant er1_ibf_aoe : integer := 9; -- address overflow error
|
constant er1_ibf_aoe : integer := 9; -- address overflow error
|
constant er1_ibf_rmr : integer := 2; -- register modification refused
|
constant er1_ibf_rmr : integer := 2; -- register modification refused
|
constant er1_ibf_ilf : integer := 0; -- illegal function
|
constant er1_ibf_ilf : integer := 0; -- illegal function
|
|
|
subtype la_ibf_sc is integer range 11 downto 6; -- current sector
|
subtype la_ibf_sc is integer range 11 downto 6; -- current sector
|
|
|
constant dt_ibf_rm : integer := 2; -- rm cntl
|
constant dt_ibf_rm : integer := 2; -- rm cntl
|
constant dt_ibf_e1 : integer := 1; -- encoded type bit 1
|
constant dt_ibf_e1 : integer := 1; -- encoded type bit 1
|
constant dt_ibf_e0 : integer := 0; -- encoded type bit 0
|
constant dt_ibf_e0 : integer := 0; -- encoded type bit 0
|
|
|
constant dte_rp04 : slv3 := "000"; -- encoded dt for rp04 rm=0
|
constant dte_rp04 : slv3 := "000"; -- encoded dt for rp04 rm=0
|
constant dte_rp06 : slv3 := "001"; -- encoded dt for rp06 rm=0
|
constant dte_rp06 : slv3 := "001"; -- encoded dt for rp06 rm=0
|
constant dte_rm03 : slv3 := "100"; -- encoded dt for rm03 rm=1
|
constant dte_rm03 : slv3 := "100"; -- encoded dt for rm03 rm=1
|
constant dte_rm80 : slv3 := "101"; -- encoded dt for rm80 rm=1
|
constant dte_rm80 : slv3 := "101"; -- encoded dt for rm80 rm=1
|
constant dte_rm05 : slv3 := "110"; -- encoded dt for rm05 rm=1
|
constant dte_rm05 : slv3 := "110"; -- encoded dt for rm05 rm=1
|
constant dte_rp07 : slv3 := "111"; -- encoded dt for rp07 rm=1
|
constant dte_rp07 : slv3 := "111"; -- encoded dt for rp07 rm=1
|
|
|
subtype dc_ibf_ca is integer range 9 downto 0; -- cyclinder addr
|
subtype dc_ibf_ca is integer range 9 downto 0; -- cyclinder addr
|
|
|
subtype bae_ibf_bae is integer range 5 downto 0; -- bus addr ext.
|
subtype bae_ibf_bae is integer range 5 downto 0; -- bus addr ext.
|
|
|
constant cs3_ibf_wco : integer := 12; -- write check odd
|
constant cs3_ibf_wco : integer := 12; -- write check odd
|
constant cs3_ibf_wce : integer := 11; -- write check even
|
constant cs3_ibf_wce : integer := 11; -- write check even
|
constant cs3_ibf_ie : integer := 6; -- interrupt enable
|
constant cs3_ibf_ie : integer := 6; -- interrupt enable
|
constant cs3_ibf_rseardone : integer := 3; -- rem: sear done flag
|
constant cs3_ibf_rseardone : integer := 3; -- rem: sear done flag
|
constant cs3_ibf_rpackdone : integer := 2; -- rem: pack done flag
|
constant cs3_ibf_rpackdone : integer := 2; -- rem: pack done flag
|
constant cs3_ibf_rporedone : integer := 1; -- rem: pore done flag
|
constant cs3_ibf_rporedone : integer := 1; -- rem: pore done flag
|
constant cs3_ibf_rseekdone : integer := 0; -- rem: seek done flag
|
constant cs3_ibf_rseekdone : integer := 0; -- rem: seek done flag
|
|
|
-- RP controller type disks
|
-- RP controller type disks
|
constant rp04_dtyp : slv6 := slv(to_unsigned( 8#20#, 6));
|
constant rp04_dtyp : slv6 := slv(to_unsigned( 8#20#, 6));
|
constant rp04_camax : slv10 := slv(to_unsigned( 411-1, 10));
|
constant rp04_camax : slv10 := slv(to_unsigned( 411-1, 10));
|
constant rp04_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rp04_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rp04_samax : slv6 := slv(to_unsigned( 22-1, 6));
|
constant rp04_samax : slv6 := slv(to_unsigned( 22-1, 6));
|
|
|
constant rp06_dtyp : slv6 := slv(to_unsigned( 8#22#, 6));
|
constant rp06_dtyp : slv6 := slv(to_unsigned( 8#22#, 6));
|
constant rp06_camax : slv10 := slv(to_unsigned( 815-1, 10));
|
constant rp06_camax : slv10 := slv(to_unsigned( 815-1, 10));
|
constant rp06_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rp06_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rp06_samax : slv6 := slv(to_unsigned( 22-1, 6));
|
constant rp06_samax : slv6 := slv(to_unsigned( 22-1, 6));
|
|
|
-- RM controller type disks (Note: rp07 has a RM stype controller!)
|
-- RM controller type disks (Note: rp07 has a RM stype controller!)
|
constant rm03_dtyp : slv6 := slv(to_unsigned( 8#24#, 6));
|
constant rm03_dtyp : slv6 := slv(to_unsigned( 8#24#, 6));
|
constant rm03_camax : slv10 := slv(to_unsigned( 823-1, 10));
|
constant rm03_camax : slv10 := slv(to_unsigned( 823-1, 10));
|
constant rm03_tamax : slv5 := slv(to_unsigned( 5-1, 5));
|
constant rm03_tamax : slv5 := slv(to_unsigned( 5-1, 5));
|
constant rm03_samax : slv6 := slv(to_unsigned( 32-1, 6));
|
constant rm03_samax : slv6 := slv(to_unsigned( 32-1, 6));
|
|
|
constant rm80_dtyp : slv6 := slv(to_unsigned( 8#26#, 6));
|
constant rm80_dtyp : slv6 := slv(to_unsigned( 8#26#, 6));
|
constant rm80_camax : slv10 := slv(to_unsigned( 559-1, 10));
|
constant rm80_camax : slv10 := slv(to_unsigned( 559-1, 10));
|
constant rm80_tamax : slv5 := slv(to_unsigned( 14-1, 5));
|
constant rm80_tamax : slv5 := slv(to_unsigned( 14-1, 5));
|
constant rm80_samax : slv6 := slv(to_unsigned( 31-1, 6));
|
constant rm80_samax : slv6 := slv(to_unsigned( 31-1, 6));
|
|
|
constant rm05_dtyp : slv6 := slv(to_unsigned( 8#27#, 6));
|
constant rm05_dtyp : slv6 := slv(to_unsigned( 8#27#, 6));
|
constant rm05_camax : slv10 := slv(to_unsigned( 823-1, 10));
|
constant rm05_camax : slv10 := slv(to_unsigned( 823-1, 10));
|
constant rm05_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rm05_tamax : slv5 := slv(to_unsigned( 19-1, 5));
|
constant rm05_samax : slv6 := slv(to_unsigned( 32-1, 6));
|
constant rm05_samax : slv6 := slv(to_unsigned( 32-1, 6));
|
|
|
constant rp07_dtyp : slv6 := slv(to_unsigned( 8#42#, 6));
|
constant rp07_dtyp : slv6 := slv(to_unsigned( 8#42#, 6));
|
constant rp07_camax : slv10 := slv(to_unsigned( 630-1, 10));
|
constant rp07_camax : slv10 := slv(to_unsigned( 630-1, 10));
|
constant rp07_tamax : slv5 := slv(to_unsigned( 32-1, 5));
|
constant rp07_tamax : slv5 := slv(to_unsigned( 32-1, 5));
|
constant rp07_samax : slv6 := slv(to_unsigned( 50-1, 6));
|
constant rp07_samax : slv6 := slv(to_unsigned( 50-1, 6));
|
|
|
type state_type is (
|
type state_type is (
|
s_idle, -- idle: handle ibus
|
s_idle, -- idle: handle ibus
|
s_wcs1, -- wcs1: write cs1
|
s_wcs1, -- wcs1: write cs1
|
s_wcs2, -- wcs2: write cs2
|
s_wcs2, -- wcs2: write cs2
|
s_wcs3, -- wcs3: write cs3
|
s_wcs3, -- wcs3: write cs3
|
s_wer1, -- wer1: write er1 (rem only)
|
s_wer1, -- wer1: write er1 (rem only)
|
s_was, -- was: write as
|
s_was, -- was: write as
|
s_wdt, -- wdt: write dt (rem only)
|
s_wdt, -- wdt: write dt (rem only)
|
s_wds, -- wdt: write ds (rem only)
|
s_wds, -- wdt: write ds (rem only)
|
s_wbae, -- wbae: write bae
|
s_wbae, -- wbae: write bae
|
s_wmem, -- wmem: write mem (DA,MR1,OF,DC,MR2)
|
s_wmem, -- wmem: write mem (DA,MR1,OF,DC,MR2)
|
s_wmembe, -- wmem: write mem with be (WC,BA,DB)
|
s_wmembe, -- wmem: write mem with be (WC,BA,DB)
|
s_whr, -- whr: write hr (holding reg only)
|
s_whr, -- whr: write hr (holding reg only)
|
s_funcchk, -- funcchk: check function go
|
s_funcchk, -- funcchk: check function go
|
s_funcgo, -- funcgo: handle function go
|
s_funcgo, -- funcgo: handle function go
|
s_chkdc, -- chkdc: handle dc check
|
s_chkdc, -- chkdc: handle dc check
|
s_chkda, -- chksa: handle da check
|
s_chkda, -- chksa: handle da check
|
s_chkdo, -- chkdo: execute function
|
s_chkdo, -- chkdo: execute function
|
s_read, -- read: all register reads
|
s_read, -- read: all register reads
|
s_setrmr, -- set rmr flag
|
s_setrmr, -- set rmr flag
|
s_oot_clr0, -- OOT clr0: state 0
|
s_oot_clr0, -- OOT clr0: state 0
|
s_oot_clr1, -- OOT clr1: state 1
|
s_oot_clr1, -- OOT clr1: state 1
|
s_oot_clr2 -- OOT clr2: state 2
|
s_oot_clr2 -- OOT clr2: state 2
|
);
|
);
|
|
|
type regs_type is record -- state registers
|
type regs_type is record -- state registers
|
ibsel : slbit; -- ibus select
|
ibsel : slbit; -- ibus select
|
state : state_type; -- state
|
state : state_type; -- state
|
amap : slv5; -- mem mapped address
|
amap : slv5; -- mem mapped address
|
omux : slv4; -- omux select
|
omux : slv4; -- omux select
|
dinmsk : slv16; -- mbreq.din masked
|
dinmsk : slv16; -- mbreq.din masked
|
dtrm : slv4; -- dt: drive rm controller
|
dtrm : slv4; -- dt: drive rm controller
|
dte1 : slv4; -- dt: drive type bit 1
|
dte1 : slv4; -- dt: drive type bit 1
|
dte0 : slv4; -- dt: drive type bit 0
|
dte0 : slv4; -- dt: drive type bit 0
|
bae : slv6; -- bae: bus addr extension (in cs1&bae)
|
bae : slv6; -- bae: bus addr extension (in cs1&bae)
|
cs1sc : slbit; -- cs1: special condition
|
cs1sc : slbit; -- cs1: special condition
|
cs1tre : slbit; -- cs1: transfer error
|
cs1tre : slbit; -- cs1: transfer error
|
cs1rdy : slbit; -- cs1: controller ready
|
cs1rdy : slbit; -- cs1: controller ready
|
cs1ie : slbit; -- cs1: interrupt enable
|
cs1ie : slbit; -- cs1: interrupt enable
|
ffunc : slv5; -- func code (frozen on ext func go)
|
ffunc : slv5; -- func code (frozen on ext func go)
|
fxfer : slbit; -- func is xfer
|
fxfer : slbit; -- func is xfer
|
cs2wce : slbit; -- cs2: write check error
|
cs2wce : slbit; -- cs2: write check error
|
cs2ned : slbit; -- cs2: non-existent drive
|
cs2ned : slbit; -- cs2: non-existent drive
|
cs2nem : slbit; -- cs2: non-existent memory
|
cs2nem : slbit; -- cs2: non-existent memory
|
cs2pge : slbit; -- cs2: programming error
|
cs2pge : slbit; -- cs2: programming error
|
cs2mxf : slbit; -- cs2: missed transfer
|
cs2mxf : slbit; -- cs2: missed transfer
|
cs2pat : slbit; -- cs2: parity test
|
cs2pat : slbit; -- cs2: parity test
|
cs2bai : slbit; -- cs2: bus address inhibit
|
cs2bai : slbit; -- cs2: bus address inhibit
|
cs2unit2: slbit; -- cs2: unit lsb
|
cs2unit2: slbit; -- cs2: unit lsb
|
cs2unit : slv2; -- unit (ibus view)
|
cs2unit : slv2; -- unit (ibus view)
|
funit : slv2; -- unit (frozen on ext func go)
|
funit : slv2; -- unit (frozen on ext func go)
|
runit : slv2; -- unit (remote view)
|
runit : slv2; -- unit (remote view)
|
eunit : slv2; -- unit (effective)
|
eunit : slv2; -- unit (effective)
|
dsata : slv4; -- ds: attention
|
dsata : slv4; -- ds: attention
|
dserp : slv4; -- ds: error summary (or of er1+er2)
|
dserp : slv4; -- ds: error summary (or of er1+er2)
|
dspip : slv4; -- ds: positioning in progress
|
dspip : slv4; -- ds: positioning in progress
|
dsmol : slv4; -- ds: medium online (ATTACHED)
|
dsmol : slv4; -- ds: medium online (ATTACHED)
|
dswrl : slv4; -- ds: write locked
|
dswrl : slv4; -- ds: write locked
|
dslbt : slv4; -- ds: last block transfered
|
dslbt : slv4; -- ds: last block transfered
|
dsdpr : slv4; -- ds: drive present (ENABLED)
|
dsdpr : slv4; -- ds: drive present (ENABLED)
|
dsvv : slv4; -- ds: volume valid
|
dsvv : slv4; -- ds: volume valid
|
dsom : slv4; -- ds: offset mode
|
dsom : slv4; -- ds: offset mode
|
er1uns : slv4; -- er1: dive unsafe
|
er1uns : slv4; -- er1: dive unsafe
|
er1wle : slv4; -- er1: write lock error
|
er1wle : slv4; -- er1: write lock error
|
er1iae : slv4; -- er1: invalid address error
|
er1iae : slv4; -- er1: invalid address error
|
er1aoe : slv4; -- er1: address overflow error
|
er1aoe : slv4; -- er1: address overflow error
|
er1rmr : slv4; -- er1: register modificaton refused
|
er1rmr : slv4; -- er1: register modificaton refused
|
er1ilf : slv4; -- er1: illegal function
|
er1ilf : slv4; -- er1: illegal function
|
cs3wco : slbit; -- cs3: write check odd word
|
cs3wco : slbit; -- cs3: write check odd word
|
idlyval : slv8; -- int delay value
|
idlyval : slv8; -- int delay value
|
idlycnt : slv8; -- int delay counter
|
idlycnt : slv8; -- int delay counter
|
seekdone: slbit; -- cs3 rem: seek done
|
seekdone: slbit; -- cs3 rem: seek done
|
poredone: slbit; -- cs3 rem: port rel done
|
poredone: slbit; -- cs3 rem: port rel done
|
packdone: slbit; -- cs3 rem: pack ack done
|
packdone: slbit; -- cs3 rem: pack ack done
|
seardone: slbit; -- cs3 rem: search done
|
seardone: slbit; -- cs3 rem: search done
|
ned : slbit; -- current drive non-existent
|
ned : slbit; -- current drive non-existent
|
cerm : slbit; -- current eff. drive rm controller
|
cerm : slbit; -- current eff. drive rm controller
|
dtyp : slv6; -- current drive type (5:0)
|
dtyp : slv6; -- current drive type (5:0)
|
camax : slv10; -- current max cylinder address
|
camax : slv10; -- current max cylinder address
|
tamax : slv5; -- current max track address
|
tamax : slv5; -- current max track address
|
samax : slv6; -- current max sector address
|
samax : slv6; -- current max sector address
|
uscnt : slv7; -- usec counter
|
uscnt : slv7; -- usec counter
|
sc : slv6; -- current sector counter
|
sc : slv6; -- current sector counter
|
clrmode : slv2; -- clear: mode
|
clrmode : slv2; -- clear: mode
|
clrreg : slv3; -- clear: register counter
|
clrreg : slv3; -- clear: register counter
|
ireq : slbit; -- interrupt request flag
|
ireq : slbit; -- interrupt request flag
|
end record regs_type;
|
end record regs_type;
|
|
|
constant regs_init : regs_type := (
|
constant regs_init : regs_type := (
|
'0', -- ibsel
|
'0', -- ibsel
|
s_idle, -- state
|
s_idle, -- state
|
(others=>'0'), -- amap,
|
(others=>'0'), -- amap,
|
(others=>'0'), -- omux,
|
(others=>'0'), -- omux,
|
(others=>'0'), -- dinmsk,
|
(others=>'0'), -- dinmsk,
|
(others=>'0'), -- dtrm
|
(others=>'0'), -- dtrm
|
(others=>'0'), -- dte1
|
(others=>'0'), -- dte1
|
(others=>'0'), -- dte0
|
(others=>'0'), -- dte0
|
(others=>'0'), -- bae,
|
(others=>'0'), -- bae,
|
'0','0','1','0', -- cs1sc,cs1tre,cs1rdy,cs1ie
|
'0','0','1','0', -- cs1sc,cs1tre,cs1rdy,cs1ie
|
(others=>'0'), -- ffunc
|
(others=>'0'), -- ffunc
|
'0', -- fxfer
|
'0', -- fxfer
|
'0','0','0','0', -- cs2wce,cs2ned,cs2nem,cs2pge
|
'0','0','0','0', -- cs2wce,cs2ned,cs2nem,cs2pge
|
'0','0','0', -- cs2mxf,cs2pat,cs2bai
|
'0','0','0', -- cs2mxf,cs2pat,cs2bai
|
'0', -- cs2unit2
|
'0', -- cs2unit2
|
(others=>'0'), -- cs2unit
|
(others=>'0'), -- cs2unit
|
(others=>'0'), -- funit
|
(others=>'0'), -- funit
|
(others=>'0'), -- runit
|
(others=>'0'), -- runit
|
(others=>'0'), -- eunit
|
(others=>'0'), -- eunit
|
(others=>'0'), -- dsata
|
(others=>'0'), -- dsata
|
(others=>'0'), -- dserp
|
(others=>'0'), -- dserp
|
(others=>'0'), -- dspip
|
(others=>'0'), -- dspip
|
(others=>'0'), -- dsmol
|
(others=>'0'), -- dsmol
|
(others=>'0'), -- dswrl
|
(others=>'0'), -- dswrl
|
(others=>'0'), -- dslbt
|
(others=>'0'), -- dslbt
|
(others=>'0'), -- dsdpr
|
(others=>'0'), -- dsdpr
|
(others=>'0'), -- dsvv
|
(others=>'0'), -- dsvv
|
(others=>'0'), -- dsom
|
(others=>'0'), -- dsom
|
(others=>'0'), -- er1uns
|
(others=>'0'), -- er1uns
|
(others=>'0'), -- er1wle
|
(others=>'0'), -- er1wle
|
(others=>'0'), -- er1iae
|
(others=>'0'), -- er1iae
|
(others=>'0'), -- er1aoe
|
(others=>'0'), -- er1aoe
|
(others=>'0'), -- er1rmr
|
(others=>'0'), -- er1rmr
|
(others=>'0'), -- er1ilf
|
(others=>'0'), -- er1ilf
|
'0', -- cs3wco
|
'0', -- cs3wco
|
x"0a", -- idlyval (default delay=10)
|
x"0a", -- idlyval (default delay=10)
|
(others=>'0'), -- idlycnt
|
(others=>'0'), -- idlycnt
|
'0','0','0','0', -- seekdone,poredone,packdone,seardone
|
'0','0','0','0', -- seekdone,poredone,packdone,seardone
|
'0','0', -- ned,cerm
|
'0','0', -- ned,cerm
|
(others=>'0'), -- dtyp
|
(others=>'0'), -- dtyp
|
(others=>'0'), -- camax
|
(others=>'0'), -- camax
|
(others=>'0'), -- tamax
|
(others=>'0'), -- tamax
|
(others=>'0'), -- samax
|
(others=>'0'), -- samax
|
(others=>'0'), -- uscnt
|
(others=>'0'), -- uscnt
|
(others=>'0'), -- sc
|
(others=>'0'), -- sc
|
(others=>'0'), -- clrmode
|
(others=>'0'), -- clrmode
|
(others=>'0'), -- clrreg
|
(others=>'0'), -- clrreg
|
'0' -- ireq
|
'0' -- ireq
|
);
|
);
|
|
|
signal R_REGS : regs_type := regs_init;
|
signal R_REGS : regs_type := regs_init;
|
signal N_REGS : regs_type := regs_init;
|
signal N_REGS : regs_type := regs_init;
|
|
|
signal MEM_1_WE : slbit := '0';
|
signal MEM_1_WE : slbit := '0';
|
signal MEM_0_WE : slbit := '0';
|
signal MEM_0_WE : slbit := '0';
|
signal MEM_ADDR : slv5 := (others=>'0');
|
signal MEM_ADDR : slv5 := (others=>'0');
|
signal MEM_DIN : slv16 := (others=>'0');
|
signal MEM_DIN : slv16 := (others=>'0');
|
signal MEM_DOUT : slv16 := (others=>'0');
|
signal MEM_DOUT : slv16 := (others=>'0');
|
|
|
-- the following is unfortunately not accepted by xst:
|
-- the following is unfortunately not accepted by xst:
|
-- attribute fsm_encoding : string;
|
-- attribute fsm_encoding : string;
|
-- attribute fsm_encoding of R_REGS.state : signal is "one-hot";
|
-- attribute fsm_encoding of R_REGS.state : signal is "one-hot";
|
|
|
begin
|
begin
|
|
|
MEM_1 : ram_1swar_gen
|
MEM_1 : ram_1swar_gen
|
generic map (
|
generic map (
|
AWIDTH => 5,
|
AWIDTH => 5,
|
DWIDTH => 8)
|
DWIDTH => 8)
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
WE => MEM_1_WE,
|
WE => MEM_1_WE,
|
ADDR => MEM_ADDR,
|
ADDR => MEM_ADDR,
|
DI => MEM_DIN(ibf_byte1),
|
DI => MEM_DIN(ibf_byte1),
|
DO => MEM_DOUT(ibf_byte1));
|
DO => MEM_DOUT(ibf_byte1));
|
|
|
MEM_0 : ram_1swar_gen
|
MEM_0 : ram_1swar_gen
|
generic map (
|
generic map (
|
AWIDTH => 5,
|
AWIDTH => 5,
|
DWIDTH => 8)
|
DWIDTH => 8)
|
port map (
|
port map (
|
CLK => CLK,
|
CLK => CLK,
|
WE => MEM_0_WE,
|
WE => MEM_0_WE,
|
ADDR => MEM_ADDR,
|
ADDR => MEM_ADDR,
|
DI => MEM_DIN(ibf_byte0),
|
DI => MEM_DIN(ibf_byte0),
|
DO => MEM_DOUT(ibf_byte0));
|
DO => MEM_DOUT(ibf_byte0));
|
|
|
proc_regs: process (CLK)
|
proc_regs: process (CLK)
|
begin
|
begin
|
-- BRESET handled in main fsm, not here !!
|
-- BRESET handled in main fsm, not here !!
|
if rising_edge(CLK) then
|
if rising_edge(CLK) then
|
R_REGS <= N_REGS;
|
R_REGS <= N_REGS;
|
end if;
|
end if;
|
end process proc_regs;
|
end process proc_regs;
|
|
|
proc_next : process (R_REGS, CE_USEC, BRESET, ITIMER, IB_MREQ, MEM_DOUT,
|
proc_next : process (R_REGS, CE_USEC, BRESET, ITIMER, IB_MREQ, MEM_DOUT,
|
EI_ACK)
|
EI_ACK)
|
variable r : regs_type := regs_init;
|
variable r : regs_type := regs_init;
|
variable n : regs_type := regs_init;
|
variable n : regs_type := regs_init;
|
variable ibhold : slbit := '0';
|
variable ibhold : slbit := '0';
|
variable idout : slv16 := (others=>'0');
|
variable idout : slv16 := (others=>'0');
|
variable ibrem : slbit := '0';
|
variable ibrem : slbit := '0';
|
variable ibreq : slbit := '0';
|
variable ibreq : slbit := '0';
|
variable ibrd : slbit := '0';
|
variable ibrd : slbit := '0';
|
variable ibw0 : slbit := '0';
|
variable ibw0 : slbit := '0';
|
variable ibw1 : slbit := '0';
|
variable ibw1 : slbit := '0';
|
variable ibwrem : slbit := '0';
|
variable ibwrem : slbit := '0';
|
variable ilam : slbit := '0';
|
variable ilam : slbit := '0';
|
variable iei_req : slbit := '0';
|
variable iei_req : slbit := '0';
|
|
|
variable imem_we0 : slbit := '0';
|
variable imem_we0 : slbit := '0';
|
variable imem_we1 : slbit := '0';
|
variable imem_we1 : slbit := '0';
|
variable imem_addr : slv5 := (others=>'0');
|
variable imem_addr : slv5 := (others=>'0');
|
variable imem_din : slv16 := (others=>'0');
|
variable imem_din : slv16 := (others=>'0');
|
|
|
variable ieunit : slv2 := (others=>'0');
|
variable ieunit : slv2 := (others=>'0');
|
|
|
variable iomux : slv4 := (others=>'0'); -- omux select
|
variable iomux : slv4 := (others=>'0'); -- omux select
|
variable iamap : slv5 := (others=>'0'); -- mem mapped address
|
variable iamap : slv5 := (others=>'0'); -- mem mapped address
|
variable imask : slv16 := (others=>'0'); -- implemented bits mask
|
variable imask : slv16 := (others=>'0'); -- implemented bits mask
|
variable imbreg : slbit := '0'; -- massbus register
|
variable imbreg : slbit := '0'; -- massbus register
|
variable inormr : slbit := '0'; -- inhibit rmr protect
|
variable inormr : slbit := '0'; -- inhibit rmr protect
|
|
|
variable idte : slv3 := (others=>'0'); -- encoded drive type
|
variable idte : slv3 := (others=>'0'); -- encoded drive type
|
variable idtyp : slv6 := (others=>'0'); -- drive type (5:0)
|
variable idtyp : slv6 := (others=>'0'); -- drive type (5:0)
|
variable icamax : slv10 := (others=>'0'); -- max cylinder address
|
variable icamax : slv10 := (others=>'0'); -- max cylinder address
|
variable itamax : slv5 := (others=>'0'); -- max track address
|
variable itamax : slv5 := (others=>'0'); -- max track address
|
variable isamax : slv6 := (others=>'0'); -- max sector address
|
variable isamax : slv6 := (others=>'0'); -- max sector address
|
|
|
variable ined : slbit := '0'; -- non-existent drive
|
variable ined : slbit := '0'; -- non-existent drive
|
variable icerm : slbit := '0'; -- effectiv drive is rm
|
variable icerm : slbit := '0'; -- effectiv drive is rm
|
|
|
variable iclrreg : slbit := '0'; -- clr enable
|
variable iclrreg : slbit := '0'; -- clr enable
|
|
|
variable iscinc : slbit := '0'; -- increment r.sc enable
|
variable iscinc : slbit := '0'; -- increment r.sc enable
|
|
|
begin
|
begin
|
|
|
r := R_REGS;
|
r := R_REGS;
|
n := R_REGS;
|
n := R_REGS;
|
|
|
ibhold := '0';
|
ibhold := '0';
|
idout := (others=>'0');
|
idout := (others=>'0');
|
ibrem := IB_MREQ.racc;
|
ibrem := IB_MREQ.racc;
|
ibreq := IB_MREQ.re or IB_MREQ.we;
|
ibreq := IB_MREQ.re or IB_MREQ.we;
|
ibrd := IB_MREQ.re;
|
ibrd := IB_MREQ.re;
|
ibw0 := IB_MREQ.we and IB_MREQ.be0;
|
ibw0 := IB_MREQ.we and IB_MREQ.be0;
|
ibw1 := IB_MREQ.we and IB_MREQ.be1;
|
ibw1 := IB_MREQ.we and IB_MREQ.be1;
|
ibwrem := IB_MREQ.we and ibrem;
|
ibwrem := IB_MREQ.we and ibrem;
|
ilam := '0';
|
ilam := '0';
|
iei_req := '0';
|
iei_req := '0';
|
|
|
imem_we0 := '0';
|
imem_we0 := '0';
|
imem_we1 := '0';
|
imem_we1 := '0';
|
imem_addr := r.amap; -- default address (from mapper)
|
imem_addr := r.amap; -- default address (from mapper)
|
imem_din := r.dinmsk; -- default input (from masker)
|
imem_din := r.dinmsk; -- default input (from masker)
|
|
|
ieunit := (others=>'0');
|
ieunit := (others=>'0');
|
|
|
iomux := (others=>'0');
|
iomux := (others=>'0');
|
iamap := (others=>'0');
|
iamap := (others=>'0');
|
imask := (others=>'1'); -- default: all bits ok
|
imask := (others=>'1'); -- default: all bits ok
|
imbreg := '0';
|
imbreg := '0';
|
inormr := '0';
|
inormr := '0';
|
|
|
idte := (others=>'0');
|
idte := (others=>'0');
|
idtyp := (others=>'0');
|
idtyp := (others=>'0');
|
icamax := (others=>'0');
|
icamax := (others=>'0');
|
itamax := (others=>'0');
|
itamax := (others=>'0');
|
isamax := (others=>'0');
|
isamax := (others=>'0');
|
|
|
ined := '0';
|
ined := '0';
|
icerm := '0';
|
icerm := '0';
|
|
|
iclrreg := '0';
|
iclrreg := '0';
|
|
|
iscinc := '0';
|
iscinc := '0';
|
|
|
-- ibus address decoder, accept only offsets 0 to ibaddr_cs3
|
-- ibus address decoder, accept only offsets 0 to ibaddr_cs3
|
n.ibsel := '0';
|
n.ibsel := '0';
|
if IB_MREQ.aval = '1' and
|
if IB_MREQ.aval = '1' and
|
IB_MREQ.addr(12 downto 6) = ibaddr_rhrp(12 downto 6) and
|
IB_MREQ.addr(12 downto 6) = ibaddr_rhrp(12 downto 6) and
|
unsigned(IB_MREQ.addr(5 downto 1)) <= unsigned(ibaddr_cs3) then
|
unsigned(IB_MREQ.addr(5 downto 1)) <= unsigned(ibaddr_cs3) then
|
n.ibsel := '1';
|
n.ibsel := '1';
|
end if;
|
end if;
|
|
|
-- internal state machine
|
-- internal state machine
|
case r.state is
|
case r.state is
|
when s_idle => -- idle: handle ibus -----------------
|
when s_idle => -- idle: handle ibus -----------------
|
|
|
if r.ibsel='1' then -- selected
|
if r.ibsel='1' then -- selected
|
|
|
-- determine effective unit number
|
-- determine effective unit number
|
if ibrem = '1' then
|
if ibrem = '1' then
|
ieunit := r.runit;
|
ieunit := r.runit;
|
else
|
else
|
ieunit := r.cs2unit;
|
ieunit := r.cs2unit;
|
end if;
|
end if;
|
n.eunit := ieunit;
|
n.eunit := ieunit;
|
|
|
-- determine drive properties (always via iunit) FIXME: correct ??
|
-- determine drive properties (always via iunit) FIXME: correct ??
|
idte(2) := r.dtrm(to_integer(unsigned(r.cs2unit)));
|
idte(2) := r.dtrm(to_integer(unsigned(r.cs2unit)));
|
idte(1) := r.dte1(to_integer(unsigned(r.cs2unit)));
|
idte(1) := r.dte1(to_integer(unsigned(r.cs2unit)));
|
idte(0) := r.dte0(to_integer(unsigned(r.cs2unit)));
|
idte(0) := r.dte0(to_integer(unsigned(r.cs2unit)));
|
case idte is
|
case idte is
|
when dte_rp04 => -- RP04
|
when dte_rp04 => -- RP04
|
idtyp := rp04_dtyp;
|
idtyp := rp04_dtyp;
|
icamax := rp04_camax;
|
icamax := rp04_camax;
|
itamax := rp04_tamax;
|
itamax := rp04_tamax;
|
isamax := rp04_samax;
|
isamax := rp04_samax;
|
when dte_rp06 => -- RP06
|
when dte_rp06 => -- RP06
|
idtyp := rp06_dtyp;
|
idtyp := rp06_dtyp;
|
icamax := rp06_camax;
|
icamax := rp06_camax;
|
itamax := rp06_tamax;
|
itamax := rp06_tamax;
|
isamax := rp06_samax;
|
isamax := rp06_samax;
|
when dte_rm03 => -- RM03
|
when dte_rm03 => -- RM03
|
idtyp := rm03_dtyp;
|
idtyp := rm03_dtyp;
|
icamax := rm03_camax;
|
icamax := rm03_camax;
|
itamax := rm03_tamax;
|
itamax := rm03_tamax;
|
isamax := rm03_samax;
|
isamax := rm03_samax;
|
when dte_rm80 => -- RM80
|
when dte_rm80 => -- RM80
|
idtyp := rm80_dtyp;
|
idtyp := rm80_dtyp;
|
icamax := rm80_camax;
|
icamax := rm80_camax;
|
itamax := rm80_tamax;
|
itamax := rm80_tamax;
|
isamax := rm80_samax;
|
isamax := rm80_samax;
|
when dte_rm05 => -- RM05
|
when dte_rm05 => -- RM05
|
idtyp := rm05_dtyp;
|
idtyp := rm05_dtyp;
|
icamax := rm05_camax;
|
icamax := rm05_camax;
|
itamax := rm05_tamax;
|
itamax := rm05_tamax;
|
isamax := rm05_samax;
|
isamax := rm05_samax;
|
when dte_rp07 => -- RP07
|
when dte_rp07 => -- RP07
|
idtyp := rp07_dtyp;
|
idtyp := rp07_dtyp;
|
icamax := rp07_camax;
|
icamax := rp07_camax;
|
itamax := rp07_tamax;
|
itamax := rp07_tamax;
|
isamax := rp07_samax;
|
isamax := rp07_samax;
|
when others =>
|
when others =>
|
idtyp := (others=>'0');
|
idtyp := (others=>'0');
|
icamax := (others=>'0');
|
icamax := (others=>'0');
|
itamax := (others=>'0');
|
itamax := (others=>'0');
|
isamax := (others=>'0');
|
isamax := (others=>'0');
|
end case; -- case idte
|
end case; -- case idte
|
n.dtyp := idtyp;
|
n.dtyp := idtyp;
|
n.camax := icamax;
|
n.camax := icamax;
|
n.tamax := itamax;
|
n.tamax := itamax;
|
n.samax := isamax;
|
n.samax := isamax;
|
|
|
-- consider drive non-existent if not 'DPR' or unit>=4 selected
|
-- consider drive non-existent if not 'DPR' or unit>=4 selected
|
if r.dsdpr(to_integer(unsigned(r.cs2unit))) = '0' or
|
if r.dsdpr(to_integer(unsigned(r.cs2unit))) = '0' or
|
r.cs2unit2 = '1' then
|
r.cs2unit2 = '1' then
|
ined := '1';
|
ined := '1';
|
end if;
|
end if;
|
n.ned := ined;
|
n.ned := ined;
|
|
|
icerm := r.dtrm(to_integer(unsigned(ieunit)));
|
icerm := r.dtrm(to_integer(unsigned(ieunit)));
|
n.cerm := icerm;
|
n.cerm := icerm;
|
|
|
-- setup mapper
|
-- setup mapper
|
case IB_MREQ.addr(5 downto 1) is
|
case IB_MREQ.addr(5 downto 1) is
|
|
|
when ibaddr_cs1 => -- RxCS1 control reg 1
|
when ibaddr_cs1 => -- RxCS1 control reg 1
|
-- cs1 not flagged mbreg !! ned handling done explicitely
|
-- cs1 not flagged mbreg !! ned handling done explicitely
|
iamap := ieunit & amapc_cs1;
|
iamap := ieunit & amapc_cs1;
|
iomux := omux_cs1;
|
iomux := omux_cs1;
|
|
|
when ibaddr_wc => -- RxWC word count
|
when ibaddr_wc => -- RxWC word count
|
iamap := amapr_wc & amapc_ext;
|
iamap := amapr_wc & amapc_ext;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
|
|
when ibaddr_ba => -- RxBA bus address
|
when ibaddr_ba => -- RxBA bus address
|
imask := "1111111111111110"; -- lsb ignored
|
imask := "1111111111111110"; -- lsb ignored
|
iamap := amapr_ba & amapc_ext;
|
iamap := amapr_ba & amapc_ext;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
|
|
when ibaddr_da => -- RxDA disk address
|
when ibaddr_da => -- RxDA disk address
|
imask := "0001111100111111"; -- 000t tttt 00ss ssss
|
imask := "0001111100111111"; -- 000t tttt 00ss ssss
|
iamap := ieunit & amapc_da;
|
iamap := ieunit & amapc_da;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
imbreg := '1'; -- mb 5
|
imbreg := '1'; -- mb 5
|
|
|
when ibaddr_cs2 => -- RxCS2 control reg 2
|
when ibaddr_cs2 => -- RxCS2 control reg 2
|
iomux := omux_cs2;
|
iomux := omux_cs2;
|
|
|
when ibaddr_ds => -- RxDS drive status
|
when ibaddr_ds => -- RxDS drive status
|
iomux := omux_ds;
|
iomux := omux_ds;
|
imbreg := '1'; -- mb 1
|
imbreg := '1'; -- mb 1
|
|
|
when ibaddr_er1 => -- RxER1 error status 1
|
when ibaddr_er1 => -- RxER1 error status 1
|
iomux := omux_er1;
|
iomux := omux_er1;
|
imbreg := '1'; -- mb 2
|
imbreg := '1'; -- mb 2
|
|
|
when ibaddr_as => -- RxAS attention summary
|
when ibaddr_as => -- RxAS attention summary
|
iomux := omux_as;
|
iomux := omux_as;
|
imbreg := '1'; -- mb 4
|
imbreg := '1'; -- mb 4
|
inormr := '1'; -- AS writes allowed when RDY=0
|
inormr := '1'; -- AS writes allowed when RDY=0
|
|
|
when ibaddr_la => -- RxLA look ahead
|
when ibaddr_la => -- RxLA look ahead
|
iomux := omux_la;
|
iomux := omux_la;
|
imbreg := '1'; -- mb 7
|
imbreg := '1'; -- mb 7
|
|
|
when ibaddr_db => -- RxDB data buffer
|
when ibaddr_db => -- RxDB data buffer
|
iamap := amapr_db & amapc_ext;
|
iamap := amapr_db & amapc_ext;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
|
|
when ibaddr_mr1 => -- RxMR1 maintenance reg 1
|
when ibaddr_mr1 => -- RxMR1 maintenance reg 1
|
iamap := ieunit & amapc_mr1;
|
iamap := ieunit & amapc_mr1;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
imbreg := '1'; -- mb 3
|
imbreg := '1'; -- mb 3
|
inormr := '1'; -- MR1 writes allowed when RDY=0
|
inormr := '1'; -- MR1 writes allowed when RDY=0
|
|
|
when ibaddr_dt => -- RxDT drive type
|
when ibaddr_dt => -- RxDT drive type
|
iomux := omux_dt;
|
iomux := omux_dt;
|
imbreg := '1'; -- mb 6
|
imbreg := '1'; -- mb 6
|
|
|
when ibaddr_sn => -- RxSN serial number
|
when ibaddr_sn => -- RxSN serial number
|
iomux := omux_sn;
|
iomux := omux_sn;
|
imbreg := '1'; -- mb 10
|
imbreg := '1'; -- mb 10
|
|
|
when ibaddr_of => -- RxOF offset reg
|
when ibaddr_of => -- RxOF offset reg
|
imask := "0001110011111111"; -- 000f eh00 d??? ????
|
imask := "0001110011111111"; -- 000f eh00 d??? ????
|
iamap := ieunit & amapc_of;
|
iamap := ieunit & amapc_of;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
imbreg := '1'; -- mb 11
|
imbreg := '1'; -- mb 11
|
|
|
when ibaddr_dc => -- RxDC desired cylinder
|
when ibaddr_dc => -- RxDC desired cylinder
|
imask := "0000001111111111"; -- 0000 00cc cccc cccc
|
imask := "0000001111111111"; -- 0000 00cc cccc cccc
|
iamap := ieunit & amapc_dc;
|
iamap := ieunit & amapc_dc;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
imbreg := '1'; -- mb 12
|
imbreg := '1'; -- mb 12
|
|
|
when ibaddr_m13 =>
|
when ibaddr_m13 =>
|
if icerm = '1' then
|
if icerm = '1' then
|
iamap := ieunit & amapc_hr; -- RMHR holding reg
|
iamap := ieunit & amapc_hr; -- RMHR holding reg
|
else
|
else
|
iamap := ieunit & amapc_dc; -- RPDC current cylinder
|
iamap := ieunit & amapc_dc; -- RPDC current cylinder
|
end if;
|
end if;
|
iomux := omux_mem;
|
iomux := omux_mem;
|
imbreg := '1'; -- mb 13
|
imbreg := '1'; -- mb 13
|
|
|
when ibaddr_m14 =>
|
when ibaddr_m14 =>
|
if icerm = '1' then
|
if icerm = '1' then
|
iamap := ieunit & amapc_mr2; -- RMMR2 maintenance reg 2
|
iamap := ieunit & amapc_mr2; -- RMMR2 maintenance reg 2
|
iomux := omux_mem;
|
iomux := omux_mem;
|
else
|
else
|
iomux := omux_zero; -- RPER2 error status 2
|
iomux := omux_zero; -- RPER2 error status 2
|
end if;
|
end if;
|
imbreg := '1'; -- mb 14
|
imbreg := '1'; -- mb 14
|
|
|
when ibaddr_m15 => -- RxER3 error status 3/2
|
when ibaddr_m15 => -- RxER3 error status 3/2
|
iomux := omux_zero;
|
iomux := omux_zero;
|
imbreg := '1'; -- mb 15
|
imbreg := '1'; -- mb 15
|
|
|
when ibaddr_ec1 => -- RxEC1 ecc status 1
|
when ibaddr_ec1 => -- RxEC1 ecc status 1
|
iomux := omux_zero;
|
iomux := omux_zero;
|
imbreg := '1'; -- mb 16
|
imbreg := '1'; -- mb 16
|
|
|
when ibaddr_ec2 => -- RxEC2 ecc status 2
|
when ibaddr_ec2 => -- RxEC2 ecc status 2
|
iomux := omux_zero;
|
iomux := omux_zero;
|
imbreg := '1'; -- mb 17
|
imbreg := '1'; -- mb 17
|
|
|
when ibaddr_bae => -- RxBAE bus addr extension
|
when ibaddr_bae => -- RxBAE bus addr extension
|
iomux := omux_bae;
|
iomux := omux_bae;
|
|
|
when ibaddr_cs3 => -- RxCS3 control reg 3
|
when ibaddr_cs3 => -- RxCS3 control reg 3
|
iomux := omux_cs3;
|
iomux := omux_cs3;
|
|
|
when others => null; -- doesn't happen, ibsel only for
|
when others => null; -- doesn't happen, ibsel only for
|
-- subrange up to cs3, and all
|
-- subrange up to cs3, and all
|
-- 22 regs are decoded above
|
-- 22 regs are decoded above
|
|
|
end case; -- case IB_MREQ.addr
|
end case; -- case IB_MREQ.addr
|
n.amap := iamap;
|
n.amap := iamap;
|
n.omux := iomux;
|
n.omux := iomux;
|
n.dinmsk := imask and IB_MREQ.din;
|
n.dinmsk := imask and IB_MREQ.din;
|
|
|
if IB_MREQ.we = '1' then -- write request
|
if IB_MREQ.we = '1' then -- write request
|
ibhold := '1'; -- assume follow-up state taken
|
ibhold := '1'; -- assume follow-up state taken
|
case IB_MREQ.addr(5 downto 1) is
|
case IB_MREQ.addr(5 downto 1) is
|
|
|
when ibaddr_cs1 => n.state := s_wcs1; -- RxCS1
|
when ibaddr_cs1 => n.state := s_wcs1; -- RxCS1
|
when ibaddr_wc => n.state := s_wmembe; -- RxWC
|
when ibaddr_wc => n.state := s_wmembe; -- RxWC
|
when ibaddr_ba => n.state := s_wmembe; -- RxBA
|
when ibaddr_ba => n.state := s_wmembe; -- RxBA
|
when ibaddr_da => n.state := s_wmem; -- RxDA
|
when ibaddr_da => n.state := s_wmem; -- RxDA
|
when ibaddr_cs2 => n.state := s_wcs2; -- RxCS2
|
when ibaddr_cs2 => n.state := s_wcs2; -- RxCS2
|
when ibaddr_ds => n.state := s_wds; -- RxDS (read-only)
|
when ibaddr_ds => n.state := s_wds; -- RxDS (read-only)
|
when ibaddr_er1 => n.state := s_wer1; -- RxER1 (read-only)
|
when ibaddr_er1 => n.state := s_wer1; -- RxER1 (read-only)
|
when ibaddr_as => n.state := s_was; -- RxAS
|
when ibaddr_as => n.state := s_was; -- RxAS
|
when ibaddr_la => n.state := s_whr; -- RxLA (read-only)
|
when ibaddr_la => n.state := s_whr; -- RxLA (read-only)
|
when ibaddr_db => n.state := s_wmembe; -- RxDB
|
when ibaddr_db => n.state := s_wmembe; -- RxDB
|
when ibaddr_mr1 => n.state := s_wmem; -- RxMR1
|
when ibaddr_mr1 => n.state := s_wmem; -- RxMR1
|
when ibaddr_dt => n.state := s_wdt; -- RxDT (read-only)
|
when ibaddr_dt => n.state := s_wdt; -- RxDT (read-only)
|
when ibaddr_sn => n.state := s_whr; -- RxSN (read-only)
|
when ibaddr_sn => n.state := s_whr; -- RxSN (read-only)
|
when ibaddr_of => n.state := s_wmem; -- RxOF
|
when ibaddr_of => n.state := s_wmem; -- RxOF
|
when ibaddr_dc => n.state := s_wmem; -- RxDC
|
when ibaddr_dc => n.state := s_wmem; -- RxDC
|
when ibaddr_m13 => n.state := s_whr; -- RPCC|RMHR (fits both)
|
when ibaddr_m13 => n.state := s_whr; -- RPCC|RMHR (fits both)
|
when ibaddr_m14 =>
|
when ibaddr_m14 =>
|
if icerm = '1' then
|
if icerm = '1' then
|
n.state := s_wmem; -- RMMR2
|
n.state := s_wmem; -- RMMR2
|
else
|
else
|
n.state := s_whr; -- RPER2
|
n.state := s_whr; -- RPER2
|
end if;
|
end if;
|
when ibaddr_m15 => n.state := s_whr; -- RPER3|RMER2 (fits both)
|
when ibaddr_m15 => n.state := s_whr; -- RPER3|RMER2 (fits both)
|
when ibaddr_ec1 => n.state := s_whr; -- RxEC1
|
when ibaddr_ec1 => n.state := s_whr; -- RxEC1
|
when ibaddr_ec2 => n.state := s_whr; -- RxEC2
|
when ibaddr_ec2 => n.state := s_whr; -- RxEC2
|
when ibaddr_bae => n.state := s_wbae; -- RxBAE
|
when ibaddr_bae => n.state := s_wbae; -- RxBAE
|
when ibaddr_cs3 => n.state := s_wcs3; -- RxCS3
|
when ibaddr_cs3 => n.state := s_wcs3; -- RxCS3
|
|
|
when others => null; -- doesn't happen, ibsel only for
|
when others => null; -- doesn't happen, ibsel only for
|
-- subrange up to cs3, and all
|
-- subrange up to cs3, and all
|
-- 22 regs are decoded above
|
-- 22 regs are decoded above
|
|
|
end case; -- case IB_MREQ.addr
|
end case; -- case IB_MREQ.addr
|
|
|
-- some general error catchers
|
-- some general error catchers
|
if ibrem = '0' and imbreg='1' then -- local massbus write
|
if ibrem = '0' and imbreg='1' then -- local massbus write
|
-- for cs1: imbreg=0 !!
|
-- for cs1: imbreg=0 !!
|
-- write to non-existent drives
|
-- write to non-existent drives
|
if ined = '1' then
|
if ined = '1' then
|
n.cs2ned := '1';
|
n.cs2ned := '1';
|
-- write to a busy unit, can be a search/seek or a transfer
|
-- write to a busy unit, can be a search/seek or a transfer
|
elsif inormr='0' and -- rmr protected reg
|
elsif inormr='0' and -- rmr protected reg
|
(r.dspip(to_integer(unsigned(r.cs2unit)))='1' or -- busy pip
|
(r.dspip(to_integer(unsigned(r.cs2unit)))='1' or -- busy pip
|
(r.cs1rdy='0' and (r.funit = r.cs2unit)) -- busy xfer
|
(r.cs1rdy='0' and (r.funit = r.cs2unit)) -- busy xfer
|
) then
|
) then
|
n.state := s_setrmr;
|
n.state := s_setrmr;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
elsif IB_MREQ.re = '1' then -- read request
|
elsif IB_MREQ.re = '1' then -- read request
|
if ibrem='0' and imbreg='1' and ined='1' then
|
if ibrem='0' and imbreg='1' and ined='1' then
|
n.cs2ned := '1'; -- signal error
|
n.cs2ned := '1'; -- signal error
|
else
|
else
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_read;
|
n.state := s_read;
|
end if;
|
end if;
|
|
|
end if; -- if IB_MREQ.we .. elsif IB_MREQ.re
|
end if; -- if IB_MREQ.we .. elsif IB_MREQ.re
|
|
|
-- BRESET and ITIMER can be handled in the 'else' because both can
|
-- BRESET and ITIMER can be handled in the 'else' because both can
|
-- never come during an ibus transaction. Done here to keep logic
|
-- never come during an ibus transaction. Done here to keep logic
|
-- path in the 'if' short.
|
-- path in the 'if' short.
|
else -- if r.ibsel='1'
|
else -- if r.ibsel='1'
|
if BRESET = '1' then
|
if BRESET = '1' then
|
n.eunit := "00";
|
n.eunit := "00";
|
n.clrmode := clrmode_breset;
|
n.clrmode := clrmode_breset;
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
end if;
|
end if;
|
|
|
if unsigned(r.idlycnt) = 0 then -- interrupt delay expired
|
if unsigned(r.idlycnt) = 0 then -- interrupt delay expired
|
n.dsata := r.dsata or r.dspip; -- convert pip's to ata's
|
n.dsata := r.dsata or r.dspip; -- convert pip's to ata's
|
n.dspip := (others=>'0'); -- and mark them done
|
n.dspip := (others=>'0'); -- and mark them done
|
else
|
else
|
if ITIMER = '1' then -- not expired and ITIMER
|
if ITIMER = '1' then -- not expired and ITIMER
|
n.idlycnt := slv(unsigned(r.idlycnt) - 1); -- count down
|
n.idlycnt := slv(unsigned(r.idlycnt) - 1); -- count down
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
end if; -- if r.ibsel='1'
|
end if; -- if r.ibsel='1'
|
|
|
-- s_idle goes up to here !!
|
-- s_idle goes up to here !!
|
|
|
when s_wcs1 => -- wcs1: write cs1 -------------------
|
when s_wcs1 => -- wcs1: write cs1 -------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
imem_addr := r.amap; -- use mapped address
|
imem_addr := r.amap; -- use mapped address
|
imem_din := r.dinmsk; -- use masked input
|
imem_din := r.dinmsk; -- use masked input
|
|
|
if ibrem = '0' then -- loc write access
|
if ibrem = '0' then -- loc write access
|
|
|
if IB_MREQ.be1 = '1' then
|
if IB_MREQ.be1 = '1' then
|
if IB_MREQ.din(cs1_ibf_tre) = '1' then -- TRE=1 -> clear errors
|
if IB_MREQ.din(cs1_ibf_tre) = '1' then -- TRE=1 -> clear errors
|
n.cs2wce := '0';
|
n.cs2wce := '0';
|
n.cs2ned := '0';
|
n.cs2ned := '0';
|
n.cs2nem := '0';
|
n.cs2nem := '0';
|
n.cs2pge := '0';
|
n.cs2pge := '0';
|
n.cs2mxf := '0';
|
n.cs2mxf := '0';
|
end if;
|
end if;
|
if r.cs1rdy = '1' then -- only if RDY
|
if r.cs1rdy = '1' then -- only if RDY
|
n.bae(1 downto 0) := IB_MREQ.din(cs1_ibf_bae); -- update bae
|
n.bae(1 downto 0) := IB_MREQ.din(cs1_ibf_bae); -- update bae
|
end if;
|
end if;
|
end if; -- IB_MREQ.be1 = '1'
|
end if; -- IB_MREQ.be1 = '1'
|
|
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
n.cs1ie := IB_MREQ.din(cs1_ibf_ie);
|
n.cs1ie := IB_MREQ.din(cs1_ibf_ie);
|
if IB_MREQ.din(cs1_ibf_ie) = '1' and -- if IE and RDY both 1
|
if IB_MREQ.din(cs1_ibf_ie) = '1' and -- if IE and RDY both 1
|
IB_MREQ.din(cs1_ibf_rdy) = '1'then
|
IB_MREQ.din(cs1_ibf_rdy) = '1'then
|
n.ireq := '1'; -- issue software interrupt
|
n.ireq := '1'; -- issue software interrupt
|
end if;
|
end if;
|
|
|
if r.ned = '0' and -- drive on
|
if r.ned = '0' and -- drive on
|
IB_MREQ.din(cs1_ibf_go) = '1' then -- GO bit set
|
IB_MREQ.din(cs1_ibf_go) = '1' then -- GO bit set
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_funcchk;
|
n.state := s_funcchk;
|
end if;
|
end if;
|
|
|
-- FIXME_code: that's likely not fully correct, cs1 func bits are
|
-- FIXME_code: that's likely not fully correct, cs1 func bits are
|
-- stored before all error checks are done...
|
-- stored before all error checks are done...
|
imem_we0 := IB_MREQ.be0; -- remember func field per unit
|
imem_we0 := IB_MREQ.be0; -- remember func field per unit
|
|
|
if r.ned = '1' then -- loc access and drive off
|
if r.ned = '1' then -- loc access and drive off
|
n.cs2ned := '1'; -- signal error
|
n.cs2ned := '1'; -- signal error
|
end if;
|
end if;
|
|
|
end if; -- IB_MREQ.be0 = '1'
|
end if; -- IB_MREQ.be0 = '1'
|
|
|
else -- rem write access. GO not checked
|
else -- rem write access. GO not checked
|
-- always treated as remote function
|
-- always treated as remote function
|
case IB_MREQ.din(cs1_ibf_func) is
|
case IB_MREQ.din(cs1_ibf_func) is
|
|
|
when rfunc_wunit => -- rfunc: wunit ---------------
|
when rfunc_wunit => -- rfunc: wunit ---------------
|
n.runit := IB_MREQ.din(cs1_ibf_runit);
|
n.runit := IB_MREQ.din(cs1_ibf_runit);
|
|
|
when rfunc_cunit => -- rfunc: cunit ---------------
|
when rfunc_cunit => -- rfunc: cunit ---------------
|
n.runit := r.funit; -- use unit from last ext func go
|
n.runit := r.funit; -- use unit from last ext func go
|
|
|
when rfunc_done => -- rfunc: done ----------------
|
when rfunc_done => -- rfunc: done ----------------
|
n.cs1rdy := '1';
|
n.cs1rdy := '1';
|
if IB_MREQ.din(cs1_ibf_rata) = '0' then
|
if IB_MREQ.din(cs1_ibf_rata) = '0' then
|
n.ireq := r.cs1ie; -- yes, ireq is set from ie !!
|
n.ireq := r.cs1ie; -- yes, ireq is set from ie !!
|
else
|
else
|
n.dsata(to_integer(unsigned(r.funit))) := '1';
|
n.dsata(to_integer(unsigned(r.funit))) := '1';
|
end if;
|
end if;
|
|
|
when rfunc_widly => -- rfunc: widly ---------------
|
when rfunc_widly => -- rfunc: widly ---------------
|
n.idlyval := IB_MREQ.din(cs1_ibf_ridly);
|
n.idlyval := IB_MREQ.din(cs1_ibf_ridly);
|
|
|
when others => null;
|
when others => null;
|
|
|
end case;
|
end case;
|
end if;
|
end if;
|
|
|
when s_wcs2 => -- wcs2: write cs2 -------------------
|
when s_wcs2 => -- wcs2: write cs2 -------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if ibrem = '1' then -- rem access
|
if ibrem = '1' then -- rem access
|
n.cs3wco := IB_MREQ.din(cs2_ibf_rwco); -- cs3.wco rem set via cs2 !!
|
n.cs3wco := IB_MREQ.din(cs2_ibf_rwco); -- cs3.wco rem set via cs2 !!
|
n.cs2wce := IB_MREQ.din(cs2_ibf_wce);
|
n.cs2wce := IB_MREQ.din(cs2_ibf_wce);
|
n.cs2nem := IB_MREQ.din(cs2_ibf_nem);
|
n.cs2nem := IB_MREQ.din(cs2_ibf_nem);
|
n.cs2mxf := IB_MREQ.din(cs2_ibf_mxf); -- FIXME: really used ???
|
n.cs2mxf := IB_MREQ.din(cs2_ibf_mxf); -- FIXME: really used ???
|
else
|
else
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
n.cs2pat := IB_MREQ.din(cs2_ibf_pat);
|
n.cs2pat := IB_MREQ.din(cs2_ibf_pat);
|
n.cs2bai := IB_MREQ.din(cs2_ibf_bai);
|
n.cs2bai := IB_MREQ.din(cs2_ibf_bai);
|
n.cs2unit2 := IB_MREQ.din(cs2_ibf_unit2);
|
n.cs2unit2 := IB_MREQ.din(cs2_ibf_unit2);
|
n.cs2unit := IB_MREQ.din(cs2_ibf_unit);
|
n.cs2unit := IB_MREQ.din(cs2_ibf_unit);
|
if IB_MREQ.din(cs2_ibf_clr) = '1' then
|
if IB_MREQ.din(cs2_ibf_clr) = '1' then
|
n.eunit := "00";
|
n.eunit := "00";
|
n.clrmode := clrmode_cs2clr;
|
n.clrmode := clrmode_cs2clr;
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when s_wcs3 => -- wcs3: write cs3 -------------------
|
when s_wcs3 => -- wcs3: write cs3 -------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
n.cs1ie := IB_MREQ.din(cs3_ibf_ie);
|
n.cs1ie := IB_MREQ.din(cs3_ibf_ie);
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when s_wer1 => -- wer1: write er1 (rem only) --------
|
when s_wer1 => -- wer1: write er1 (rem only) --------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if ibrem = '1' then -- rem access
|
if ibrem = '1' then -- rem access
|
if IB_MREQ.din(er1_ibf_uns) = '1' then
|
if IB_MREQ.din(er1_ibf_uns) = '1' then
|
n.er1uns(to_integer(unsigned(r.eunit))) := '1';
|
n.er1uns(to_integer(unsigned(r.eunit))) := '1';
|
end if;
|
end if;
|
if IB_MREQ.din(er1_ibf_wle) = '1' then
|
if IB_MREQ.din(er1_ibf_wle) = '1' then
|
n.er1wle(to_integer(unsigned(r.eunit))) := '1';
|
n.er1wle(to_integer(unsigned(r.eunit))) := '1';
|
end if;
|
end if;
|
if IB_MREQ.din(er1_ibf_iae) = '1' then
|
if IB_MREQ.din(er1_ibf_iae) = '1' then
|
n.er1iae(to_integer(unsigned(r.eunit))) := '1';
|
n.er1iae(to_integer(unsigned(r.eunit))) := '1';
|
end if;
|
end if;
|
if IB_MREQ.din(er1_ibf_aoe) = '1' then
|
if IB_MREQ.din(er1_ibf_aoe) = '1' then
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '1';
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '1';
|
end if;
|
end if;
|
if IB_MREQ.din(er1_ibf_ilf) = '1' then
|
if IB_MREQ.din(er1_ibf_ilf) = '1' then
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '1';
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '1';
|
end if;
|
end if;
|
else -- loc access
|
else -- loc access
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_whr;
|
n.state := s_whr;
|
end if;
|
end if;
|
|
|
when s_was => -- was: write as ---------------------
|
when s_was => -- was: write as ---------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
-- clear the attention bits marked as '1' in data word (loc and rem !!)
|
-- clear the attention bits marked as '1' in data word (loc and rem !!)
|
n.dsata := r.dsata and not IB_MREQ.din(r.dsata'range);
|
n.dsata := r.dsata and not IB_MREQ.din(r.dsata'range);
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_whr;
|
n.state := s_whr;
|
end if;
|
end if;
|
|
|
when s_wdt => -- wdt: write dt ---------------------
|
when s_wdt => -- wdt: write dt ---------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if ibrem = '1' then -- rem access
|
if ibrem = '1' then -- rem access
|
n.dtrm(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_rm);
|
n.dtrm(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_rm);
|
n.dte1(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e1);
|
n.dte1(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e1);
|
n.dte0(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e0);
|
n.dte0(to_integer(unsigned(r.runit))) := IB_MREQ.din(dt_ibf_e0);
|
n.state := s_idle;
|
n.state := s_idle;
|
else -- loc access
|
else -- loc access
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_whr;
|
n.state := s_whr;
|
end if;
|
end if;
|
|
|
when s_wds => -- wdt: write ds ---------------------
|
when s_wds => -- wdt: write ds ---------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if ibrem = '1' then -- rem access
|
if ibrem = '1' then -- rem access
|
n.dsmol(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_mol);
|
n.dsmol(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_mol);
|
n.dswrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_wrl);
|
n.dswrl(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_wrl);
|
n.dslbt(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_lbt);
|
n.dslbt(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_lbt);
|
n.dsdpr(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_dpr);
|
n.dsdpr(to_integer(unsigned(r.runit))) := IB_MREQ.din(ds_ibf_dpr);
|
if IB_MREQ.din(ds_ibf_ata) = '1' then -- set ata on demand
|
if IB_MREQ.din(ds_ibf_ata) = '1' then -- set ata on demand
|
n.dsata(to_integer(unsigned(r.runit))) := '1';
|
n.dsata(to_integer(unsigned(r.runit))) := '1';
|
end if;
|
end if;
|
if IB_MREQ.din(ds_ibf_vv) = '1' then -- clr vv on demand
|
if IB_MREQ.din(ds_ibf_vv) = '1' then -- clr vv on demand
|
n.dsvv(to_integer(unsigned(r.runit))) := '0';
|
n.dsvv(to_integer(unsigned(r.runit))) := '0';
|
end if;
|
end if;
|
if IB_MREQ.din(ds_ibf_erp) = '1' then -- clr er1 on demand
|
if IB_MREQ.din(ds_ibf_erp) = '1' then -- clr er1 on demand
|
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
|
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
|
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
|
end if;
|
end if;
|
n.state := s_idle;
|
n.state := s_idle;
|
else -- loc access
|
else -- loc access
|
ibhold := '1'; -- read-only reg, thus noop
|
ibhold := '1'; -- read-only reg, thus noop
|
n.state := s_whr;
|
n.state := s_whr;
|
end if;
|
end if;
|
|
|
when s_wbae => -- wbae: write bae -------------------
|
when s_wbae => -- wbae: write bae -------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if IB_MREQ.be0 = '1' then
|
if IB_MREQ.be0 = '1' then
|
n.bae := IB_MREQ.din(bae_ibf_bae);
|
n.bae := IB_MREQ.din(bae_ibf_bae);
|
end if;
|
end if;
|
|
|
when s_wmem => -- wmem: write mem (DA,MR1,OF,DC,MR2)-
|
when s_wmem => -- wmem: write mem (DA,MR1,OF,DC,MR2)-
|
-- this state only handles massbus registers
|
-- this state only handles massbus registers
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
imem_addr := r.amap; -- use mapped address
|
imem_addr := r.amap; -- use mapped address
|
imem_din := r.dinmsk; -- use masked input
|
imem_din := r.dinmsk; -- use masked input
|
|
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
imem_we0 := '1'; -- write memory
|
imem_we0 := '1'; -- write memory
|
imem_we1 := '1';
|
imem_we1 := '1';
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_whr;
|
n.state := s_whr;
|
else -- rem access
|
else -- rem access
|
imem_we0 := '1'; -- write memory
|
imem_we0 := '1'; -- write memory
|
imem_we1 := '1';
|
imem_we1 := '1';
|
end if;
|
end if;
|
|
|
when s_wmembe => -- wmem: write mem with be (WC,BA,DB)-
|
when s_wmembe => -- wmem: write mem with be (WC,BA,DB)-
|
-- this state only handles controller registers --> no ned checking
|
-- this state only handles controller registers --> no ned checking
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
imem_we0 := IB_MREQ.be0;
|
imem_we0 := IB_MREQ.be0;
|
imem_we1 := IB_MREQ.be1;
|
imem_we1 := IB_MREQ.be1;
|
imem_addr := r.amap;
|
imem_addr := r.amap;
|
imem_din := r.dinmsk;
|
imem_din := r.dinmsk;
|
|
|
when s_whr => -- whr: write hr ---------------------
|
when s_whr => -- whr: write hr ---------------------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
imem_addr := r.cs2unit & amapc_hr; -- mem address of holding reg
|
imem_addr := r.cs2unit & amapc_hr; -- mem address of holding reg
|
imem_din := not IB_MREQ.din;
|
imem_din := not IB_MREQ.din;
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
imem_we0 := '1'; -- keep state
|
imem_we0 := '1'; -- keep state
|
imem_we1 := '1';
|
imem_we1 := '1';
|
end if;
|
end if;
|
|
|
when s_funcchk => -- funcchk: check function go --------
|
when s_funcchk => -- funcchk: check function go --------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
if r.cs1rdy = '0' and
|
if r.cs1rdy = '0' and
|
unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_xfer) then
|
unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_xfer) then
|
n.cs2pge := '1'; -- issue program error
|
n.cs2pge := '1'; -- issue program error
|
elsif IB_MREQ.din(cs1_ibf_func) = func_dclr then
|
elsif IB_MREQ.din(cs1_ibf_func) = func_dclr then
|
n.eunit := r.cs2unit; -- for follow-up states
|
n.eunit := r.cs2unit; -- for follow-up states
|
n.clrmode := clrmode_fdclr;
|
n.clrmode := clrmode_fdclr;
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
elsif r.dserp(to_integer(unsigned(r.cs2unit))) = '1' then
|
elsif r.dserp(to_integer(unsigned(r.cs2unit))) = '1' then
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
else
|
else
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_funcgo;
|
n.state := s_funcgo;
|
end if;
|
end if;
|
|
|
when s_funcgo => -- funcgo: handle function go --------
|
when s_funcgo => -- funcgo: handle function go --------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '0';
|
|
|
case IB_MREQ.din(cs1_ibf_func) is
|
case IB_MREQ.din(cs1_ibf_func) is
|
when func_noop => -- func: noop --------------
|
when func_noop => -- func: noop --------------
|
null; -- nothing done...
|
null; -- nothing done...
|
|
|
when func_pore => -- func: port release-------
|
when func_pore => -- func: port release-------
|
n.poredone := '1'; -- take note in done flag
|
n.poredone := '1'; -- take note in done flag
|
|
|
when func_unl => -- func: unload ------------
|
when func_unl => -- func: unload ------------
|
-- only for RP, simply clears MOL
|
-- only for RP, simply clears MOL
|
if r.dtrm(to_integer(unsigned(r.cs2unit))) = '0' then
|
if r.dtrm(to_integer(unsigned(r.cs2unit))) = '0' then
|
n.dsmol(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsmol(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dswrl(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dswrl(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
|
else
|
else
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
end if;
|
end if;
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
|
|
-- when func_dclr => now handled in funcchk !!
|
-- when func_dclr => now handled in funcchk !!
|
|
|
when func_offs | -- func: offset ------------
|
when func_offs | -- func: offset ------------
|
func_retc => -- func: return to center --
|
func_retc => -- func: return to center --
|
|
|
-- currently always immediate completion, so ata set here
|
-- currently always immediate completion, so ata set here
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
|
|
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
|
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
|
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
|
else
|
else
|
if IB_MREQ.din(cs1_ibf_func) = func_offs then
|
if IB_MREQ.din(cs1_ibf_func) = func_offs then
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '1';
|
else
|
else
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
|
n.dsom(to_integer(unsigned(r.cs2unit))) := '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when func_pres => -- func: readin preset -----
|
when func_pres => -- func: readin preset -----
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
|
n.eunit := r.cs2unit; -- for follow-up states
|
n.eunit := r.cs2unit; -- for follow-up states
|
n.clrmode := clrmode_fpres;
|
n.clrmode := clrmode_fpres;
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
n.state := s_oot_clr0; -- OOT state, no hold!
|
|
|
when func_pack => -- func: pack acknowledge --
|
when func_pack => -- func: pack acknowledge --
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsvv(to_integer(unsigned(r.cs2unit))) := '1';
|
n.packdone := '1'; -- take note in done flag
|
n.packdone := '1'; -- take note in done flag
|
|
|
-- seek like and data transfer functions
|
-- seek like and data transfer functions
|
when func_seek | -- func: seek --------------
|
when func_seek | -- func: seek --------------
|
func_recal | -- func: recalibrate -------
|
func_recal | -- func: recalibrate -------
|
func_sear | -- func: search ------------
|
func_sear | -- func: search ------------
|
func_wcd | -- func: write check data --
|
func_wcd | -- func: write check data --
|
func_wchd | -- func: write check h&d ---
|
func_wchd | -- func: write check h&d ---
|
func_write | -- func: write ------------
|
func_write | -- func: write ------------
|
func_whd | -- func: write header&data -
|
func_whd | -- func: write header&data -
|
func_read | -- func: read --------------
|
func_read | -- func: read --------------
|
func_rhd => -- func: read header&data --
|
func_rhd => -- func: read header&data --
|
|
|
if IB_MREQ.din(cs1_ibf_func) = func_seek then
|
if IB_MREQ.din(cs1_ibf_func) = func_seek then
|
n.seekdone := '1'; -- take note in done flag
|
n.seekdone := '1'; -- take note in done flag
|
end if;
|
end if;
|
if IB_MREQ.din(cs1_ibf_func) = func_sear then
|
if IB_MREQ.din(cs1_ibf_func) = func_sear then
|
n.seardone := '1'; -- take note in done flag
|
n.seardone := '1'; -- take note in done flag
|
end if;
|
end if;
|
|
|
-- check for transfer functions
|
-- check for transfer functions
|
n.fxfer := '0';
|
n.fxfer := '0';
|
if unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_wcd) then
|
if unsigned(IB_MREQ.din(cs1_ibf_func)) >= unsigned(func_wcd) then
|
n.fxfer := '1';
|
n.fxfer := '1';
|
-- in case of write, check for write lock
|
-- in case of write, check for write lock
|
if IB_MREQ.din(cs1_ibf_func) = func_write or
|
if IB_MREQ.din(cs1_ibf_func) = func_write or
|
IB_MREQ.din(cs1_ibf_func) = func_whd then
|
IB_MREQ.din(cs1_ibf_func) = func_whd then
|
if r.dswrl(to_integer(unsigned(r.cs2unit))) = '1' then
|
if r.dswrl(to_integer(unsigned(r.cs2unit))) = '1' then
|
n.er1wle(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1wle(to_integer(unsigned(r.cs2unit))) := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
|
if r.dsmol(to_integer(unsigned(r.cs2unit))) = '0' then
|
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1uns(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
else
|
else
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_chkdc;
|
n.state := s_chkdc;
|
end if;
|
end if;
|
|
|
-- illegal function codes
|
-- illegal function codes
|
when others =>
|
when others =>
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1ilf(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1';
|
|
|
end case; -- IB_MREQ.din(cs1_ibf_func)
|
end case; -- IB_MREQ.din(cs1_ibf_func)
|
|
|
when s_chkdc => -- chkdc: handle dc check ------------
|
when s_chkdc => -- chkdc: handle dc check ------------
|
imem_addr := r.cs2unit & amapc_dc; -- mem address of dc reg
|
imem_addr := r.cs2unit & amapc_dc; -- mem address of dc reg
|
if unsigned(MEM_DOUT(dc_ibf_ca)) > unsigned(r.camax) then
|
if unsigned(MEM_DOUT(dc_ibf_ca)) > unsigned(r.camax) then
|
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
|
end if;
|
end if;
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_chkda;
|
n.state := s_chkda;
|
|
|
when s_chkda => -- chkda: handle da check ------------
|
when s_chkda => -- chkda: handle da check ------------
|
imem_addr := r.cs2unit & amapc_da; -- mem address of da reg
|
imem_addr := r.cs2unit & amapc_da; -- mem address of da reg
|
if unsigned(MEM_DOUT(da_ibf_sa)) > unsigned(r.samax) or
|
if unsigned(MEM_DOUT(da_ibf_sa)) > unsigned(r.samax) or
|
unsigned(MEM_DOUT(da_ibf_ta)) > unsigned(r.tamax) then
|
unsigned(MEM_DOUT(da_ibf_ta)) > unsigned(r.tamax) then
|
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1iae(to_integer(unsigned(r.cs2unit))) := '1';
|
end if;
|
end if;
|
ibhold := '1';
|
ibhold := '1';
|
n.state := s_chkdo;
|
n.state := s_chkdo;
|
|
|
when s_chkdo => -- chkdo: execute function -----------
|
when s_chkdo => -- chkdo: execute function -----------
|
if r.er1iae(to_integer(unsigned(r.cs2unit))) = '1' or
|
if r.er1iae(to_integer(unsigned(r.cs2unit))) = '1' or
|
r.er1wle(to_integer(unsigned(r.cs2unit))) = '1' then
|
r.er1wle(to_integer(unsigned(r.cs2unit))) = '1' then
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1'; -- ata and done
|
n.dsata(to_integer(unsigned(r.cs2unit))) := '1'; -- ata and done
|
else
|
else
|
if r.fxfer = '0' then -- must be seek like function
|
if r.fxfer = '0' then -- must be seek like function
|
n.dspip(to_integer(unsigned(r.cs2unit))) := '1'; -- pip
|
n.dspip(to_integer(unsigned(r.cs2unit))) := '1'; -- pip
|
n.idlycnt := r.idlyval; -- start delay
|
n.idlycnt := r.idlyval; -- start delay
|
else -- must be transfer function
|
else -- must be transfer function
|
n.ffunc := IB_MREQ.din(cs1_ibf_func); -- latch func
|
n.ffunc := IB_MREQ.din(cs1_ibf_func); -- latch func
|
n.funit := r.cs2unit; -- latch unit
|
n.funit := r.cs2unit; -- latch unit
|
n.cs1rdy := '0'; -- controller busy
|
n.cs1rdy := '0'; -- controller busy
|
n.cs2wce := '0'; -- clear errors
|
n.cs2wce := '0'; -- clear errors
|
n.cs2ned := '0';
|
n.cs2ned := '0';
|
n.cs2nem := '0';
|
n.cs2nem := '0';
|
n.cs2pge := '0';
|
n.cs2pge := '0';
|
n.cs2mxf := '0';
|
n.cs2mxf := '0';
|
ilam := '1'; -- issue lam
|
ilam := '1'; -- issue lam
|
end if;
|
end if;
|
end if;
|
end if;
|
n.state := s_idle;
|
n.state := s_idle;
|
|
|
when s_read => -- read: all register reads ----------
|
when s_read => -- read: all register reads ----------
|
n.state := s_idle; -- in general return to s_idle
|
n.state := s_idle; -- in general return to s_idle
|
imem_addr := r.amap;
|
imem_addr := r.amap;
|
|
|
case r.omux is
|
case r.omux is
|
|
|
when omux_cs1 => -- omux: cs1 reg ---------------
|
when omux_cs1 => -- omux: cs1 reg ---------------
|
idout(cs1_ibf_sc) := r.cs1sc;
|
idout(cs1_ibf_sc) := r.cs1sc;
|
idout(cs1_ibf_tre) := r.cs1tre;
|
idout(cs1_ibf_tre) := r.cs1tre;
|
idout(cs1_ibf_dva) := '1';
|
idout(cs1_ibf_dva) := '1';
|
idout(cs1_ibf_bae) := r.bae(1 downto 0);
|
idout(cs1_ibf_bae) := r.bae(1 downto 0);
|
idout(cs1_ibf_rdy) := r.cs1rdy;
|
idout(cs1_ibf_rdy) := r.cs1rdy;
|
idout(cs1_ibf_ie) := r.cs1ie;
|
idout(cs1_ibf_ie) := r.cs1ie;
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
idout(cs1_ibf_func) := MEM_DOUT(cs1_ibf_func); --func per unit
|
idout(cs1_ibf_func) := MEM_DOUT(cs1_ibf_func); --func per unit
|
if r.ned = '1' then -- drive off
|
if r.ned = '1' then -- drive off
|
n.cs2ned := '1'; -- signal error
|
n.cs2ned := '1'; -- signal error
|
end if;
|
end if;
|
else -- rem access
|
else -- rem access
|
idout(cs1_ibf_func) := r.ffunc;
|
idout(cs1_ibf_func) := r.ffunc;
|
end if;
|
end if;
|
|
|
when omux_cs2 => -- omux: cs2 reg ---------------
|
when omux_cs2 => -- omux: cs2 reg ---------------
|
idout(cs2_ibf_wce) := r.cs2wce;
|
idout(cs2_ibf_wce) := r.cs2wce;
|
idout(cs2_ibf_ned) := r.cs2ned;
|
idout(cs2_ibf_ned) := r.cs2ned;
|
idout(cs2_ibf_nem) := r.cs2nem;
|
idout(cs2_ibf_nem) := r.cs2nem;
|
idout(cs2_ibf_pge) := r.cs2pge;
|
idout(cs2_ibf_pge) := r.cs2pge;
|
idout(cs2_ibf_mxf) := r.cs2mxf;
|
idout(cs2_ibf_mxf) := r.cs2mxf;
|
idout(cs2_ibf_or) := '1';
|
idout(cs2_ibf_or) := '1';
|
idout(cs2_ibf_ir) := '1';
|
idout(cs2_ibf_ir) := '1';
|
idout(cs2_ibf_pat) := r.cs2pat;
|
idout(cs2_ibf_pat) := r.cs2pat;
|
idout(cs2_ibf_bai) := r.cs2bai;
|
idout(cs2_ibf_bai) := r.cs2bai;
|
idout(cs2_ibf_unit2) := r.cs2unit2;
|
idout(cs2_ibf_unit2) := r.cs2unit2;
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
idout(cs2_ibf_unit) := r.cs2unit;
|
idout(cs2_ibf_unit) := r.cs2unit;
|
else -- rem access
|
else -- rem access
|
idout(cs2_ibf_unit) := r.funit;
|
idout(cs2_ibf_unit) := r.funit;
|
end if;
|
end if;
|
|
|
when omux_ds => -- omux: ds reg ---------------
|
when omux_ds => -- omux: ds reg ---------------
|
idout(ds_ibf_ata) := r.dsata(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_ata) := r.dsata(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_erp) := r.dserp(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_erp) := r.dserp(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_pip) := r.dspip(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_pip) := r.dspip(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_mol) := r.dsmol(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_mol) := r.dsmol(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_wrl) := r.dswrl(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_wrl) := r.dswrl(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_lbt) := r.dslbt(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_lbt) := r.dslbt(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_dpr) := r.dsdpr(to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_dpr) := r.dsdpr(to_integer(unsigned(r.eunit)));
|
|
|
-- ds.dry is 0 if mol=0 or if transfer or seek is active on unit
|
-- ds.dry is 0 if mol=0 or if transfer or seek is active on unit
|
-- the logic below checks for the complement ...
|
-- the logic below checks for the complement ...
|
if r.dsmol(to_integer(unsigned(r.eunit))) = '1' then
|
if r.dsmol(to_integer(unsigned(r.eunit))) = '1' then
|
if (r.cs1rdy = '1' or r.funit /= r.eunit) and
|
if (r.cs1rdy = '1' or r.funit /= r.eunit) and
|
r.dspip(to_integer(unsigned(r.eunit))) = '0' then
|
r.dspip(to_integer(unsigned(r.eunit))) = '0' then
|
idout(ds_ibf_dry) := '1';
|
idout(ds_ibf_dry) := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
idout(ds_ibf_vv) := r.dsvv (to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_vv) := r.dsvv (to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_om) := r.dsom (to_integer(unsigned(r.eunit)));
|
idout(ds_ibf_om) := r.dsom (to_integer(unsigned(r.eunit)));
|
|
|
when omux_er1 => -- omux: er1 reg ---------------
|
when omux_er1 => -- omux: er1 reg ---------------
|
idout(er1_ibf_uns) := r.er1uns(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_uns) := r.er1uns(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_wle) := r.er1wle(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_wle) := r.er1wle(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_iae) := r.er1iae(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_iae) := r.er1iae(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_aoe) := r.er1aoe(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_aoe) := r.er1aoe(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_rmr) := r.er1rmr(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_rmr) := r.er1rmr(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_ilf) := r.er1ilf(to_integer(unsigned(r.eunit)));
|
idout(er1_ibf_ilf) := r.er1ilf(to_integer(unsigned(r.eunit)));
|
|
|
when omux_as => -- omux: as reg ---------------
|
when omux_as => -- omux: as reg ---------------
|
idout(r.dsata'range) := r.dsata;
|
idout(r.dsata'range) := r.dsata;
|
|
|
when omux_la => -- omux: la reg ---------------
|
when omux_la => -- omux: la reg ---------------
|
idout(la_ibf_sc) := r.sc;
|
idout(la_ibf_sc) := r.sc;
|
|
|
when omux_dt => -- omux: dt reg ---------------
|
when omux_dt => -- omux: dt reg ---------------
|
if ibrem = '0' then -- loc access
|
if ibrem = '0' then -- loc access
|
idout(13) := '1'; -- set bit 020000 (movable head)
|
idout(13) := '1'; -- set bit 020000 (movable head)
|
idout(r.dtyp'range) := r.dtyp;
|
idout(r.dtyp'range) := r.dtyp;
|
else -- rem access (read back rem side)
|
else -- rem access (read back rem side)
|
idout(dt_ibf_rm) := r.dtrm(to_integer(unsigned(r.runit)));
|
idout(dt_ibf_rm) := r.dtrm(to_integer(unsigned(r.runit)));
|
idout(dt_ibf_e1) := r.dte1(to_integer(unsigned(r.runit)));
|
idout(dt_ibf_e1) := r.dte1(to_integer(unsigned(r.runit)));
|
idout(dt_ibf_e0) := r.dte0(to_integer(unsigned(r.runit)));
|
idout(dt_ibf_e0) := r.dte0(to_integer(unsigned(r.runit)));
|
end if;
|
end if;
|
|
|
when omux_sn => -- omux: sn reg ---------------
|
when omux_sn => -- omux: sn reg ---------------
|
-- the serial number is encoded as 4 digit BCD
|
-- the serial number is encoded as 4 digit BCD
|
-- digit 3: always 1
|
-- digit 3: always 1
|
-- digit 2: 1 if RM type; 0 if RP type
|
-- digit 2: 1 if RM type; 0 if RP type
|
-- digit 1: 0-3 based on encoded drive type
|
-- digit 1: 0-3 based on encoded drive type
|
-- digit 0: 0-3 taken as complement of unit
|
-- digit 0: 0-3 taken as complement of unit
|
-- Note: the 3lsb are the *complement* of the unit number because
|
-- Note: the 3lsb are the *complement* of the unit number because
|
-- 211bsd driver code contains a hack to detect SI and CDC
|
-- 211bsd driver code contains a hack to detect SI and CDC
|
-- drives. For those drives the drive type is encode in the
|
-- drives. For those drives the drive type is encode in the
|
-- sn register, and one convention is that the 3 lsb of sn
|
-- sn register, and one convention is that the 3 lsb of sn
|
-- equal the unit numnber. To prevent that the SI/CDC hacks
|
-- equal the unit numnber. To prevent that the SI/CDC hacks
|
-- are actived the 3lsb are set as complement of the unit !
|
-- are actived the 3lsb are set as complement of the unit !
|
idout(12) := '1';
|
idout(12) := '1';
|
idout(8) := r.dtrm(to_integer(unsigned(r.eunit)));
|
idout(8) := r.dtrm(to_integer(unsigned(r.eunit)));
|
idout(5) := r.dte1(to_integer(unsigned(r.eunit)));
|
idout(5) := r.dte1(to_integer(unsigned(r.eunit)));
|
idout(4) := r.dte0(to_integer(unsigned(r.eunit)));
|
idout(4) := r.dte0(to_integer(unsigned(r.eunit)));
|
idout(2) := '1';
|
idout(2) := '1';
|
idout(1) := not r.eunit(1);
|
idout(1) := not r.eunit(1);
|
idout(0) := not r.eunit(0);
|
idout(0) := not r.eunit(0);
|
|
|
when omux_bae => -- omux: bae reg ---------------
|
when omux_bae => -- omux: bae reg ---------------
|
idout(bae_ibf_bae) := r.bae;
|
idout(bae_ibf_bae) := r.bae;
|
|
|
when omux_cs3 => -- omux: cs3 reg ---------------
|
when omux_cs3 => -- omux: cs3 reg ---------------
|
idout(cs3_ibf_wco) := r.cs2wce and r.cs3wco;
|
idout(cs3_ibf_wco) := r.cs2wce and r.cs3wco;
|
idout(cs3_ibf_wce) := r.cs2wce and not r.cs3wco;
|
idout(cs3_ibf_wce) := r.cs2wce and not r.cs3wco;
|
idout(cs3_ibf_ie) := r.cs1ie;
|
idout(cs3_ibf_ie) := r.cs1ie;
|
if ibrem = '1' then -- rem access
|
if ibrem = '1' then -- rem access
|
idout(cs3_ibf_rseardone) := r.seardone;
|
idout(cs3_ibf_rseardone) := r.seardone;
|
idout(cs3_ibf_rpackdone) := r.packdone;
|
idout(cs3_ibf_rpackdone) := r.packdone;
|
idout(cs3_ibf_rporedone) := r.poredone;
|
idout(cs3_ibf_rporedone) := r.poredone;
|
idout(cs3_ibf_rseekdone) := r.seekdone;
|
idout(cs3_ibf_rseekdone) := r.seekdone;
|
if IB_MREQ.re = '1' then -- if read, do read & clear
|
if IB_MREQ.re = '1' then -- if read, do read & clear
|
n.seardone := '0';
|
n.seardone := '0';
|
n.packdone := '0';
|
n.packdone := '0';
|
n.poredone := '0';
|
n.poredone := '0';
|
n.seekdone := '0';
|
n.seekdone := '0';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
when omux_mem => -- omux: mem output ------------
|
when omux_mem => -- omux: mem output ------------
|
idout := MEM_DOUT;
|
idout := MEM_DOUT;
|
|
|
when omux_zero => -- omux: zero ------------------
|
when omux_zero => -- omux: zero ------------------
|
idout := (others=>'0');
|
idout := (others=>'0');
|
|
|
when others => null; -- nxr caught before in mapper !
|
when others => null; -- nxr caught before in mapper !
|
end case; -- case r.omux
|
end case; -- case r.omux
|
|
|
when s_setrmr => -- set rmr flag ----------------------
|
when s_setrmr => -- set rmr flag ----------------------
|
n.er1rmr(to_integer(unsigned(r.cs2unit))) := '1';
|
n.er1rmr(to_integer(unsigned(r.cs2unit))) := '1';
|
n.state := s_idle;
|
n.state := s_idle;
|
|
|
when s_oot_clr0 => -- OOT clr0: state 0 -----------------
|
when s_oot_clr0 => -- OOT clr0: state 0 -----------------
|
if r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr then
|
if r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr then
|
n.cs1rdy := '1'; -- clear cs1
|
n.cs1rdy := '1'; -- clear cs1
|
n.cs1ie := '0';
|
n.cs1ie := '0';
|
n.cs2wce := '0'; -- clear cs2
|
n.cs2wce := '0'; -- clear cs2
|
n.cs2ned := '0';
|
n.cs2ned := '0';
|
n.cs2nem := '0';
|
n.cs2nem := '0';
|
n.cs2pge := '0';
|
n.cs2pge := '0';
|
n.cs2mxf := '0';
|
n.cs2mxf := '0';
|
n.cs2pat := '0';
|
n.cs2pat := '0';
|
n.cs2bai := '0';
|
n.cs2bai := '0';
|
n.cs2unit2 := '0';
|
n.cs2unit2 := '0';
|
n.cs2unit := (others=>'0');
|
n.cs2unit := (others=>'0');
|
n.bae := (others=>'0'); -- clear bae
|
n.bae := (others=>'0'); -- clear bae
|
n.ireq := '0'; -- clear iff
|
n.ireq := '0'; -- clear iff
|
end if;
|
end if;
|
|
|
if r.clrmode=clrmode_breset or r.clrmode=clrmode_fdclr then
|
if r.clrmode=clrmode_breset or r.clrmode=clrmode_fdclr then
|
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
|
n.er1uns(to_integer(unsigned(r.eunit))) := '0'; -- clr all er1
|
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1wle(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1iae(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1aoe(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1rmr(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
|
n.er1ilf(to_integer(unsigned(r.eunit))) := '0'; -- "
|
end if;
|
end if;
|
|
|
n.cerm := r.dtrm(to_integer(unsigned(ieunit)));
|
n.cerm := r.dtrm(to_integer(unsigned(ieunit)));
|
|
|
n.clrreg := "000";
|
n.clrreg := "000";
|
ibhold := r.ibsel; -- delay pending request
|
ibhold := r.ibsel; -- delay pending request
|
n.state := s_oot_clr1;
|
n.state := s_oot_clr1;
|
|
|
when s_oot_clr1 => -- OOT clr1: state 1 ----------------
|
when s_oot_clr1 => -- OOT clr1: state 1 ----------------
|
imem_addr := r.eunit & r.clrreg;
|
imem_addr := r.eunit & r.clrreg;
|
imem_din := (others=>'0');
|
imem_din := (others=>'0');
|
|
|
iclrreg := '0';
|
iclrreg := '0';
|
case r.clrmode is
|
case r.clrmode is
|
|
|
when clrmode_breset => -- BRESET -------------------------
|
when clrmode_breset => -- BRESET -------------------------
|
iclrreg := '1'; -- simply clear all (cntl+drives)
|
iclrreg := '1'; -- simply clear all (cntl+drives)
|
|
|
when clrmode_cs2clr => -- CS2.CLR (controller clr) -------
|
when clrmode_cs2clr => -- CS2.CLR (controller clr) -------
|
case r.clrreg is
|
case r.clrreg is
|
when amapc_ext => iclrreg := '1';
|
when amapc_ext => iclrreg := '1';
|
when amapc_mr1 => iclrreg := r.cerm;
|
when amapc_mr1 => iclrreg := r.cerm;
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
|
|
when clrmode_fdclr => -- func=DCLR (drive clr) ----------
|
when clrmode_fdclr => -- func=DCLR (drive clr) ----------
|
case r.clrreg is
|
case r.clrreg is
|
when amapc_mr1 => iclrreg := r.cerm;
|
when amapc_mr1 => iclrreg := r.cerm;
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
|
|
when clrmode_fpres => -- func=PRESET --------------------
|
when clrmode_fpres => -- func=PRESET --------------------
|
case r.clrreg is
|
case r.clrreg is
|
when amapc_da => iclrreg := '1';
|
when amapc_da => iclrreg := '1';
|
when amapc_of => iclrreg := '1';
|
when amapc_of => iclrreg := '1';
|
when amapc_dc => iclrreg := '1';
|
when amapc_dc => iclrreg := '1';
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
|
|
when others => null;
|
when others => null;
|
end case;
|
end case;
|
if iclrreg = '1' then
|
if iclrreg = '1' then
|
imem_we0 := IB_MREQ.be0;
|
imem_we0 := IB_MREQ.be0;
|
imem_we1 := IB_MREQ.be1;
|
imem_we1 := IB_MREQ.be1;
|
end if;
|
end if;
|
n.clrreg := slv(unsigned(r.clrreg) + 1);
|
n.clrreg := slv(unsigned(r.clrreg) + 1);
|
|
|
ibhold := r.ibsel; -- delay pending request
|
ibhold := r.ibsel; -- delay pending request
|
if r.clrreg = "111" then -- if last register done
|
if r.clrreg = "111" then -- if last register done
|
n.state := s_oot_clr2; -- proceed with clr2
|
n.state := s_oot_clr2; -- proceed with clr2
|
end if;
|
end if;
|
|
|
when s_oot_clr2 => -- OOT clr2: state 2 ----------------
|
when s_oot_clr2 => -- OOT clr2: state 2 ----------------
|
n.eunit := slv(unsigned(r.eunit) + 1);
|
n.eunit := slv(unsigned(r.eunit) + 1);
|
|
|
ibhold := r.ibsel; -- delay pending request, so that
|
ibhold := r.ibsel; -- delay pending request, so that
|
-- s_idle can finally process it
|
-- s_idle can finally process it
|
if (r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr) and
|
if (r.clrmode=clrmode_breset or r.clrmode=clrmode_cs2clr) and
|
r.eunit /= "11" then
|
r.eunit /= "11" then
|
n.state := s_oot_clr0;
|
n.state := s_oot_clr0;
|
else
|
else
|
n.state := s_idle;
|
n.state := s_idle;
|
end if;
|
end if;
|
|
|
when others => null; -- <> ------------------------------
|
when others => null; -- <> ------------------------------
|
end case; -- case r.state
|
end case; -- case r.state
|
|
|
-- update cs1tre and cs1sc
|
-- update cs1tre and cs1sc
|
n.cs1tre := r.cs2wce or r.cs2ned or r.cs2nem or r.cs2pge or r.cs2mxf;
|
n.cs1tre := r.cs2wce or r.cs2ned or r.cs2nem or r.cs2pge or r.cs2mxf;
|
n.cs1sc := n.cs1tre or r.dsata(0) or r.dsata(1) or r.dsata(2) or r.dsata(3);
|
n.cs1sc := n.cs1tre or r.dsata(0) or r.dsata(1) or r.dsata(2) or r.dsata(3);
|
-- update dserp
|
-- update dserp
|
n.dserp := r.er1uns or -- or all er1
|
n.dserp := r.er1uns or -- or all er1
|
r.er1wle or -- "
|
r.er1wle or -- "
|
r.er1iae or -- "
|
r.er1iae or -- "
|
r.er1aoe or -- "
|
r.er1aoe or -- "
|
r.er1rmr or -- "
|
r.er1rmr or -- "
|
r.er1ilf; -- "
|
r.er1ilf; -- "
|
|
|
-- handle current sector counter (for RxLA emulation)
|
-- handle current sector counter (for RxLA emulation)
|
-- advance every 128 usec, so generate a pulse every 128 usec
|
-- advance every 128 usec, so generate a pulse every 128 usec
|
if CE_USEC = '1' then
|
if CE_USEC = '1' then
|
n.uscnt := slv(unsigned(r.uscnt) + 1);
|
n.uscnt := slv(unsigned(r.uscnt) + 1);
|
if unsigned(r.uscnt) = 0 then
|
if unsigned(r.uscnt) = 0 then
|
iscinc := '1';
|
iscinc := '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- if current sector larger or equal highest sector wrap to zero
|
-- if current sector larger or equal highest sector wrap to zero
|
-- note: iscinc is also '1' when unit changes, this ensures that
|
-- note: iscinc is also '1' when unit changes, this ensures that
|
-- the sector counter is always in range when read to ibus.
|
-- the sector counter is always in range when read to ibus.
|
if iscinc = '1' then
|
if iscinc = '1' then
|
if unsigned(r.sc) >= unsigned(r.samax) then
|
if unsigned(r.sc) >= unsigned(r.samax) then
|
n.sc := (others=>'0');
|
n.sc := (others=>'0');
|
else
|
else
|
n.sc := slv(unsigned(r.sc) + 1);
|
n.sc := slv(unsigned(r.sc) + 1);
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
-- the RH70 interrupt logic is very unusual
|
-- the RH70 interrupt logic is very unusual
|
-- 1. done interrupts (rdy 0->1) are edge sensitive (via r.ireq)
|
-- 1. done interrupts (rdy 0->1) are edge sensitive (via r.ireq)
|
-- 2. done interrupts are not canceled when IE is cleared
|
-- 2. done interrupts are not canceled when IE is cleared
|
-- 3. attention interrupts are level sensitive (via r.cs1sc)
|
-- 3. attention interrupts are level sensitive (via r.cs1sc)
|
-- 4. IE is disabled on interrupt acknowledge
|
-- 4. IE is disabled on interrupt acknowledge
|
|
|
iei_req := r.ireq or (r.cs1sc and r.cs1ie and r.cs1rdy);
|
iei_req := r.ireq or (r.cs1sc and r.cs1ie and r.cs1rdy);
|
|
|
if EI_ACK = '1' then -- interrupt executed
|
if EI_ACK = '1' then -- interrupt executed
|
n.ireq := '0'; -- cancel request
|
n.ireq := '0'; -- cancel request
|
n.cs1ie := '0'; -- disable interrupts
|
n.cs1ie := '0'; -- disable interrupts
|
end if;
|
end if;
|
|
|
N_REGS <= n;
|
N_REGS <= n;
|
|
|
MEM_0_WE <= imem_we0;
|
MEM_0_WE <= imem_we0;
|
MEM_1_WE <= imem_we1;
|
MEM_1_WE <= imem_we1;
|
MEM_ADDR <= imem_addr;
|
MEM_ADDR <= imem_addr;
|
MEM_DIN <= imem_din;
|
MEM_DIN <= imem_din;
|
|
|
IB_SRES.dout <= idout;
|
IB_SRES.dout <= idout;
|
IB_SRES.ack <= r.ibsel and ibreq;
|
IB_SRES.ack <= r.ibsel and ibreq;
|
IB_SRES.busy <= ibhold and ibreq;
|
IB_SRES.busy <= ibhold and ibreq;
|
|
|
RB_LAM <= ilam;
|
RB_LAM <= ilam;
|
EI_REQ <= iei_req;
|
EI_REQ <= iei_req;
|
|
|
end process proc_next;
|
end process proc_next;
|
|
|
|
|
end syn;
|
end syn;
|
|
|