📄 dmacntrl.vhd
字号:
--------------------------------------------------------------------------------
--
-- File : dmacntrl.vhd
-- Last Modification: 06/26/2001
--
-- Created In SpDE Version: SpDE 8.22
-- Author : Richard Yuan, QuickLogic Corporation
-- Copyright (C) 2001, Licensed Customers of QuickLogic may copy and modify
-- this file for use in designing with QuickLogic devices only.
--
-- Description : DMA Controller Reference Design for 5332/5432.
-- See the QuickPCI User's Guide for a detailed description of functionality.
-- Note that this DMA Controller Reference Design is different from that of 5032/5232.
--
-- Hierarchy:
-- This file represents the dmacntrl block in pci5432_208.sch.
--
-- History:
-- Date Author Version
-- 06/26/01 Richard Yuan 1.0
-- - Header reorganized to conform to coding standard.
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ucount30 is
port (
CLK, CLR: in std_logic;
D: in std_logic_vector(29 downto 0);
EN, load: in std_logic;
Q: out std_logic_vector(29 downto 0)
);
end ucount30;
architecture behavioral of ucount30 is
signal Q_local: unsigned(29 downto 0);
begin
Q <= std_logic_vector(Q_local);
process(CLK, CLR)
begin
if CLR = '1' then Q_local <= (others => '0');
elsif CLK'event and CLK = '1' then
if LOAD = '1' then Q_local <= unsigned(D);
elsif EN = '1' then Q_local <= Q_local + 1;
end if;
end if;
end process;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity dmacntrl is
generic (
Burst_Length: std_logic_vector(7 downto 0) := "11111111"; -- Set to desired PCI burst length, up to 255
-- DMA Burst State Machine (one-hot)
idle : std_logic_vector(4 downto 0) := "00001";
dma_wr : std_logic_vector(4 downto 0) := "00010";
dma_wr_wt: std_logic_vector(4 downto 0) := "00100";
dma_rd : std_logic_vector(4 downto 0) := "01000";
dma_rd_wt: std_logic_vector(4 downto 0) := "10000";
idle_bt : integer := 0;
dma_wr_bt : integer := 1;
dma_wr_wt_bt: integer := 2;
dma_rd_bt : integer := 3;
dma_rd_wt_bt: integer := 4
);
port (
PCI_reset: in std_logic; -- PCI Reset, active high & asynchronous
PCI_clk: in std_logic; -- PCI Clk (33 MHz)
Usr_CBE: in std_logic_vector(3 downto 0); -- Registered PCI CBE signals [3:0]
Usr_Ad: in std_logic_vector(9 downto 2); -- PCI Target Address [9:2]
Usr_WrData: in std_logic_vector(31 downto 0); -- Registered PCI Data Signals [31:0]
Usr_RdDataIn: in std_logic_vector(31 downto 0);-- Data for User Reads not decoded within this block [31:0]
Mst_Tabort_Det: in std_logic; -- Target aborting transfer this cycle
Mst_Xfer_D1: in std_logic; -- Delayed XFER Detected on PCI
Mst_TTO_Det: in std_logic; -- Target did not assert DEVSEL in time
Usr_Write: in std_logic; -- Write Data on PCI pins addressed to DMA Registers
IncrAddr: in std_logic; -- Address increment signal, used to enable writing to dma regs.
BusMstEn: in std_logic; -- PCI Config Command Bit 2 (bus mastering enabled)
RdRdy: in std_logic; -- Read FIFO has room for data from PCI
WrRdy: in std_logic; -- Write FIFO is ready to send data to PCI
LastWr: in std_logic; -- End of Packet Signal from FIFO
Mst_WrBurst_Done: in std_logic; -- Write Pipeline is clear (including output register)
Mst_RdBurst_Done: in std_logic; -- Read Pipeline is clear
Mst_WrData_Rdy: in std_logic; -- Write Pipeline is ready for new data
Mst_BE_FIFO: in std_logic_vector(3 downto 0); -- Byte-enables from the BE FIFO
Mst_RdData_Valid: in std_logic; -- Data strobe from PCI core for master read
Mst_RdAd: out std_logic_vector(31 downto 0); -- Decoded for Reads of DMA registers [31:0]
Mst_WrAd: out std_logic_vector(31 downto 0); -- Decoded for Reads of DMA registers [31:0]
Usr_RdData: out std_logic_vector(31 downto 0); -- For Target Reads of DMA registers [31:0]
Mst_WrData_Valid: out std_logic;-- In active write state (not flushing pipeline)
DMAWrEn: out std_logic; -- Software controlled enable for the write FIFO
DMARdEn: out std_logic; -- Software controlled enable for the read FIFO
LocalEn: out std_logic; -- Software controlled enable for back-end target accesses
Mst_Burst_Req: out std_logic; -- Tells master to assert REQN
Mst_One_Read: out std_logic; -- one read remains in burst
Mst_Two_Reads: out std_logic; -- two reads remain in burst
MstRdAd_Sel: out std_logic; -- Address for Master Read Address has been selected
MstWrAd_Sel: out std_logic; -- Address for Master Write Address has been selected
Mst_LatCntEn: out std_logic; -- Enables Latency Counter for Master Transactions
PCI_Cmd: out std_logic_vector(3 downto 0); -- Specifies the PCI Command to Use [3:0]
BEfifo: out std_logic; -- Push signal for the BE FIFO
Mst_BE_Sel: out std_logic; -- Selects which byte-enable mode
Mst_BE: out std_logic_vector(3 downto 0); -- Byte-enable signal for master transactions [3:0]
Mst_Rd_Term_Sel: out std_logic; -- Master read termination mode
WD_Reg: out std_logic_vector(31 downto 0); -- Master data reg output [31:0]
Mst_Data_Sel: out std_logic -- Selects whether FIFO or WD_Reg is read/written
);
end dmacntrl;
architecture behavioral of dmacntrl is
signal DMASm: std_logic_vector(4 downto 0);
signal Mst_RdBE_Load_Done: std_logic;
signal Burst_Cnt2: std_logic_vector(7 downto 0);
signal Dec_BCnt2, BCnt2_eq_1: std_logic;
signal DMACntReg, DMACtrlStat: std_logic_vector(31 downto 0);
signal DMARdCnt, DMAWrCnt: std_logic_vector(15 downto 0);
signal Burst_Cnt, RdBCnt, WrBCnt, Init_BCnt: std_logic_vector(7 downto 0);
signal BCnt_eq_1, BCnt_eq_2, BCnt_eq_3: std_logic;
signal PCIWrEn, PCIRdEn, Mst_RdMode_local: std_logic;
signal Ld_BCnt, LdWrCnt, LdRdCnt: std_logic;
signal LdRdAdrCnt, LdWrAdrCnt, DecDMARdCnt, Dec_BCnt: std_logic;
signal IncWrAdr, IncRdAdr: std_logic;
signal Mst_RdMode, Mst_WrMode: std_logic;
signal Mst_RdCmd: std_logic_vector(3 downto 0);
signal Mst_WrCmd: std_logic_vector(2 downto 0);
signal WrCnt0, RdCnt0: std_logic;
signal DMAWrEn_local, DMARdEn_local, DMAWrErr: std_logic;
signal DMARdErr, LocalEn_local, Mst_LatCntEn_local: std_logic;
signal DecDMAWrCnt: std_logic;
signal WrCtrl, WrRdAdr, WrWrAdr, WrDMACnt, WrDReg: std_logic;
signal Mst_RdBE, Mst_WrBE: std_logic_vector(3 downto 0);
signal Mst_WrBE_Sel, Mst_RdBE_Sel: std_logic;
signal Mst_D_Reg: std_logic_vector(31 downto 0);
signal Mst_WrData_Sel, Mst_RdData_Sel: std_logic;
signal Mst_Rd_Term_Sel_local: std_logic;
component ucount30
port ( CLK, CLR: in std_logic;
D: in std_logic_vector(29 downto 0);
EN, load: in std_logic;
Q: out std_logic_vector(29 downto 0) );
end component;
component dcount16
port ( CLK, CLR: in std_logic;
D: in std_logic_vector(15 downto 0);
EN, load: in std_logic;
Q: out std_logic_vector(15 downto 0) );
end component;
component dcount8
port ( CLK, CLR: in std_logic;
D: in std_logic_vector(7 downto 0);
EN, load: in std_logic;
Q: out std_logic_vector(7 downto 0) );
end component;
begin
DMAWrEn <= DMAWrEn_local;
DMARdEn <= DMARdEn_local;
LocalEn <= LocalEn_local;
Mst_LatCntEn <= Mst_LatCntEn_local;
Mst_Rd_Term_Sel <= Mst_Rd_Term_Sel_local;
-- PCI command decoded from various registers
-- This decoding process is to be compatible with 5032/5232 reference design
-- More straightforward approach may be used to simplify logic
process (Mst_RdMode, Mst_WrMode, Mst_RdCmd, Mst_WrCmd)
begin
if Mst_RdMode = '1' then
if Mst_RdCmd(3) = '0' then
case Mst_RdCmd(1 downto 0) is
when "00" | "01"=> PCI_Cmd <= "0110";
when "10"=> PCI_Cmd <= "1110";
when "11"=> PCI_Cmd <= "1100";
when others=> PCI_Cmd <= "0110";
end case;
else
PCI_Cmd <= Mst_RdCmd(2 downto 0) & '0';
end if;
elsif Mst_WrMode = '1' then
if Mst_WrCmd(2 downto 0) /= "000" then
if Mst_WrCmd = "011" then PCI_Cmd <= "0001";
else PCI_Cmd <= Mst_WrCmd & '1';
end if;
else PCI_Cmd <= "0111";
end if;
else PCI_Cmd <= "0110";
end if;
end process;
-- Master byte-enable mode generation
process (Mst_RdMode, Mst_RdBE_Sel, Mst_WrBE_Sel, Mst_RdBE, Mst_WrBE, Mst_BE_FIFO)
begin
if Mst_RdMode = '1' then
if Mst_RdBE_Sel = '1' then Mst_BE <= Mst_BE_FIFO;
else Mst_BE <= Mst_RdBE;
end if;
else
if Mst_WrBE_Sel = '1' then Mst_BE <= Mst_BE_FIFO;
else Mst_BE <= Mst_WrBE;
end if;
end if;
end process;
-- Data and BE source/destination selection for master transactions
Mst_Data_Sel <= Mst_RdData_Sel when Mst_RdMode = '1' else Mst_WrData_Sel;
Mst_BE_Sel <= Mst_RdBE_Sel when Mst_RdMode = '1' else Mst_WrBE_Sel;
-- DMA Register Read Addressing
with Usr_Ad(9 downto 2) select
Usr_RdData <= DMACntReg when "01000000"|"01000001", -- address 0x100 and 0x104
DMACtrlStat when "01000010"|"01000011", -- address 0x108 and 0x01C
Mst_D_Reg when "01000111", -- address 0x11c
Usr_RdDataIn when others;
process (Usr_Ad)
begin
MstWrAd_Sel <= '0';
MstRdAd_Sel <= '0';
case Usr_Ad is
when "01000001" => MstWrAd_Sel <= '1'; -- address 0x104
when "01000010" => MstRdAd_Sel <= '1'; -- address 0x108
when others => null;
end case;
end process;
-- DMA Register Write Addressing
process (Usr_Write, IncrAddr, Usr_Ad)
begin
WrCtrl <= '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -