if_main.vhd
来自「基于4个mips核的noc设计」· VHDL 代码 · 共 565 行 · 第 1/2 页
VHD
565 行
------------------------------------------------------------------
-- --
-- If_main.vhd - Main Interface Control --
-- Paul Dunn - Nallatech Ltd Copyright 1999 --
-- Description - --
-- This process contains the main state machine for --
-- controlling the interface between the Virtex and the --
-- Spartan on the Ballynuey. --
-- This process also contains the main CSR. This CSR --
-- controls the DMA engine (enables and determines --
-- direction). --
-- --
------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity if_main is
generic (-- Number of memory blocks in memory map in bit size.
NUM_BLOCKSg : integer range 1 to 29;-- := 4;
-- Block size.
BLOCK_SIZEg : integer range 1 to 29;--:= 8;
-- Number of registers.
NUM_REGSg : integer range 1 to 29-- := 4
);
port ( -- Spartan - Virtex clock.
CLK: in STD_LOGIC;
-- Global reset
RST: in STD_LOGIC;
-- Synchronous reset.
SYNC_RST: in STD_LOGIC;
-- Indicates if Spartan can receive data.
BUSY: in STD_LOGIC;
-- Indicates if Spartan has data to send.
EMPTY: in STD_LOGIC;
-- Address Strobe / Data Strobe.
AS_DSl: in STD_LOGIC;
-- DMA engine is writing to Spartan.
DMA_IN_FULL: in STD_LOGIC;
DMA_IN_EMPTY: in STD_LOGIC;
DMA_OUT_FULL: in STD_LOGIC;
-- DMA engine is reading from Spartan.
DMA_OUT_EMPTY: in STD_LOGIC;
-- Terminal count of DMA counter.
TERM_CNT: in STD_LOGIC;
-- DMA count output.
COUNT_OUT: in STD_LOGIC_VECTOR (31 downto 0);
-- DMA output.
DMA_OUT: in STD_LOGIC_VECTOR (31 downto 0);
-- Read Enable / Write Enable.
RENl_WENl: out STD_LOGIC;
-- Read / Write.
RDl_WR: out STD_LOGIC;
-- Load DMA count.
WR_COUNT: out STD_LOGIC;
-- Enable DMA engine.
DMA_ENABLE: out STD_LOGIC;
-- DMA direction.
DMA_DIRECTION: out STD_LOGIC;
-- DMA select.
DMA_SEL: out STD_LOGIC_VECTOR (3 downto 0);
-- DMA reset.
DMA_RST: out STD_LOGIC;
-- Active address.
ADDRESS: out STD_LOGIC_VECTOR (30 downto 0);
-- Write to active register.
WR_STROBE: out STD_LOGIC;
-- Read from active register.
RD_STROBE: out STD_LOGIC;
-- Write DMA.
WR_DMA: out STD_LOGIC;
-- Read DMA.
RD_DMA: out STD_LOGIC;
-- DMA count input.
COUNT_IN: out STD_LOGIC_VECTOR (31 downto 0);
-- DMA input.
DMA_IN: out STD_LOGIC_VECTOR (31 downto 0);
-- Data to and from Spartan.
ADIO: inout STD_LOGIC_VECTOR (31 downto 0);
-- Data to and from user's design.
DATA: inout STD_LOGIC_VECTOR (31 downto 0)
);
end if_main;
architecture if_main_arch of if_main is
-- Main control states of interface.
type IFACE_STATES is (RST_STATE, IDLE, WAIT_DATA, DATA_READ, ADDR_DEC, RD_REG, WR_REG, WAIT_TO_DMARD, WAIT_DATACHK, WAIT_ENDTRANS,
DMA_READ, WAIT_ADDRDEC, DMA_WRITE, WAIT_DMA_RD, WAIT_ADDRCHK, WAIT_TO_DMAWR, WAIT_END_DMARD);
signal SM_STATE : IFACE_STATES;
-- Delayed versions of busy and empty.
signal EMPTYd1 : std_logic;
signal BUSYd1 : std_logic;
-- Data input register.
signal DATAIN : std_logic_vector (31 downto 0);
-- Address strobe / Data strobe.
signal AS_DSl_IN : std_logic;
-- Address in.
signal ADDRESSi : std_logic_vector (31 downto 0);
-- Data valid required to determine valid data when in DMA read mode.
signal DVALID : std_logic;
signal DVALIDd1 : std_logic;
signal DVALIDd2 : std_logic;
-- Write data into input register.
signal DATAIN_WR : std_logic;
-- Write in address.
signal ADDRESS_WR : std_logic;
-- Memory block 0 is being addressed.
signal MEM_BLOCK0_EN : std_logic;
-- Internal read and write strobe signals.
signal READ_STROBEi : std_logic;
signal WRITE_STROBEi : std_logic;
signal WRITE_STROBEid1 : std_logic;
-- Read DMA count.
signal RD_COUNTi : std_logic;
-- Read DMA.
signal RD_DMAi : std_logic;
signal RD_DMAii : std_logic;
signal WR_DMAi, WR_DMAid1 : std_logic;
-- Write to Control/Status register.
signal WR_CSR : std_logic;
-- Read from control/status register.
signal RD_CSR : std_logic;
-- Control/status register.
signal CSR : std_logic_vector (31 downto 0);
-- Enable DMA read.
signal DMA_RD_EN : std_logic;
-- Enable DMA write.
signal DMA_WR_EN : std_logic;
-- Data is in buffer waiting to be processed.
signal DATA_READY : std_logic;
-- Internal use of signals RDl_WR and RENl_WENl.
signal RDl_WRi : std_logic;
signal RENl_WENli : std_logic;
-- Data out to be driven onto ADIO.
signal DATAOUTi : std_logic_vector (31 downto 0);
signal DATAOUT : std_logic_vector (31 downto 0);
signal WR_REG_WR : std_logic;
signal WR_REG_WRd1 : std_logic;
-- Constant values for zero and one. 32 bits wide.
constant ZEROS : std_logic_vector (31 downto 0) := (others => '0');
constant ONE : std_logic_vector (31 downto 0) := ( 0 => '1', others => '0');
begin
-- This state machine controls the all data to and from the Spartan.
-- Priority is given to reading data from the Spartan in case any CSRs need updating.
process (RST, CLK)
begin
if RST='1' then
SM_STATE <= RST_STATE;
RDl_WRi <= '1';
RENl_WENli <= '1';
DATA_READY <= '0';
WR_DMAi <= '0';
RD_DMAi <= '0';
elsif CLK'event and CLK='1' then
case SM_STATE is
-- Reset state ensures that the state machine remains reset until the whole design is definitely reset.
when RST_STATE =>
if SYNC_RST='1' then
SM_STATE <= RST_STATE;
RDl_WRi <= '1';
RENl_WENli <= '1';
DATA_READY <= '0';
WR_DMAi <= '0';
RD_DMAi <= '0';
else
SM_STATE <= IDLE;
end if;
-- When idle, check to see if there's data to be sent.
-- If there isn't, check to see if the DMA engine is set up to output data.
when IDLE =>
if EMPTYd1='0' then
SM_STATE <= WAIT_DATA;
RDl_WRi <= '0';
RENl_WENli <= '0';
elsif EMPTYd1='1' and DMA_WR_EN='1' and TERM_CNT='0' then
SM_STATE <= WAIT_TO_DMAWR;
end if;
-- Wait for data to be valid.
when WAIT_DATA =>
RDl_WRi <= '1';
RENl_WENli <= '1';
SM_STATE <= DATA_READ;
-- Firstly check to see if data is address or not.
-- If it is an address, go to address decode.
-- If it's not an address see if the data is for the DMA engine or not.
when DATA_READ =>
RDl_WRi <= '1';
RENl_WENli <= '1';
if AS_DSl_IN='1' then
SM_STATE <= ADDR_DEC;
elsif DMA_RD_EN='1' and TERM_CNT='0' then
if DMA_IN_FULL='1' then
SM_STATE <= WAIT_DMA_RD;
WR_DMAi <= '0';
elsif EMPTY='0' and DMA_IN_FULL='0' then
SM_STATE <= WAIT_TO_DMARD;
RDl_WRi <= '0';
RENl_WENli <= '0';
WR_DMAi <= '1';
elsif EMPTY='1' and DMA_IN_FULL='0' then
SM_STATE <= WAIT_ENDTRANS;
WR_DMAi <= '1';
end if;
else
DATA_READY <= '1';
SM_STATE <= WR_REG;
end if;
-- Determine if the address is being written to or read from.
when ADDR_DEC =>
if ADDRESSi(31)='0' then
SM_STATE <= WR_REG;
else
SM_STATE <= RD_REG;
end if;
-- Check to see if data has already been read.
-- If it hasn't, read from Spartan.
when WR_REG =>
if DATA_READY='0' then
if EMPTYd1='0' then
RDl_WRi <= '0';
RENl_WENli <= '0';
SM_STATE <= WAIT_DATACHK;
end if;
else
DATA_READY <= '0';
SM_STATE <= WAIT_DATACHK;
end if;
-- Read from register.
when RD_REG =>
RDl_WRi <= '1';
RENl_WENli <= '0';
SM_STATE <= WAIT_DATACHK;
-- Wait before going into DMA read.
when WAIT_TO_DMARD =>
RDl_WRi <= '0';
RENl_WENli <= '0';
WR_DMAi <= '1';
SM_STATE <= DMA_READ;
-- Check to see if there's still data to be processed.
-- If there is, determine the nature of the data.
when WAIT_DATACHK =>
RDl_WRi <= '1';
RENl_WENli <= '1';
if DATA_READY='1' then
if AS_DSl_IN='1' then
SM_STATE <= ADDR_DEC;
DATA_READY <= '0';
elsif DMA_RD_EN='1' and TERM_CNT='0' then
SM_STATE <= WAIT_TO_DMARD;
DATA_READY <= '0';
else
SM_STATE <= WR_REG;
end if;
else
SM_STATE <= WAIT_ENDTRANS;
end if;
-- Wait before going idle.
when WAIT_ENDTRANS =>
SM_STATE <= IDLE;
WR_DMAi <= '0';
RDl_WRi <= '1';
RENl_WENli <= '1';
-- Check that data in isn't an address.
-- Also check for terminal count.
-- If neither of these are true, check that it's okay to read data.
when DMA_READ =>
if EMPTY='1' then--or TERM_CNT='1' then
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?