This commit is contained in:
aschi54
2010-12-27 13:20:36 +00:00
commit 92c2ab95fc
427 changed files with 91737 additions and 0 deletions

View File

@@ -0,0 +1,631 @@
----------------------------------------------------------------------
---- ----
---- 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 (C) 2009 Wolfgang Foerster ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/lgpl.html ----
---- ----
----------------------------------------------------------------------
--
-- 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;

View File

@@ -0,0 +1,139 @@
----------------------------------------------------------------------
---- ----
---- 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 package file of the ip core. ----
---- ----
---- ----
---- ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2009 Wolfgang Foerster ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/lgpl.html ----
---- ----
----------------------------------------------------------------------
--
-- Revision History
--
-- Revision 2K9A 2009/06/20 WF
-- Initial Release.
library ieee;
use ieee.std_logic_1164.all;
package WF5380_PKG is
component WF5380_REGISTERS
port (
CLK : in bit;
RESETn : in bit;
ADR : in bit_vector(2 downto 0);
DATA_IN : in bit_vector(7 downto 0);
DATA_OUT : out bit_vector(7 downto 0);
DATA_EN : out bit;
CSn : in bit;
RDn : in bit;
WRn : in bit;
RSTn : in bit;
RST : out bit;
ARB_EN : out bit;
DMA_ACTIVE : in bit;
DMA_EN : out bit;
BSY_DISn : out bit;
EOP_EN : out bit;
PINT_EN : out bit;
SPER : out bit;
TARG : out bit;
BLK : out bit;
DMA_DIS : in bit;
IDR_WR : in bit;
ODR_WR : in bit;
CHK_PAR : in bit;
AIP : in bit;
ARB : in bit;
LA : in bit;
CSD : in bit_vector(7 downto 0);
CSB : in bit_vector(7 downto 0);
BSR : in bit_vector(7 downto 0);
ODR_OUT : out bit_vector(7 downto 0);
ICR_OUT : out bit_vector(7 downto 0);
TCR_OUT : out bit_vector(3 downto 0);
SER_OUT : out bit_vector(7 downto 0);
SDS : out bit;
SDT : out bit;
SDI : out bit;
RPI : out bit
);
end component;
component WF5380_CONTROL
port (
CLK : in bit;
RESETn : in bit;
BSY_INn : in bit;
BSY_OUTn : out bit;
DATA_EN : out bit;
SEL_INn : in bit;
ARB_EN : in bit;
BSY_DISn : in bit;
RSTn : in bit;
ARB : out bit;
AIP : out bit;
LA : out bit;
ACK_INn : in bit;
ACK_OUTn : out bit;
REQ_INn : in bit;
REQ_OUTn : out bit;
DACKn : in bit;
READY : out bit;
DRQ : out bit;
TARG : in bit;
BLK : in bit;
PINT_EN : in bit;
SPER : in bit;
SER_ID : in bit;
RPI : in bit;
DMA_EN : in bit;
SDS : in bit;
SDT : in bit;
SDI : in bit;
EOP_EN : in bit;
EOPn : in bit;
PHSM : in bit;
INT : out bit;
IDR_WR : out bit;
ODR_WR : out bit;
CHK_PAR : out bit;
BSY_ERR : out bit;
DMA_SND : out bit;
DMA_ACTIVE : out bit
);
end component;
end WF5380_PKG;

View File

@@ -0,0 +1,265 @@
----------------------------------------------------------------------
---- ----
---- 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 register model. ----
---- ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Register description (for more information see the DP5380 ----
---- data sheet: ----
---- ODR (address 0) Output data register, write only. ----
---- CSD (address 0) Current SCSI data, read only. ----
---- ICR (address 1) Initiator command register, read/write. ----
---- MR2 (address 2) Mode register 2, read/write. ----
---- TCR (address 3) Target command register, read/write. ----
---- SER (address 4) Select enable register, write only. ----
---- CSB (address 4) Current SCSI bus status, read only. ----
---- BSR (address 5) Start DMA send, write only. ----
---- SDS (address 5) Bus and status, read only. ----
---- SDT (address 6) Start DMA target receive, write only. ----
---- IDR (address 6) Input data register, read only. ----
---- SDI (address 7) Start DMA initiator recive, write only. ----
---- RPI (address 7) Reset parity / interrupts, read only. ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2009 Wolfgang Foerster ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/lgpl.html ----
---- ----
----------------------------------------------------------------------
--
-- 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_REGISTERS is
port (
-- System controls:
CLK : in bit;
RESETn : in bit; -- System reset.
-- Address and data:
ADR : in bit_vector(2 downto 0);
DATA_IN : in bit_vector(7 downto 0);
DATA_OUT : out bit_vector(7 downto 0);
DATA_EN : out bit;
-- Bus and DMA controls:
CSn : in bit;
RDn : in bit;
WRn : in bit;
-- Core controls:
RSTn : in bit; -- SCSI reset.
RST : out bit; -- Programmed SCSI reset.
ARB_EN : out bit; -- Arbitration enable.
DMA_ACTIVE : in bit; -- DMA is running.
DMA_EN : out bit; -- DMA mode enable.
BSY_DISn : out bit; -- BSY monitoring enable.
EOP_EN : out bit; -- EOP interrupt enable.
PINT_EN : out bit; -- Parity interrupt enable.
SPER : out bit; -- Parity error.
TARG : out bit; -- Target mode.
BLK : out bit; -- Block DMA mode.
DMA_DIS : in bit; -- Reset the DMA_EN by this signal.
IDR_WR : in bit; -- Write input data register during DMA.
ODR_WR : in bit; -- Write output data register, during DMA.
CHK_PAR : in bit; -- Check Parity during DMA operation.
AIP : in bit; -- Arbitration in progress.
ARB : in bit; -- Arbitration.
LA : in bit; -- Lost arbitration.
CSD : in bit_vector(7 downto 0); -- SCSI data.
CSB : in bit_vector(7 downto 0); -- Current SCSI bus status.
BSR : in bit_vector(7 downto 0); -- Bus and status.
ODR_OUT : out bit_vector(7 downto 0); -- This is the ODR register.
ICR_OUT : out bit_vector(7 downto 0); -- This is the ICR register.
TCR_OUT : out bit_vector(3 downto 0); -- This is the TCR register.
SER_OUT : out bit_vector(7 downto 0); -- This is the SER register.
SDS : out bit; -- Start DMA send, write only.
SDT : out bit; -- Start DMA target receive, write only.
SDI : out bit; -- Start DMA initiator receive, write only.
RPI : out bit
);
end entity WF5380_REGISTERS;
architecture BEHAVIOUR of WF5380_REGISTERS is
signal ICR : bit_vector(7 downto 0); -- Initiator command register, read/write.
signal IDR : bit_vector(7 downto 0); -- Input data register.
signal MR2 : bit_vector(7 downto 0); -- Mode register 2, read/write.
signal ODR : bit_vector(7 downto 0); -- Output data register, write only.
signal SER : bit_vector(7 downto 0); -- Select enable register, write only.
signal TCR : bit_vector(3 downto 0); -- Target command register, read/write.
begin
REGISTERS: process(RESETn, CLK)
-- This process reflects all registers in the 5380.
variable BSY_LOCK : boolean;
begin
if RESETn = '0' then
ODR <= (others => '0');
ICR <= (others => '0');
MR2 <= (others => '0');
TCR <= (others => '0');
SER <= (others => '0');
BSY_LOCK := false;
elsif CLK = '1' and CLK' event then
if RSTn = '0' then -- SCSI reset.
ODR <= (others => '0');
ICR(6 downto 0) <= (others => '0');
MR2(7) <= '0';
MR2(5 downto 0) <= (others => '0');
TCR <= (others => '0');
SER <= (others => '0');
BSY_LOCK := false;
elsif ADR = "000" and CSn = '0' and WRn = '0' then
ODR <= DATA_IN;
elsif ADR = "001" and CSn = '0' and WRn = '0' then
ICR <= DATA_IN;
elsif ADR = "010" and CSn = '0' and WRn = '0' then
MR2 <= DATA_IN;
elsif ADR = "011" and CSn = '0' and WRn = '0' then
TCR <= DATA_IN(3 downto 0);
elsif ADR = "100" and CSn = '0' and WRn = '0' then
SER <= DATA_IN;
end if;
--
if ODR_WR = '1' then
ODR <= DATA_IN;
end if;
--
-- This reset function is edge triggered on the 'Monitor Busy'
-- MR2(2).
if MR2(2) = '1' and BSY_LOCK = false then
ICR(5 downto 0) <= "000000";
BSY_LOCK := true;
elsif MR2(2) = '0' then
BSY_LOCK := false;
end if;
--
if DMA_DIS = '1' then
MR2(1) <= '0';
end if;
end if;
end process REGISTERS;
IDR_REGISTER: process(RESETn, CLK)
begin
if RESETn = '0' then
IDR <= x"00";
elsif CLK = '1' and CLK' event then
if RSTn = '0' or ICR(7) = '1' then
IDR <= x"00"; -- SCSI reset.
elsif IDR_WR = '1' then
IDR <= CSD;
end if;
end if;
end process IDR_REGISTER;
PARITY: process(RESETn, CLK)
-- This is the parity generating logic with it's related
-- error generation.
variable PAR_VAR : bit;
variable LOCK : boolean;
begin
if RESETn = '0' then
SPER <= '0';
LOCK := false;
elsif CLK = '1' and CLK' event then
-- Parity checked during 'Read from CSD'
-- (registered I/O and selection/reselection):
if ADR = "000" and CSn = '0' and RDn = '0' and LOCK = false then
for i in 1 to 7 loop
PAR_VAR := CSD(i) xor CSD(i-1);
end loop;
SPER <= not PAR_VAR;
LOCK := true;
end if;
--
-- Parity checking during DMA operation:
if DMA_ACTIVE = '1' and CHK_PAR = '1' then
for i in 1 to 7 loop
PAR_VAR := IDR(i) xor IDR(i-1);
end loop;
SPER <= not PAR_VAR;
LOCK := true;
end if;
--
-- Reset parity flag:
if MR2(5) <= '0' then -- MR2(5) = PCHK (disabled).
SPER <= '0';
elsif ADR = "111" and CSn = '0' and RDn = '0' then -- Reset parity/interrupts.
SPER <= '0';
LOCK := false;
end if;
end if;
end process PARITY;
DATA_EN <= '1' when ADR < "101" and CSn = '0' and WRn = '0' else '0';
SDS <= '1' when ADR = "101" and CSn = '0' and WRn = '0' else '0';
SDT <= '1' when ADR = "110" and CSn = '0' and WRn = '0' else '0';
SDI <= '1' when ADR = "111" and CSn = '0' and WRn = '0' else '0';
ICR_OUT <= ICR;
TCR_OUT <= TCR;
SER_OUT <= SER;
ODR_OUT <= ODR;
ARB_EN <= MR2(0);
DMA_EN <= MR2(1);
BSY_DISn <= MR2(2);
EOP_EN <= MR2(3);
PINT_EN <= MR2(4);
TARG <= MR2(6);
BLK <= MR2(7);
RST <= ICR(7);
-- Readback, unused bit positions are read back zero.
DATA_OUT <= CSD when ADR = "000" and CSn = '0' and RDn = '0' else -- Current SCSI data.
ICR(7) & AIP & LA & ICR(4 downto 0) when ADR = "001" and CSn = '0' and RDn = '0' else
MR2 when ADR = "010" and CSn = '0' and RDn = '0' else
x"0" & TCR when ADR = "011" and CSn = '0' and RDn = '0' else
CSB when ADR = "100" and CSn = '0' and RDn = '0' else -- Current SCSI bus status.
BSR when ADR = "101" and CSn = '0' and RDn = '0' else -- Bus and status.
IDR when ADR = "110" and CSn = '0' and RDn = '0' else x"00"; -- Input data register.
RPI <= '1' when ADR = "111" and CSn = '0' and RDn = '0' else '0'; -- Reset parity/interrupts.
end BEHAVIOUR;

View File

@@ -0,0 +1,300 @@
----------------------------------------------------------------------
---- ----
---- WF5380 IP Core ----
---- ----
---- Description: ----
---- This model provides an asynchronous SCSI interface compa- ----
---- tible to the DP5380 from National Semiconductor and others. ----
---- ----
---- Some remarks to the required input clock: ----
---- This core is provided for a 16MHz input clock. To use other ----
---- frequencies, it is necessary to modify the following proces- ----
---- ses in the control file section: ----
---- P_BUSFREE, DELAY_800, INTERRUPTS. ----
---- ----
---- This file is the top level file without tree state buses for ----
---- use in 'systems on chip' designs. ----
---- ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2009 Wolfgang Foerster ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/lgpl.html ----
---- ----
----------------------------------------------------------------------
--
-- Revision History
--
-- Revision 2K9A 2009/06/20 WF
-- Initial Release.
--
library work;
use work.wf5380_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity WF5380_TOP_SOC is
port (
-- System controls:
CLK : in bit; -- Use a 16MHz Clock.
RESETn : in bit;
-- Address and data:
ADR : in bit_vector(2 downto 0);
DATA_IN : in bit_vector(7 downto 0);
DATA_OUT : out bit_vector(7 downto 0);
DATA_EN : out bit;
-- Bus and DMA controls:
CSn : in bit;
RDn : in bit;
WRn : in bit;
EOPn : in bit;
DACKn : in bit;
DRQ : out bit;
INT : out bit;
READY : out bit;
-- SCSI bus:
DB_INn : in bit_vector(7 downto 0);
DB_OUTn : out bit_vector(7 downto 0);
DB_EN : out bit;
DBP_INn : in bit;
DBP_OUTn : out bit;
DBP_EN : out bit;
RST_INn : in bit;
RST_OUTn : out bit;
RST_EN : out bit;
BSY_INn : in bit;
BSY_OUTn : out bit;
BSY_EN : out bit;
SEL_INn : in bit;
SEL_OUTn : out bit;
SEL_EN : out bit;
ACK_INn : in bit;
ACK_OUTn : out bit;
ACK_EN : out bit;
ATN_INn : in bit;
ATN_OUTn : out bit;
ATN_EN : out bit;
REQ_INn : in bit;
REQ_OUTn : out bit;
REQ_EN : out bit;
IOn_IN : in bit;
IOn_OUT : out bit;
IO_EN : out bit;
CDn_IN : in bit;
CDn_OUT : out bit;
CD_EN : out bit;
MSG_INn : in bit;
MSG_OUTn : out bit;
MSG_EN : out bit
);
end entity WF5380_TOP_SOC;
architecture STRUCTURE of WF5380_TOP_SOC is
signal ACK_OUT_CTRLn : bit;
signal AIP : bit;
signal ARB : bit;
signal ARB_EN : bit;
signal BLK : bit;
signal BSR : bit_vector(7 downto 0);
signal BSY_DISn : bit;
signal BSY_ERR : bit;
signal BSY_OUT_CTRLn : bit;
signal CHK_PAR : bit;
signal CSD : bit_vector(7 downto 0);
signal CSB : bit_vector(7 downto 0);
signal DATA_EN_CTRL : bit;
signal DB_EN_I : bit;
signal DMA_ACTIVE : bit;
signal DMA_EN : bit;
signal DMA_DIS : bit;
signal DMA_SND : bit;
signal DRQ_I : bit;
signal EDMA : bit;
signal EOP_EN : bit;
signal ICR : bit_vector(7 downto 0);
signal IDR_WR : bit;
signal INT_I : bit;
signal LA : bit;
signal ODR : bit_vector(7 downto 0);
signal ODR_WR : bit;
signal PCHK : bit;
signal PHSM : bit;
signal PINT_EN : bit;
signal REQ_OUT_CTRLn : bit;
signal RPI : bit;
signal RST : bit;
signal SDI : bit;
signal SDS : bit;
signal SDT : bit;
signal SER : bit_vector(7 downto 0);
signal SER_ID : bit;
signal SPER : bit;
signal TARG : bit;
signal TCR : bit_vector(3 downto 0);
begin
EDMA <= '1' when EOPn = '0' and DACKn = '0' and RDn = '0' else
'1' when EOPn = '0' and DACKn = '0' and WRn = '0' else '0';
PHSM <= '1' when DMA_ACTIVE = '0' else -- Always true, if there is no DMA.
'1' when DMA_ACTIVE = '1' and REQ_INn = '0' and CDn_In = TCR(1) and IOn_IN = TCR(0) and MSG_INn = TCR(2) else '0'; -- Phasematch.
DMA_DIS <= '1' when DMA_ACTIVE = '1' and BSY_INn = '1' else '0';
SER_ID <= '1' when SER /= x"00" and SER = not CSD else '0';
DRQ <= DRQ_I;
INT <= INT_I;
-- Pay attention: the SCSI bus is driven with inverted signals.
ACK_OUTn <= ACK_OUT_CTRLn when DMA_ACTIVE = '1' else not ICR(4); -- Valid in initiator mode.
REQ_OUTn <= REQ_OUT_CTRLn when DMA_ACTIVE = '1' else not TCR(3); -- Valid in Target mode.
BSY_OUTn <= '0' when BSY_OUT_CTRLn = '0' and TARG = '0' else -- Valid in initiator mode.
'0' when ICR(3) = '1' else '1';
ATN_OUTn <= not ICR(1); -- Valid in initiator mode.
SEL_OUTn <= not ICR(2); -- Valid in initiator mode.
IOn_OUT <= not TCR(0); -- Valid in Target mode.
CDn_OUT <= not TCR(1); -- Valid in Target mode.
MSG_OUTn <= not TCR(2); -- Valid in Target mode.
RST_OUTn <= not RST;
DB_OUTn <= not ODR;
DBP_OUTn <= not SPER;
CSD <= not DB_INn;
CSB <= not RST_INn & not BSY_INn & not REQ_INn & not MSG_INn & not CDn_IN & not IOn_IN & not SEL_INn & not DBP_INn;
BSR <= EDMA & DRQ_I & SPER & INT_I & PHSM & BSY_ERR & not ATN_INn & not ACK_INn;
-- Hi impedance control:
ATN_EN <= '1' when TARG = '0' else '0'; -- Initiator mode.
SEL_EN <= '1' when TARG = '0' else '0'; -- Initiator mode.
BSY_EN <= '1' when TARG = '0' else '0'; -- Initiator mode.
ACK_EN <= '1' when TARG = '0' else '0'; -- Initiator mode.
IO_EN <= '1' when TARG = '1' else '0'; -- Target mode.
CD_EN <= '1' when TARG = '1' else '0'; -- Target mode.
MSG_EN <= '1' when TARG = '1' else '0'; -- Target mode.
REQ_EN <= '1' when TARG = '1' else '0'; -- Target mode.
RST_EN <= '1' when RST = '1' else '0'; -- Open drain control.
-- Data enables:
DB_EN_I <= '1' when DATA_EN_CTRL = '1' else -- During Arbitration.
'1' when ICR(0) = '1' and TARG = '1' and DMA_SND = '1' else -- Target 'Send' mode.
'1' when ICR(0) = '1' and TARG = '0' and IOn_IN = '0' and PHSM = '1' else
'1' when ICR(6) = '1' else '0'; -- Test mode enable.
DB_EN <= DB_EN_I;
DBP_EN <= DB_EN_I;
I_REGISTERS: WF5380_REGISTERS
port map(
CLK => CLK,
RESETn => RESETn,
ADR => ADR,
DATA_IN => DATA_IN,
DATA_OUT => DATA_OUT,
DATA_EN => DATA_EN,
CSn => CSn,
RDn => RDn,
WRn => WRn,
RSTn => RST_INn,
RST => RST,
ARB_EN => ARB_EN,
DMA_ACTIVE => DMA_ACTIVE,
DMA_EN => DMA_EN,
BSY_DISn => BSY_DISn,
EOP_EN => EOP_EN,
PINT_EN => PINT_EN,
SPER => SPER,
TARG => TARG,
BLK => BLK,
DMA_DIS => DMA_DIS,
IDR_WR => IDR_WR,
ODR_WR => ODR_WR,
CHK_PAR => CHK_PAR,
AIP => AIP,
ARB => ARB,
LA => LA,
CSD => CSD,
CSB => CSB,
BSR => BSR,
ODR_OUT => ODR,
ICR_OUT => ICR,
TCR_OUT => TCR,
SER_OUT => SER,
SDS => SDS,
SDT => SDT,
SDI => SDI,
RPI => RPI
);
I_CONTROL: WF5380_CONTROL
port map(
CLK => CLK,
RESETn => RESETn,
BSY_INn => BSY_INn,
BSY_OUTn => BSY_OUT_CTRLn,
DATA_EN => DATA_EN_CTRL,
SEL_INn => SEL_INn,
ARB_EN => ARB_EN,
BSY_DISn => BSY_DISn,
RSTn => RST_INn,
ARB => ARB,
AIP => AIP,
LA => LA,
ACK_INn => ACK_INn,
ACK_OUTn => ACK_OUT_CTRLn,
REQ_INn => REQ_INn,
REQ_OUTn => REQ_OUT_CTRLn,
DACKn => DACKn,
READY => READY,
DRQ => DRQ_I,
TARG => TARG,
BLK => BLK,
PINT_EN => PINT_EN,
SPER => SPER,
SER_ID => SER_ID,
RPI => RPI,
DMA_EN => DMA_EN,
SDS => SDS,
SDT => SDT,
SDI => SDI,
EOP_EN => EOP_EN,
EOPn => EOPn,
PHSM => PHSM,
INT => INT_I,
IDR_WR => IDR_WR,
ODR_WR => ODR_WR,
CHK_PAR => CHK_PAR,
BSY_ERR => BSY_ERR,
DMA_SND => DMA_SND,
DMA_ACTIVE => DMA_ACTIVE
);
end STRUCTURE;

View File

@@ -0,0 +1,275 @@
----------------------------------------------------------------------
---- ----
---- 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 top level file with tree state buses. ----
---- ----
---- ----
---- ----
---- ----
---- Author(s): ----
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2009 Wolfgang Foerster ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/lgpl.html ----
---- ----
----------------------------------------------------------------------
--
-- Revision History
--
-- Revision 2K9A 2009/06/20 WF
-- Initial Release.
--
library work;
use work.wf5380_pkg.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity WF5380_TOP is
port (
-- System controls:
CLK : in bit;
RESETn : in bit;
-- Address and data:
ADR : in std_logic_vector(2 downto 0);
DATA : inout std_logic_vector(7 downto 0);
-- Bus and DMA controls:
CSn : in bit;
RDn : in bit;
WRn : in bit;
EOPn : in bit;
DACKn : in bit;
DRQ : out bit;
INT : out bit;
READY : out bit;
-- SCSI bus:
DBn : inout std_logic_vector(7 downto 0);
DBPn : inout std_logic;
RSTn : inout std_logic;
BSYn : inout std_logic;
SELn : inout std_logic;
ACKn : inout std_logic;
ATNn : inout std_logic;
REQn : inout std_logic;
IOn : inout std_logic;
CDn : inout std_logic;
MSGn : inout std_logic
);
end entity WF5380_TOP;
architecture STRUCTURE of WF5380_TOP is
component WF5380_TOP_SOC
port (
-- System controls:
CLK : in bit;
RESETn : in bit;
ADR : in bit_vector(2 downto 0);
DATA_IN : in bit_vector(7 downto 0);
DATA_OUT : out bit_vector(7 downto 0);
DATA_EN : out bit;
CSn : in bit;
RDn : in bit;
WRn : in bit;
EOPn : in bit;
DACKn : in bit;
DRQ : out bit;
INT : out bit;
READY : out bit;
DB_INn : in bit_vector(7 downto 0);
DB_OUTn : out bit_vector(7 downto 0);
DB_EN : out bit;
DBP_INn : in bit;
DBP_OUTn : out bit;
DBP_EN : out bit;
RST_INn : in bit;
RST_OUTn : out bit;
RST_EN : out bit;
BSY_INn : in bit;
BSY_OUTn : out bit;
BSY_EN : out bit;
SEL_INn : in bit;
SEL_OUTn : out bit;
SEL_EN : out bit;
ACK_INn : in bit;
ACK_OUTn : out bit;
ACK_EN : out bit;
ATN_INn : in bit;
ATN_OUTn : out bit;
ATN_EN : out bit;
REQ_INn : in bit;
REQ_OUTn : out bit;
REQ_EN : out bit;
IOn_IN : in bit;
IOn_OUT : out bit;
IO_EN : out bit;
CDn_IN : in bit;
CDn_OUT : out bit;
CD_EN : out bit;
MSG_INn : in bit;
MSG_OUTn : out bit;
MSG_EN : out bit
);
end component;
--
signal ADR_IN : bit_vector(2 downto 0);
signal DATA_IN : bit_vector(7 downto 0);
signal DATA_OUT : bit_vector(7 downto 0);
signal DATA_EN : bit;
signal DB_INn : bit_vector(7 downto 0);
signal DB_OUTn : bit_vector(7 downto 0);
signal DB_EN : bit;
signal DBP_INn : bit;
signal DBP_OUTn : bit;
signal DBP_EN : bit;
signal RST_INn : bit;
signal RST_OUTn : bit;
signal RST_EN : bit;
signal BSY_INn : bit;
signal BSY_OUTn : bit;
signal BSY_EN : bit;
signal SEL_INn : bit;
signal SEL_OUTn : bit;
signal SEL_EN : bit;
signal ACK_INn : bit;
signal ACK_OUTn : bit;
signal ACK_EN : bit;
signal ATN_INn : bit;
signal ATN_OUTn : bit;
signal ATN_EN : bit;
signal REQ_INn : bit;
signal REQ_OUTn : bit;
signal REQ_EN : bit;
signal IOn_IN : bit;
signal IOn_OUT : bit;
signal IO_EN : bit;
signal CDn_IN : bit;
signal CDn_OUT : bit;
signal CD_EN : bit;
signal MSG_INn : bit;
signal MSG_OUTn : bit;
signal MSG_EN : bit;
begin
ADR_IN <= To_BitVector(ADR);
DATA_IN <= To_BitVector(DATA);
DATA <= To_StdLogicVector(DATA_OUT) when DATA_EN = '1' else (others => 'Z');
DB_INn <= To_BitVector(DBn);
DBn <= To_StdLogicVector(DB_OUTn) when DB_EN = '1' else (others => 'Z');
DBP_INn <= To_Bit(DBPn);
RST_INn <= To_Bit(RSTn);
BSY_INn <= To_Bit(BSYn);
SEL_INn <= To_Bit(SELn);
ACK_INn <= To_Bit(ACKn);
ATN_INn <= To_Bit(ATNn);
REQ_INn <= To_Bit(REQn);
IOn_IN <= To_Bit(IOn);
CDn_IN <= To_Bit(CDn);
MSG_INn <= To_Bit(MSGn);
DBPn <= '1' when DBP_OUTn = '1' and DBP_EN = '1' else
'0' when DBP_OUTn = '0' and DBP_EN = '1' else 'Z';
RSTn <= '1' when RST_OUTn = '1' and RST_EN = '1'else
'0' when RST_OUTn = '0' and RST_EN = '1' else 'Z';
BSYn <= '1' when BSY_OUTn = '1' and BSY_EN = '1' else
'0' when BSY_OUTn = '0' and BSY_EN = '1' else 'Z';
SELn <= '1' when SEL_OUTn = '1' and SEL_EN = '1' else
'0' when SEL_OUTn = '0' and SEL_EN = '1' else 'Z';
ACKn <= '1' when ACK_OUTn = '1' and ACK_EN = '1' else
'0' when ACK_OUTn = '0' and ACK_EN = '1' else 'Z';
ATNn <= '1' when ATN_OUTn = '1' and ATN_EN = '1' else
'0' when ATN_OUTn = '0' and ATN_EN = '1' else 'Z';
REQn <= '1' when REQ_OUTn = '1' and REQ_EN = '1' else
'0' when REQ_OUTn = '0' and REQ_EN = '1' else 'Z';
IOn <= '1' when IOn_OUT = '1' and IO_EN = '1' else
'0' when IOn_OUT = '0' and IO_EN = '1' else 'Z';
CDn <= '1' when CDn_OUT = '1' and CD_EN = '1' else
'0' when CDn_OUT = '0' and CD_EN = '1' else 'Z';
MSGn <= '1' when MSG_OUTn = '1' and MSG_EN = '1' else
'0' when MSG_OUTn = '0' and MSG_EN = '1' else 'Z';
I_5380: WF5380_TOP_SOC
port map(
CLK => CLK,
RESETn => RESETn,
ADR => ADR_IN,
DATA_IN => DATA_IN,
DATA_OUT => DATA_OUT,
DATA_EN => DATA_EN,
CSn => CSn,
RDn => RDn,
WRn => WRn,
EOPn => EOPn,
DACKn => DACKn,
DRQ => DRQ,
INT => INT,
READY => READY,
DB_INn => DB_INn,
DB_OUTn => DB_OUTn,
DB_EN => DB_EN,
DBP_INn => DBP_INn,
DBP_OUTn => DBP_OUTn,
DBP_EN => DBP_EN,
RST_INn => RST_INn,
RST_OUTn => RST_OUTn,
RST_EN => RST_EN,
BSY_INn => BSY_INn,
BSY_OUTn => BSY_OUTn,
BSY_EN => BSY_EN,
SEL_INn => SEL_INn,
SEL_OUTn => SEL_OUTn,
SEL_EN => SEL_EN,
ACK_INn => ACK_INn,
ACK_OUTn => ACK_OUTn,
ACK_EN => ACK_EN,
ATN_INn => ATN_INn,
ATN_OUTn => ATN_OUTn,
ATN_EN => ATN_EN,
REQ_INn => REQ_INn,
REQ_OUTn => REQ_OUTn,
REQ_EN => REQ_EN,
IOn_IN => IOn_IN,
IOn_OUT => IOn_OUT,
IO_EN => IO_EN,
CDn_IN => CDn_IN,
CDn_OUT => CDn_OUT,
CD_EN => CD_EN,
MSG_INn => MSG_INn,
MSG_OUTn => MSG_OUTn,
MSG_EN => MSG_EN
);
end STRUCTURE;