if_main.vhd
来自「基于4个mips核的noc设计」· VHDL 代码 · 共 565 行 · 第 1/2 页
VHD
565 行
SM_STATE <= WAIT_ADDRCHK;
RDl_WRi <= '1';
RENl_WENli <= '1';
WR_DMAi <= '0';
elsif TERM_CNT='1' then
RDl_WRi <= '0';
RENl_WENli <= '1';
WR_DMAi <= '0';
if AS_DSl='1' then
SM_STATE <= WAIT_ADDRDEC;
DATA_READY <= '1';
else
SM_STATE <= WR_REG;
DATA_READY <= '1';
end if;
elsif DMA_IN_FULL='1' then
SM_STATE <= WAIT_END_DMARD;
RDl_WRi <= '0';
RENl_WENli <= '1';
WR_DMAi <= '1';
else
if AS_DSl='1' then
RDl_WRi <= '1';
RENl_WENli <= '1';
SM_STATE <= WAIT_ADDRDEC;
DATA_READY <= '1';
WR_DMAi <= '0';
else
RDl_WRi <= '0';
RENl_WENli <= '0';
WR_DMAi <= '1';
end if;
end if;
-- Wait before going to address decode.
-- This allows the address to be stored.
when WAIT_ADDRDEC =>
SM_STATE <= ADDR_DEC;
-- Make sure that Spartan doesn't want to send data before sending data.
-- Make sure that there is data to send.
when DMA_WRITE =>
RD_DMAi <= '0';
if EMPTY='0' then
SM_STATE <= WAIT_ENDTRANS;
RDl_WRi <= '1';
RENl_WENli <= '1';
elsif TERM_CNT='1' then
SM_STATE <= WAIT_ENDTRANS;
RDl_WRi <= '1';
RENl_WENli <= '0';
elsif BUSYd1='0' then
if BUSY='0' then
RD_DMAi <= '1';
else
RD_DMAi <= '0';
end if;
if RD_DMAii='1' then
RDl_WRi <= '1';
RENl_WENli <= '0';
else
RDl_WRi <= '1';
RENl_WENli <= '1';
end if;
else
RENl_WENli <= '1';
end if;
-- Wait for DMA input to not be full to write the data that has been captured.
when WAIT_DMA_RD =>
if DMA_IN_FULL='0' then
WR_DMAi <='1';
SM_STATE <= WAIT_ENDTRANS;
end if;
-- Check to see if last data captured is an address.
when WAIT_ADDRCHK =>
if AS_DSl_IN='1' then
SM_STATE <= ADDR_DEC;
DATA_READY <= '0';
else
SM_STATE <= IDLE;
end if;
-- Wait before enabling DMA write.
when WAIT_TO_DMAWR =>
if EMPTYd1='0' then
SM_STATE <= IDLE;
else
if DMA_OUT_EMPTY='0' then
RD_DMAi <= '1';
SM_STATE <= DMA_WRITE;
end if;
end if;
-- DMA read has ended.
when WAIT_END_DMARD =>
SM_STATE <= IDLE;
RDl_WRi <= '1';
WR_DMAi <= '0';
when others =>
SM_STATE <= RST_STATE;
RDl_WRi <= '1';
RENl_WENli <= '1';
DATA_READY <= '0';
WR_DMAi <= '0';
RD_DMAi <= '0';
end case;
end if;
end process;
-- Delay busy and empty by one clock.
process (RST, CLK)
begin
if RST='1' then
EMPTYd1 <= '1';
BUSYd1 <= '1';
elsif CLK'event and CLK='1' then
EMPTYd1 <= EMPTY;
BUSYd1 <= BUSY;
end if;
end process;
-- Generate RDl_WR and RENl_WENl.
RDl_WR <= RDl_WRi;
RENl_WENl <= RENl_WENli;
-- Control for writing address.
ADDRESS_WR <= '1' when (SM_STATE=DATA_READ and AS_DSl_IN='1') or SM_STATE=WAIT_ADDRDEC or (SM_STATE=WAIT_DATACHK and AS_DSl_IN='1') or (SM_STATE=WAIT_ADDRCHK and AS_DSl_IN='1')else '0';
-- Write new address.
process (RST, CLK)
begin
if RST='1' then
ADDRESSi <= (others => '0');
elsif CLK'event and CLK='1' then
if ADDRESS_WR='1' then
ADDRESSi <= DATAIN;
end if;
end if;
end process;
ADDRESS <= ADDRESSi(30 downto 0);
-- Generate data valid.
process (RST, CLK)
begin
if RST='1' then
DVALIDd1 <= '0';
elsif CLK'event and CLK='1' then
DVALIDd1 <= DVALID;
end if;
end process;
-- Generate signal that writes to register.
WR_REG_WR <= '1' when SM_STATE=WR_REG and DATA_READY='0' and EMPTYd1='0' else '0';
process (RST, CLK)
begin
if RST='1' then
WR_REG_WRd1 <= '0';
elsif CLK'event and CLK='1' then
WR_REG_WRd1 <= WR_REG_WR;
end if;
end process;
-- Control for writing data in.
DATAIN_WR <= '1' when SM_STATE=WAIT_DATA or SM_STATE=DMA_READ or SM_STATE=WAIT_ADDRDEC or SM_STATE=WAIT_END_DMARD or (WR_REG_WRd1='1') else '0';
-- Write data into buffer. Store address/data strobe also.
process (RST, CLK)
begin
if RST='1' then
AS_DSl_IN <= '0';
DATAIN <= (others => '0');
elsif CLK'event and CLK='1' then
if DATAIN_WR='1' then
AS_DSl_IN <= AS_DSl;
DATAIN <= ADIO;
end if;
end if;
end process;
-- Generate write strobe and read strobe.
WRITE_STROBEi <= '1' when (WR_REG_WRd1='1') or (SM_STATE=WR_REG and DATA_READY='1') else '0';
READ_STROBEi <= '1' when (SM_STATE=RD_REG) else '0';
process (RST, CLK)
begin
if RST='1' then
WRITE_STROBEid1 <= '0';
elsif CLK'event and CLK='1' then
WRITE_STROBEid1 <= WRITE_STROBEi;
end if;
end process;
WR_STROBE <= WRITE_STROBEid1;
RD_STROBE <= READ_STROBEi;
-- Internal address decode.
MEM_BLOCK0_EN <= '1' when ADDRESSi(((NUM_BLOCKSg+BLOCK_SIZEg)-1) downto (BLOCK_SIZEg)) = ZEROS((NUM_BLOCKSg-1) downto 0) else '0';
-- CSR decode.
WR_CSR <= '1' when (MEM_BLOCK0_EN='1') and (ADDRESSi((NUM_REGSg-1) downto 0) = ZEROS((NUM_REGSg-1) downto 0)) and (WRITE_STROBEid1='1') else '0';
RD_CSR <= '1' when (MEM_BLOCK0_EN='1') and (ADDRESSi((NUM_REGSg-1) downto 0) = ZEROS((NUM_REGSg-1) downto 0)) and (READ_STROBEi='1') else '0';
-- DMA Count decode.
WR_COUNT <= '1' when (MEM_BLOCK0_EN='1') and (ADDRESSi((NUM_REGSg-1) downto 0) = ONE((NUM_REGSg-1) downto 0)) and (WRITE_STROBEid1='1') else '0';
RD_COUNTi <= '1' when (MEM_BLOCK0_EN='1') and (ADDRESSi((NUM_REGSg-1) downto 0) = ONE((NUM_REGSg-1) downto 0)) and (READ_STROBEi='1') else '0';
--RD_COUNT <= RD_COUNTi;
-- Generate DMA write.
process (RST, CLK)
begin
if RST='1' then
WR_DMAid1 <= '0';
elsif CLK'event and CLK='1' then
WR_DMAid1 <= WR_DMAi;
end if;
end process;
WR_DMA <= '0' when WR_DMAid1='0' or SM_STATE=WAIT_ADDRDEC or (SM_STATE=WAIT_ADDRCHK and AS_DSl_IN='1') else '1';
--RD_DMA <= RD_DMAi;
-- Generate DMA read.
RD_DMAii <= '1' when RD_DMAi='1' and SM_STATE = DMA_WRITE and DMA_OUT_EMPTY='0' else '0';
RD_DMA <= RD_DMAii;
-- CSR register.
process (RST, CLK)
begin
if RST='1' then
CSR(6 downto 0) <= (others => '0');
CSR(7) <= '0';
CSR(8) <= '1';
CSR(9) <= '0';
CSR(10) <= '1';
elsif CLK'event and CLK='1' then
CSR(7) <= DMA_IN_FULL;
CSR(8) <= DMA_IN_EMPTY;
CSR(9) <= DMA_OUT_FULL;
CSR(10) <= DMA_OUT_EMPTY;
if WR_CSR='1' then
CSR(6 downto 0) <= DATAIN(6 downto 0);
end if;
end if;
end process;
CSR(31 downto 11) <= (others => '0');
-- DMA enable signals derived from CSR.
DMA_RD_EN <= '1' when CSR(0)='1' and CSR(1)='0' else '0';
DMA_WR_EN <= '1' when CSR(0)='1' and CSR(1)='1' else '0';
DMA_ENABLE <= CSR(0);
DMA_DIRECTION <= CSR(1);
DMA_SEL <= CSR(5 downto 2);
DMA_RST <= CSR(6);
-- Data out for DMA count.
COUNT_IN <= DATAIN;
-- Data bus output.
DATA <= COUNT_OUT when RD_COUNTi='1' else (others => 'Z');
DATA <= DMA_OUT when RD_DMAi='1' else (others => 'Z');
DATA <= CSR when RD_CSR='1' else (others => 'Z');
DATA <= DATAIN when WRITE_STROBEid1='1' else (others => 'Z');
DATAOUTi <= DATA;
-- Store data output.
process (RST, CLK)
begin
if RST='1' then
DATAOUT <= (others => '0');
elsif CLK'event and CLK='1' then
if READ_STROBEi='1' or RD_DMAi='1' then
DATAOUT <= DATAOUTi;
end if;
end if;
end process;
-- DMA input data.
DMA_IN <= DATAIN;
-- Determine if Virtex is driving ADIO.
ADIO <= DATAOUT when RDl_WRi='1' else (others => 'Z');
end if_main_arch;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?