Files
FireBee_SVN/vhdl/rtl/vhdl/WF5380/wf5380_control.vhd
2014-06-09 20:35:29 +00:00

614 lines
26 KiB
VHDL

----------------------------------------------------------------------
---- ----
---- WF5380 IP Core ----
---- ----
---- Description: ----
---- This model provides an asynchronous SCSI interface compa- ----
---- tible to the DP5380 from National Semiconductor and others. ----
---- ----
---- This file is the 5380's system controller. ----
---- ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright © 2009-2010 Wolfgang Foerster Inventronik GmbH. ----
---- All rights reserved. No portion of this sourcecode may be ----
---- reproduced or transmitted in any form by any means, whether ----
---- by electronic, mechanical, photocopying, recording or ----
---- otherwise, without my written permission. ----
---- ----
----------------------------------------------------------------------
--
-- Revision History
--
-- Revision 2K9A 2009/06/20 WF
-- Initial Release.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity WF5380_CONTROL is
port (
-- System controls:
CLK : in bit;
RESETn : in bit; -- System reset.
-- System controls:
BSY_INn : in bit; -- SCSI BSY_INn bit.
BSY_OUTn : out bit; -- SCSI BSY_INn bit.
DATA_EN : out bit; -- Enable the SCSI data lines.
SEL_INn : in bit; -- SCSI SEL_INn bit.
ARB_EN : in bit; -- Arbitration enable.
BSY_DISn : in bit; -- BSY monitoring enable.
RSTn : in bit; -- SCSI reset.
ARB : out bit; -- Arbitration flag.
AIP : out bit; -- Arbitration in progress flag.
LA : out bit; -- Lost arbitration flag.
ACK_INn : in bit;
ACK_OUTn : out bit;
REQ_INn : in bit;
REQ_OUTn : out bit;
DACKn : in bit; -- Data acknowledge.
READY : out bit;
DRQ : out bit; -- Data request.
TARG : in bit; -- Target mode indicator.
BLK : in bit; -- Block mode indicator.
PINT_EN : in bit; -- Parity interrupt enable.
SPER : in bit; -- Parity error.
SER_ID : in bit; -- SER matches ODR bits.
RPI : in bit; -- Reset interrupts.
DMA_EN : in bit; -- DMA mode enable.
SDS : in bit; -- Start DMA send, write only.
SDT : in bit; -- Start DMA target receive, write only.
SDI : in bit; -- Start DMA initiator receive, write only.
EOP_EN : in bit; -- EOP interrupt enable.
EOPn : in bit; -- End of process indicator.
PHSM : in bit; -- Phase match flag.
INT : out bit; -- Interrupt.
IDR_WR : out bit; -- Write input data register during DMA.
ODR_WR : out bit; -- Write output data register, during DMA.
CHK_PAR : out bit; -- Check Parity during DMA operation.
BSY_ERR : out bit; -- Busy monitoring error.
DMA_SND : out bit; -- Indicates direction of target DMA.
DMA_ACTIVE : out bit -- DMA is active.
);
end entity WF5380_CONTROL;
architecture BEHAVIOUR of WF5380_CONTROL is
type CTRL_STATES is (IDLE, WAIT_800ns, WAIT_2200ns, DMA_SEND, DMA_TARG_RCV, DMA_INIT_RCV);
type DMA_STATES is (IDLE, DMA_STEP_1, DMA_STEP_2, DMA_STEP_3, DMA_STEP_4);
signal CTRL_STATE : CTRL_STATES;
signal NEXT_CTRL_STATE : CTRL_STATES;
signal DMA_STATE : DMA_STATES;
signal NEXT_DMA_STATE : DMA_STATES;
signal BUS_FREE : bit;
signal DELAY_800ns : boolean;
signal DELAY_2200ns : boolean;
signal DMA_ACTIVE_I : bit;
signal EOP_In : bit;
begin
IN_BUFFER: process
-- This buffer shall prevent some signals against
-- setup hold effects and thus the state machine
-- against unpredictable behaviour.
begin
wait until CLK = '1' and CLK' event;
EOP_In <= EOPn;
end process IN_BUFFER;
STATE_REGISTERS: process(RESETn, CLK)
-- This is the controller's state machine register.
variable BSY_LOCK : boolean;
begin
if RESETn = '0' then
CTRL_STATE <= IDLE;
DMA_STATE <= IDLE;
elsif CLK = '1' and CLK' event then
if RSTn = '0' then -- SCSI reset.
CTRL_STATE <= IDLE;
DMA_STATE <= IDLE;
else
CTRL_STATE <= NEXT_CTRL_STATE;
DMA_STATE <= NEXT_DMA_STATE;
end if;
--
if DMA_EN = '0' then
DMA_STATE <= IDLE;
end if;
end if;
end process STATE_REGISTERS;
CTRL_DECODER: process(CTRL_STATE, ARB_EN, BUS_FREE, DELAY_800ns, SEL_INn, DMA_ACTIVE_I, SDS, SDT, SDI)
-- This is the controller's state machine decoder.
variable BSY_LOCK : boolean;
begin
-- Defaults.
DMA_SND <= '0';
--
case CTRL_STATE is
when IDLE =>
if ARB_EN = '1' and BUS_FREE = '1' then
NEXT_CTRL_STATE <= WAIT_800ns;
else
NEXT_CTRL_STATE <= IDLE;
end if;
when WAIT_800ns =>
if DELAY_800ns = true then
NEXT_CTRL_STATE <= WAIT_2200ns;
else
NEXT_CTRL_STATE <= WAIT_800ns;
end if;
when WAIT_2200ns =>
-- In this state the delay is provided by the
-- microprocessor and is at least 2.2us. The
-- delay is released by deasserting SELn.
if SEL_INn = '1' and SDS = '1' then
NEXT_CTRL_STATE <= DMA_SEND;
elsif SEL_INn = '1' and SDT = '1' then
NEXT_CTRL_STATE <= DMA_TARG_RCV;
elsif SEL_INn = '1' and SDI = '1' then
NEXT_CTRL_STATE <= DMA_INIT_RCV;
else
NEXT_CTRL_STATE <= WAIT_2200ns;
end if;
when DMA_SEND =>
if DMA_ACTIVE_I = '0' then
NEXT_CTRL_STATE <= IDLE;
else
NEXT_CTRL_STATE <= DMA_SEND;
end if;
--
DMA_SND <= '1';
when DMA_TARG_RCV =>
if DMA_ACTIVE_I = '0' then
NEXT_CTRL_STATE <= IDLE;
else
NEXT_CTRL_STATE <= DMA_TARG_RCV;
end if;
when DMA_INIT_RCV =>
if DMA_ACTIVE_I = '0' then
NEXT_CTRL_STATE <= IDLE;
else
NEXT_CTRL_STATE <= DMA_INIT_RCV;
end if;
end case;
end process CTRL_DECODER;
DMA_DECODER: process(CTRL_STATE, DMA_STATE, TARG, BLK, DACKn, REQ_INn, ACK_INn)
-- This is the DMA state machine decoder.
begin
-- Defaults:
IDR_WR <= '0';
ODR_WR <= '0';
CHK_PAR <= '0';
--
case DMA_STATE is
when IDLE =>
if CTRL_STATE = DMA_SEND then
NEXT_DMA_STATE <= DMA_STEP_1;
elsif CTRL_STATE = DMA_INIT_RCV then
NEXT_DMA_STATE <= DMA_STEP_1;
elsif CTRL_STATE = DMA_TARG_RCV then
NEXT_DMA_STATE <= DMA_STEP_1;
else
NEXT_DMA_STATE <= IDLE;
end if;
when DMA_STEP_1 =>
-- Initiator modes:
if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted.
ODR_WR <= '1';
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted.
ODR_WR <= '1';
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and REQ_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for REQn asserted.
IDR_WR <= '1';
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and REQ_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for REQn asserted.
IDR_WR <= '1';
-- Target modes:
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted.
ODR_WR <= '1';
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for DACKn asserted.
ODR_WR <= '1';
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and ACK_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for ACKn asserted.
IDR_WR <= '1';
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and ACK_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_2; -- Wait for ACKn asserted.
IDR_WR <= '1';
else
NEXT_DMA_STATE <= DMA_STEP_1;
end if;
when DMA_STEP_2 =>
-- Initiator modes:
if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted.
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted.
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and REQ_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for REQn deasserted.
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and REQ_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for REQn deasserted.
-- Target modes:
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted.
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for DACKn deasserted.
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and ACK_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for ACKn deasserted.
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and ACK_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_3; -- Wait for ACKn deasserted.
else
NEXT_DMA_STATE <= DMA_STEP_2;
end if;
when DMA_STEP_3 =>
-- Initiator modes:
if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and REQ_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait REQn asserted.
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and REQ_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait REQn asserted.
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted.
CHK_PAR <= '1';
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted.
CHK_PAR <= '1';
-- Target modes:
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and ACK_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait ACKn asserted.
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' and ACK_INn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait ACKn asserted.
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted.
CHK_PAR <= '1';
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and DACKn = '0' then
NEXT_DMA_STATE <= DMA_STEP_4; -- Wait DACKn asserted.
CHK_PAR <= '1';
else
NEXT_DMA_STATE <= DMA_STEP_3;
end if;
when DMA_STEP_4 =>
-- Initiator modes:
if CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' and REQ_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait REQn deasserted.
elsif CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and REQ_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait REQn deasserted.
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '0' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted.
elsif CTRL_STATE = DMA_INIT_RCV and BLK = '1' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted.
-- Target modes:
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' and ACK_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait ACKn deasserted.
elsif CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' and ACK_INn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait ACKn deasserted.
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '0' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted.
elsif CTRL_STATE = DMA_TARG_RCV and BLK = '1' and DACKn = '1' then
NEXT_DMA_STATE <= DMA_STEP_1; -- Wait DACKn deasserted.
else
NEXT_DMA_STATE <= DMA_STEP_4;
end if;
end case;
end process DMA_DECODER;
P_REQn: process(DMA_STATE, CTRL_STATE, TARG, BLK)
-- This logic controls the REQn output in target mode.
begin
if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '0' then
REQ_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then
REQ_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' then
REQ_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then
REQ_OUTn <= '0';
else
REQ_OUTn <= '1';
end if;
end process P_REQn;
P_ACKn: process(DMA_STATE, CTRL_STATE, TARG, BLK)
-- This logic controls the ACKn output in initiator mode.
begin
if DMA_STATE = DMA_STEP_2 and CTRL_STATE = DMA_INIT_RCV and BLK = '0' then
ACK_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_2 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then
ACK_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_4 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' then
ACK_OUTn <= '0';
elsif DMA_STATE = DMA_STEP_4 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' then
ACK_OUTn <= '0';
else
ACK_OUTn <= '1';
end if;
end process P_ACKn;
P_READY: process(DMA_STATE, CTRL_STATE, TARG, BLK)
-- This logic controls the READY output in initiator and target block mode.
begin
if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then
READY <= '1';
elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then
READY <= '1';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' then
READY <= '1';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then
READY <= '1';
else
READY <= '0';
end if;
end process P_READY;
P_DRQ: process(RESETn, CLK)
-- This flip flop controls the DRQ flag during all initiator and all target modes
-- for both block mode and non block mode operation.
variable LOCK : boolean;
begin
if RESETn = '0' then
DRQ <= '0';
LOCK := false;
elsif CLK = '1' and CLK' event then
-- Initiator modes:
if DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '0' then
DRQ <= '1';
elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_SEND and TARG = '0' and BLK = '1' and LOCK = false then
DRQ <= '1';
LOCK := true;
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '0' then
DRQ <= '1';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_INIT_RCV and BLK = '1' then
DRQ <= '1';
LOCK := true;
-- Target modes:
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '0' then
DRQ <= '1';
elsif DMA_STATE = DMA_STEP_3 and CTRL_STATE = DMA_SEND and TARG = '1' and BLK = '1' then
DRQ <= '1';
LOCK := true;
elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '0' then
DRQ <= '1';
elsif DMA_STATE = DMA_STEP_1 and CTRL_STATE = DMA_TARG_RCV and BLK = '1' then
DRQ <= '1';
LOCK := true;
elsif DACKn = '0' and LOCK = false then
DRQ <= '0';
elsif EOPn = '0' and DACKn = '0' then
DRQ <= '0';
LOCK := false;
end if;
end if;
end process P_DRQ;
P_BUSFREE: process(RESETn, CLK)
-- This is the logic for the bus free signal.
-- A bus free is valid if the BSY_INn signal is
-- at least 437.5ns inactive ans SEL_INn is inactive.
-- The delay are 7 clock cycles of 16MHz.
variable TMP : std_logic_vector(2 downto 0);
begin
if RESETn = '0' then
BUS_FREE <= '0';
TMP := "000";
elsif CLK = '1' and CLK' event then
if BSY_INn = '1' and TMP < x"111" then
TMP := TMP + '1';
elsif BSY_INn = '0' then
TMP := "000";
end if;
--
if RSTn = '0' then -- SCSI reset.
BUS_FREE <= '0';
elsif SEL_INn = '1' and TMP = "111" then
BUS_FREE <= '1';
else
BUS_FREE <= '0';
end if;
end if;
end process P_BUSFREE;
DELAY_800: process(RESETn, CLK)
-- This is the delay of 812.5ns.
-- It is derived from 13 16MHz clock cycles.
variable TMP : std_logic_vector(3 downto 0);
begin
if RESETn = '0' then
DELAY_800ns <= false;
TMP := x"0";
elsif CLK = '1' and CLK' event then
if CTRL_STATE /= WAIT_800ns then
TMP := x"0";
elsif TMP <= x"D" then
TMP := TMP + '1';
end if;
--
if TMP = x"D" then
DELAY_800ns <= true;
else
DELAY_800ns <= false;
end if;
end if;
end process DELAY_800;
P_ARB: process(RESETn, CLK)
-- This flip flop controls the ARB flag read back
-- by the microcontroller.
begin
if RESETn = '0' then
ARB <= '0';
elsif CLK = '1' and CLK' event then
if CTRL_STATE /= WAIT_800ns and NEXT_CTRL_STATE = WAIT_800ns then
ARB <= '1';
elsif ARB_EN = '0' then
ARB <= '0';
end if;
end if;
end process P_ARB;
P_AIP: process(RESETn, CLK)
-- This flip flop controls the AIP flag read back
-- by the microcontroller.
begin
if RESETn = '0' then
AIP <= '0';
elsif CLK = '1' and CLK' event then
if CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then
AIP <= '1';
elsif ARB_EN = '0' then
AIP <= '0';
end if;
end if;
end process P_AIP;
P_BSY: process
-- This flip flop controls the BSYn output
-- to the SCSI bus.
begin
wait until CLK = '1' and CLK' event;
if RESETn = '0' then
BSY_OUTn <= '1';
elsif CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then
BSY_OUTn <= '0';
elsif ARB_EN = '0' then
BSY_OUTn <= '1';
end if;
end process P_BSY;
P_DATA_EN: process(RESETn, CLK)
-- This flip flop controls the data enable
-- of the SCSI bus.
begin
if RESETn = '0' then
DATA_EN <= '0';
elsif CLK = '1' and CLK' event then
if CTRL_STATE = WAIT_800ns and NEXT_CTRL_STATE /= WAIT_800ns then
DATA_EN <= '1';
elsif ARB_EN = '0' then
DATA_EN <= '0';
end if;
end if;
end process P_DATA_EN;
P_LA: process(RESETn, CLK)
-- This flip flop controls the LA
-- (lost arbitration) flag.
begin
if RESETn = '0' then
LA <= '0';
elsif CLK = '1' and CLK' event then
if (CTRL_STATE = WAIT_800ns or CTRL_STATE = WAIT_2200ns) and SEL_INn = '0' then
LA <= '1';
elsif ARB_EN = '0' then
LA <= '0';
end if;
end if;
end process P_LA;
P_DMA_ACTIVE: process(RESETn, CLK, DMA_ACTIVE_I)
-- This is the Flip Flop indicating if there is DMA
-- operation.
begin
if RESETn = '0' then
DMA_ACTIVE_I <= '0';
elsif CLK = '1' and CLK' event then
if DMA_EN = '1' and SDS = '1' then
DMA_ACTIVE_I <= '1'; -- Start DMA send.
elsif DMA_EN = '1' and SDT = '1' then
DMA_ACTIVE_I <= '1'; -- Start DMA target receive.
elsif DMA_EN = '1' and SDI = '1' then
DMA_ACTIVE_I <= '1'; -- Start DMA initiator receive.
elsif DMA_EN = '0' then
DMA_ACTIVE_I <= '0'; -- Halt DMA via DMA flag in MR2.
elsif EOP_In = '0' then
DMA_ACTIVE_I <= '0'; -- Halt DMA via EOPn.
elsif PHSM = '0' then
DMA_ACTIVE_I <= '0'; -- Halt DMA via phase mismatch.
end if;
end if;
--
DMA_ACTIVE <= DMA_ACTIVE_I;
end process P_DMA_ACTIVE;
INTERRUPTS: process(RESETn, CLK)
-- This is the logic for all DP5380's interrupt sources.
-- A busy interrupt occurs if the BSY_INn signal is at
-- least 437.5ns inactive. The delay are 7 clock cycles
-- of 16MHz. This logic also provides the respective
-- error flags for the BSR.
variable TMP : std_logic_vector(2 downto 0);
begin
if RESETn = '0' then
INT <= '0';
BSY_ERR <= '0';
TMP := "000";
elsif CLK = '1' and CLK' event then
if SPER = '1' and PINT_EN = '1' then
INT <= '1'; -- Parity interrupt.
elsif RPI = '0' then -- Reset interrupts.
INT <= '0';
end if;
--
if EOP_In = '0' and CTRL_STATE = DMA_SEND then
BSY_ERR <= '1'; -- End of DMA error.
elsif EOP_In = '0' and CTRL_STATE = DMA_TARG_RCV then
BSY_ERR <= '1'; -- End of DMA error.
elsif EOP_In = '0' and CTRL_STATE = DMA_INIT_RCV then
BSY_ERR <= '1'; -- End of DMA error.
elsif DMA_EN = '0' then -- Reset error.
INT <= '0';
end if;
--
if EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_SEND then
INT <= '1'; -- End of DMA interrupt.
elsif EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_TARG_RCV then
INT <= '1'; -- End of DMA interrupt.
elsif EOP_EN = '1' and EOP_In = '0' and CTRL_STATE = DMA_INIT_RCV then
INT <= '1'; -- End of DMA interrupt.
elsif DMA_EN = '0' then -- Reset interrupt.
INT <= '0';
end if;
--
if PHSM = '0' then
INT <= '1'; -- Phase mismatch interrupt.
elsif DMA_EN = '0' then -- Reset interrupts.
INT <= '0';
end if;
--
if SEL_INn = '0' and BSY_INn = '1' and SER_ID = '1' then
INT <= '1'; -- (Re)Selection interrupt.
elsif RPI = '1' then -- Reset interrupts.
INT <= '0';
end if;
--
if BSY_INn = '1' and TMP < x"111" then
TMP := TMP + '1'; -- Bus settle delay.
elsif BSY_INn = '0' then
TMP := "000";
end if;
--
if BSY_DISn = '1' and BSY_INn = '1' and TMP = x"111" then
INT <= '1'; -- Busy monitoring interrupt.
BSY_ERR <= '1';
elsif RPI = '1' then -- Reset interrupts.
INT <= '0';
BSY_ERR <= '0';
end if;
--
end if;
end process INTERRUPTS;
end BEHAVIOUR;