📄 target_fsm.vhd
字号:
--*****************************************************************************
--* *
--* EuCore PCI-T32 - PCI Target Interface Core *
--* (C)2000 MaxLock, Inc. All rights reserved *
--* *
--*****************************************************************************
-- FILE : TARGET_FSM.vhd
-- DATE : 10.1.2001
-- REVISION: 1.1
-- DESIGNER: Tony
-- Descr : Target State Machine
-- Entities: TARGET_FSM
-- Changes :
--
-- ******************************************************
-- * Target State Machine Entities *
-- ******************************************************
library IEEE;
use IEEE.std_logic_1164.all;
entity TARGET_FSM is
port (
CLK : in std_logic; -- PCI Clock
RESET : in std_logic; -- PCI Reset
FRAMEni : in std_logic; -- PCI Frame#
FRAMEnid : in std_logic; -- PCI Frame#
IRDYni : in std_logic; -- PCI Irdy#
IRDYnid : in std_logic; -- PCI Irdy#
TRDYnid : in std_logic; -- PCI Irdy#
HIT : in std_logic; -- Hit on address decode
DRDY : in std_logic; -- Ready to transfer data
TERM : in std_logic; -- Terminate transaction
ABORT : in std_logic; -- Target error - abort transaction
ACC_WR : in std_logic; -- Command is Write
ACC_RD : in std_logic; -- Command is Read
NEW_DEVSELno: out std_logic; -- PCI Devsel#
NEW_TRDYno : out std_logic; -- PCI Trdy#
NEW_STOPno : out std_logic; -- PCI Stop#
CE_ADoDIR : out std_logic; -- Data Output FFs Clock Enable Direct
CE_ADoRDY : out std_logic; -- Data Output FFs Clock Enable Ready
NEW_OT_AD : out std_logic; -- PCI AD bus enable
OT_TRDYn : out std_logic; -- PCI Trdy# enable
OT_STOPn : out std_logic; -- PCI Stop# enable
OT_DEVSELn : out std_logic; -- PCI Devsel# enable
ACC_START : out std_logic; -- Start of Target Device Access
ACC_END : out std_logic; -- End of Target Device Access
D_SENT : out std_logic; -- Data Sent
INC_ADR : out std_logic; -- Incement Address Counter
T_NEXTD : out std_logic; -- Target ready to process NEXT Data
T_WE : out std_logic; -- Target Write Enable
T_WR : out std_logic; -- Target Write in progress
T_RD : out std_logic -- Target Read in progress
);
end TARGET_FSM;
--
--
--
architecture RTL of TARGET_FSM is
-- FSM State Definition
type tTargetFsm is (Idle, B_Busy, S_Data, Turn_Ar);
attribute ENUM_ENCODING: string;
attribute ENUM_ENCODING of tTargetFsm : type is "0001 0010 0100 1000";
-- Local Signals
signal TargetState, nextState: tTargetFsm; -- FSM State
signal LDEVSELno, LTRDYno, LSTOPno,LOTCTRL: std_logic;--
signal LCE_ADo, LCE_ADod : std_logic; --
signal WaitD : std_logic; --
signal WR_INC: std_logic;
begin
-- Target State Registers
Sync : process (CLK, RESET)
begin
if (RESET = '1') then
TargetState <= Idle;
elsif (CLK'event and CLK = '1') then
TargetState <= nextState;
end if;
end process;
-- Process to generate next state logic
nxtStProc: process (TargetState, FRAMEni, FRAMEnid,HIT, IRDYni, LTRDYno,
LDEVSELno, LSTOPno, TERM, DRDY)
begin
case TargetState is
when Idle =>
if FRAMEni = '0' and FRAMEnid /= '0' then
nextState <= B_Busy;
else
nextState <= Idle;
end if;
when B_Busy =>
if FRAMEnid = '0' and HIT = '1' then
nextState <= S_Data;
else
nextState <= Idle;
end if;
when S_Data =>
if (FRAMEni='1' and IRDYni='0' and (LTRDYno='0'or LSTOPno='0')) then
nextState <= Turn_Ar;
else
nextState <= S_Data;
end if;
when Turn_Ar =>
if (FRAMEni = '0' and HIT = '0') then
nextState <= B_Busy;
else
nextState <= Idle;
end if;
-- when BackOff =>
-- nextState <= Idle;
end case;
end process nxtStProc;
--*************************************
-- Processes to generate outputs
--*************************************
-- Local DEVSEL# signal
pLDEVSELn : process (CLK,RESET)
begin
if (RESET = '1') then
LDEVSELno <= '1';
elsif (CLK'event and CLK = '1') then
if TargetState = B_Busy and FRAMEnid = '0' and HIT = '1' then
LDEVSELno <= '0';
elsif TargetState = S_Data and ((FRAMEni='1' and IRDYni='0' and (LTRDYno='0'or LSTOPno='0'))or ABORT='1')then
LDEVSELno <= '1';
end if;
end if;
end process pLDEVSELn;
-- New DEVSEL# value - logic before OFF in IOB
pNewDEVSELn : process (TargetState,FRAMEnid,FRAMEni,IRDYni,LTRDYno, LSTOPno,HIT,ABORT)
begin
if (TargetState = B_Busy and FRAMEnid = '0' and HIT = '1') or
(TargetState = S_Data and not((FRAMEni='1' and IRDYni='0' and (LTRDYno='0'or LSTOPno='0'))or ABORT='1'))then
NEW_DEVSELno <= '0';
else
NEW_DEVSELno <= '1';
end if;
end process pNewDEVSELn;
-- Wait for data
pWaitD: process(CLK,RESET)
begin
if (RESET = '1') then
WaitD <= '0';
elsif (CLK'event and CLK = '1') then
if (TargetState = B_Busy and HIT='1' and (FRAMEni='0' or IRDYni='0')) or -- initial data phase
(TargetState = S_Data and IRDYni='0' and LTRDYno='0' and DRDY='0') then -- data not ready
WaitD <= '1';
elsif(TargetState=Turn_Ar) or (DRDY='1') then
WaitD <= '0';
end if;
end if;
end process pWaitD;
-- TRDY# signal
pLTRDYn : process (CLK,RESET)
begin
if (RESET = '1') then
LTRDYno <= '1';
elsif (CLK'event and CLK = '1') then
if LTRDYno='0'and IRDYni = '0' and (FRAMEni ='1' or DRDY='0') then
LTRDYno <= '1';
elsif (TargetState = S_Data)and(DRDY='1')then
LTRDYno <= '0';
end if;
end if;
end process pLTRDYn;
-- New TRDY# value - logic before OFF in IOB
pNewTRDYn : process (TargetState,DRDY,LTRDYno,IRDYni,FRAMEni,DRDY)
begin
if (TargetState = S_Data and DRDY='1'and LTRDYno='1')or
(LTRDYno='0' and not(IRDYni = '0' and (FRAMEni ='1' or DRDY='0'))) then
NEW_TRDYno <= '0';
else
NEW_TRDYno <= '1';
end if;
end process pNewTRDYn;
-- local STOP# signal
pLSTOPn : process (CLK,RESET)
begin
if (RESET = '1') then
LSTOPno <= '1';
elsif (CLK'event and CLK = '1') then
if LSTOPno='0' and FRAMEni ='1' and IRDYni = '0' then
LSTOPno <= '1';
elsif (TargetState = S_Data) and (TERM ='1'or ABORT='1') then
LSTOPno <= '0';
end if;
end if;
end process pLSTOPn;
-- New STOP# value - logic before OFF in IOB
pNewSTOPn: process (TargetState,TERM,ABORT,LSTOPno,FRAMEni,IRDYni)
begin
if ((TargetState = S_Data) and (TERM ='1'or ABORT='1')and LSTOPno='1')or
(LSTOPno='0' and not(FRAMEni ='1' and IRDYni = '0'))then
NEW_STOPno <= '0';
else
NEW_STOPno <= '1';
end if;
end process pNewSTOPn;
--
pCE_ADoDIR: process(TargetState,DRDY,WaitD)
begin
if TargetState = S_Data and WaitD='1' and DRDY='1' then
CE_ADoDIR <= '1';
else
CE_ADoDIR <= '0';
end if;
end process pCE_ADoDIR;
--
pCE_ADoRDY: process(TargetState,DRDY,LTRDYno)
begin
if TargetState = S_Data and LTRDYno='0' and DRDY='1' then
CE_ADoRDY <= '1';
else
CE_ADoRDY <= '0';
end if;
end process pCE_ADoRDY;
-- Local value of clock enable control of Output Data FFs
pLCE_ADo: process(TargetState,IRDYni,LTRDYno,DRDY,WaitD)
begin
if TargetState = S_Data and ((IRDYni='0'and LTRDYno='0' and DRDY='1') or
(WaitD='1' and DRDY='1'))then
LCE_ADo <= '1';
else
LCE_ADo <= '0';
end if;
end process pLCE_ADo;
-- Control of Data Output Buffer
OutOTAD : process (TargetState,ACC_RD,FRAMEni,IRDYni,LTRDYno,LSTOPno)
begin
if (TargetState = S_Data)and(ACC_RD='1')and not(FRAMEni='1' and IRDYni='0' and (LTRDYno='0'or LSTOPno='0'))then
NEW_OT_AD <= '0';
else
NEW_OT_AD <= '1';
end if;
end process OutOTAD;
-- Outbut Buffer control of PCI Control signals
pOTCTRL:process(FRAMEni,IRDYni,HIT,TargetState)
begin
if ((FRAMEni = '0' or IRDYni = '0') and HIT = '1'and TargetState=B_Busy) or TargetState=S_Data then
LOTCTRL <= '0';
else
LOTCTRL <= '1';
end if;
end process;
-- DEVSEL# output tri-state buffer control
OTDEVSELn:process(RESET,CLK)
begin
if RESET='1' then
OT_DEVSELn <= '1';
elsif CLK'event and CLK='1' then
OT_DEVSELn <= LOTCTRL;
end if;
end process;
-- TRDY# output tri-state buffer control
OTTRDYn:process(RESET,CLK)
begin
if RESET='1' then
OT_TRDYn <= '1';
elsif CLK'event and CLK='1' then
OT_TRDYn <= LOTCTRL;
end if;
end process;
-- STOP# output tri-state buffer control
OTSTOPn:process(RESET,CLK)
begin
if RESET='1' then
OT_STOPn <= '1';
elsif CLK'event and CLK='1' then
OT_STOPn <= LOTCTRL;
end if;
end process;
--
P_ACCSTART : process (TargetState, Hit) -- New access beginnig signaling
begin
if (TargetState = B_BUSY) and (Hit = '1') then
ACC_START <= '1';
else
ACC_START <= '0';
end if;
end process P_ACCSTART;
-- End of current target access
P_ACCEND : process (TargetState)
begin
if (TargetState = Turn_Ar)then
ACC_END <= '1';
else
ACC_END <= '0';
end if;
end process P_ACCEND;
-- Write Enable
pTWE:process(TargetState,ACC_WR,TRDYnid,IRDYnid)
begin
if (TargetState /= Idle)and(ACC_WR='1')and(TRDYnid='0')and(IRDYnid='0')then
T_WE <= '1';
else
T_WE <= '0';
end if;
end process;
-- Target Write In Progress
pTWR:process(TargetState,ACC_WR,TRDYnid,IRDYnid)
begin
if (TargetState /= Idle)and(ACC_WR='1')then
T_WR <= '1';
else
T_WR <= '0';
end if;
end process;
-- Target Read In Progress
pTRD:process(TargetState,ACC_RD)
begin
if (TargetState = S_Data)and(ACC_RD='1')then
T_RD <= '1';
else
T_RD <= '0';
end if;
end process;
-- Registered version of CE_ADo signal
pCE_ADod: process(CLK,RESET)
begin
if RESET='1' then
LCE_ADod <= '0';
elsif CLK'event and CLK='1' then
LCE_ADod <= LCE_ADo;
end if;
end process;
-- Next Data
pTNEXTD:process(TargetState,ACC_RD,LCE_ADod,WR_INC)
begin
if ACC_RD='1' then -- read operation
if (TargetState = S_DATA) then
T_NEXTD <= LCE_ADod;
else
T_NEXTD <= '0';
end if;
else -- write operation
if (TargetState /= Idle) then
T_NEXTD <= WR_INC;
else
T_NEXTD <= '0';
end if;
end if;
end process;
pWR_INC:process(RESET,CLK)
begin
if RESET='1' then
WR_INC <= '0';
elsif CLK'event and CLK='1' then
WR_INC <= not(IRDYnid or TRDYnid);
end if;
end process;
-- Increment Target Address Counter in PCI_CMDADR entity
pINC_ADR:process(TargetState,ACC_RD,LCE_ADod,WR_INC)
begin
if ACC_RD='1' then -- read operation
if (TargetState = S_DATA) then
INC_ADR <= LCE_ADod;
else
INC_ADR <= '0';
end if;
else -- write operation
if (TargetState /= Idle) then
INC_ADR <= WR_INC;
else
INC_ADR <= '0';
end if;
end if;
end process;
-- Assign output ports
-- CE_ADo <= LCE_ADo;
-- DEVSELno <= LDEVSELno;
-- TRDYno <= LTRDYno;
-- STOPno <= LSTOPno;
D_SENT <= not(LTRDYno);
end RTL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -