You are on page 1of 7

DMA controller library ieee; library work; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use work.components.

all;

entity dma is Port ( clk rstn start dati adr register reg_wen fifo_wen wr_rdn cs bcr_cnten acr_cnten lar_cnten enable p2s_fifo_empty s2p_fifo_usedw mstr_busy stop abort last_xfr local_busy err_pend abort lm_tsr std_logics isr_rd isr csr bcr acr

: in std_logic; -- clock : in std_logic; -- reset : in std_logic; -- trigger state machine : in std_logic_vector(31 downto 0); -- data input : in std_logic_vector(7 downto 0); &nbsp-- address of the dma : in std_logic; : in std_logic; : in std_logic; : in std_logic; : in std_logic; : in std_logic; : in std_logic; -- dma register write enable -- dma fifo write enable -- write/read signal to dma registers -- chip select (dma_register) -- byte counter count enable -- address counter count enable -- local address counter count

: in std_logic; -- high and low p2s both empty : in std_logic_vector(6 downto 0); : in std_logic; : in std_logic; -- PCI core signals stop current dma : in std_logic; -- PCI core signals abort current dma : in std_logic; -- PCI core signals last transfer : in std_logic; -- sdram is busy : in std_logic; -- target abort, parity error, master : in std_logic_vector(9 downto 0); &nbsp-- master status : in std_logic; -- isr read signal

: out std_logic_vector(5 downto 0); : out std_logic_vector(8 downto 0); : out std_logic_vector(16 downto 0); : out std_logic_vector(31 downto 0);

lar : out std_logic_vector(25 downto 0); req : out std_logic; -- dma requesting a PCI core for data transfer local_start : out std_logic; -- dma requesting sdram controller to start data transfer dato : out std_logic_vector(31 downto 0); &nbsp-- dma register read data output probe : out std_logic_vector(7 downto 0) ); end dma; architecture rtl of dma is signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal signal normal_termination : std_logic; start_chain : std_logic; chain_end : std_logic; dma_bcr : std_logic_vector(16 downto 0); dma_csr : std_logic_vector(8 downto 0); dma_done : std_logic; dma_error : std_logic; chain_acr_ld : std_logic; chain_bcr_ld : std_logic; dma_fifo_rd : std_logic; trans64 : std_logic; isr_in : std_logic_vector(5 downto 0); dma_on : std_logic; dma_acr : std_logic_vector(31 downto 0); dma_isr : std_logic_vector(5 downto 0); dma_lar : std_logic_vector(25 downto 0); dma_fifo_dato : std_logic_vector(31 downto 0); soft_flush : std_logic; dma_reg_dati : std_logic_vector(31 downto 0); reg_dat_sel : std_logic; direction : std_logic; acr_wr : std_logic; csr_wr : std_logic; csr_wr_reg : std_logic; int_irq : std_logic; local_irq : std_logic; rst : std_logic; req_int : std_logic; high : std_logic; dma_reg_hit : std_logic_vector(4 downto 0);

begin &nbsphigh <= '1'; &nbsprst <= not rstn; &nbspsoft_flush <= dma_csr(1); register &nbspstart_chain <= dma_isr(5); &nbspdirection <= dma_csr(3);

&nbsp-- flush std_logic of the control status &nbsp-- DMA chaining mode enable &nbsp-- 1 for write, 0 for read

-- interrupt pending std_logic &nbspisr_in(0) <= err_pend or int_irq or (dma_isr(3) and not dma_csr(5)); &nbspint_irq <= local_irq; -- assert local irq when there is error pending or DMA has completed &nbsplocal_irq <= dma_isr(1) or (dma_isr(3) and not dma_csr(5)); &nbspisr_in(1) <= err_pend; &nbspisr_in(2) <= int_irq;

-- generate transfer complete status std_logic 3 &nbspprocess(dma_done, isr_rd, csr_wr, acr_wr, dma_isr) -- dma_tc begin &nbspif(dma_done = '1') then isr_in(3) <= '1'; &nbspelsif(isr_rd = '1' or csr_wr = '1' or acr_wr = '1') then isr_in(3) <= '0'; &nbspelse isr_in(3) <= dma_isr(3); &nbspend if; end process; -- write signal to the address counter &nbspacr_wr <= dma_reg_hit(1) and cs and reg_wen; -- generate ad_loaded singal for the isr std_logic 4 &nbspprocess(acr_wr, dma_isr, soft_flush, dma_done, dma_error) begin &nbspif(acr_wr = '1') then isr_in(4) <= '1'; &nbspelsif(dma_isr(3) = '1' or soft_flush = '1' or dma_done = '1' or dma_error = '1') then

isr_in(4) <= '0'; &nbspelse isr_in(4) <= dma_isr(4); &nbspend if; end process; -- control status register write signal &nbspcsr_wr <= dma_reg_hit(0) and cs and reg_wen; &nbspprocess(clk,rstn) &nbsp-- register csr_wr begin &nbspif(rstn='0') then csr_wr_reg <= '0'; &nbspelsif(clk'event and clk = '1') then csr_wr_reg <= csr_wr; &nbspend if; end process; -- generate start_chain std_logic &nbspprocess(csr_wr_reg, dma_isr, dma_csr, soft_flush, dma_done, dma_error) begin &nbspif (csr_wr_reg = '1' and dma_csr(8) = '1') then &nbsp-- start chain isr_in(5) <= '1'; &nbspelsif (dma_isr(3) = '1' or soft_flush = '1' or dma_done = '1' or dma_error ='1') then isr_in(5) <= '0'; &nbspelse isr_in(5) <= dma_isr(5); &nbspend if; end process;

-- generate dma_on std_logic csr(6) &nbspdma_on <= (dma_isr(4) and dma_csr(4) and not err_pend) or (isr_in(5) and dma_csr(4) and &nbspnot err_pend);

-- dma state machine instantiation dma_sm0 : dma_sm port map (

clk => &nbspclk, rstn => &nbsprstn, normal_termination => &nbspnormal_termination, stop => &nbspstop, lm_tsr => &nbsplm_tsr, err_pend => &nbsperr_pend, start => &nbspstart , start_chain => &nbspstart_chain, chain_end => &nbspchain_end, p2s_fifo_empty => &nbspp2s_fifo_empty, s2p_fifo_usedw => &nbsps2p_fifo_usedw, direction => &nbspdirection, dma_bcr => &nbspdma_bcr, local_busy => &nbsplocal_busy, req => &nbspreq_int, dma_done => &nbspdma_done, dma_error => &nbspdma_error, chain_acr_ld => &nbspchain_acr_ld, chain_bcr_ld => &nbspchain_bcr_ld, dma_fifo_rd => &nbspdma_fifo_rd, local_start => &nbsplocal_start, chain_dma_loading => &nbspreg_dat_sel );

-- DMA registers instantiation &nbspdma_reg0 : dma_reg &nbspport map ( clk => &nbspclk , rstn => &nbsprstn , adr => &nbspadr , dati => &nbspdma_reg_dati dati and dma_fifo_dato wen => &nbspreg_wen , acr_ld => &nbspchain_acr_ld bcr_ld => &nbspchain_bcr_ld acr_cnten => &nbspacr_cnten, lar_cnten => &nbsplar_cnten, bcr_cnten => &nbspbcr_cnten, isr_in => &nbspisr_in , dma_on => &nbspdma_on ,

-- mux output select between

, ,

cs acr bcr csr isr lar dato dma_reg_hit );

=> &nbspcs, => &nbspdma_acr , => &nbspdma_bcr , => &nbspdma_csr , => &nbspdma_isr , => &nbspdma_lar , => &nbspdato, => &nbspdma_reg_hit

&nbsp-- muxing data input to dma register -- data comes from the pci side or the descriptor process(reg_dat_sel, dati, dma_fifo_dato) begin case (reg_dat_sel) is when '1' => dma_reg_dati <= dma_fifo_dato; &nbsp-- descriptor fifo for chaining DMA when OTHERS => dma_reg_dati <= dati; end case; end process; -- set normal termination when lm_lastn has asserted req <= req_int; process(clk,rstn) begin if(rstn='0') then normal_termination <= '0'; elsif(clk'event and clk='1') then if(last_xfr='1') then normal_termination <= '1'; elsif(req_int='1') then normal_termination <= '0'; end if; end if; end process;

&nbsp-- set when lm_last &nbsp-- reset when request

-- assign outputs bcr <= dma_bcr; acr <= dma_acr; lar <= dma_lar;

csr <= dma_csr; isr <= dma_isr;

end rtl;

You might also like