Professional Documents
Culture Documents
DMA Controller Code in VHDL
DMA Controller Code in VHDL
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);  -- 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);  -- 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);  -- 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  high <= '1';  rst <= not rstn;  soft_flush <= dma_csr(1); register  start_chain <= dma_isr(5);  direction <= dma_csr(3);
 -- flush std_logic of the control status  -- DMA chaining mode enable  -- 1 for write, 0 for read
-- interrupt pending std_logic  isr_in(0) <= err_pend or int_irq or (dma_isr(3) and not dma_csr(5));  int_irq <= local_irq; -- assert local irq when there is error pending or DMA has completed  local_irq <= dma_isr(1) or (dma_isr(3) and not dma_csr(5));  isr_in(1) <= err_pend;  isr_in(2) <= int_irq;
-- generate transfer complete status std_logic 3  process(dma_done, isr_rd, csr_wr, acr_wr, dma_isr) -- dma_tc begin  if(dma_done = '1') then isr_in(3) <= '1';  elsif(isr_rd = '1' or csr_wr = '1' or acr_wr = '1') then isr_in(3) <= '0';  else isr_in(3) <= dma_isr(3);  end if; end process; -- write signal to the address counter  acr_wr <= dma_reg_hit(1) and cs and reg_wen; -- generate ad_loaded singal for the isr std_logic 4  process(acr_wr, dma_isr, soft_flush, dma_done, dma_error) begin  if(acr_wr = '1') then isr_in(4) <= '1';  elsif(dma_isr(3) = '1' or soft_flush = '1' or dma_done = '1' or dma_error = '1') then
isr_in(4) <= '0';  else isr_in(4) <= dma_isr(4);  end if; end process; -- control status register write signal  csr_wr <= dma_reg_hit(0) and cs and reg_wen;  process(clk,rstn)  -- register csr_wr begin  if(rstn='0') then csr_wr_reg <= '0';  elsif(clk'event and clk = '1') then csr_wr_reg <= csr_wr;  end if; end process; -- generate start_chain std_logic  process(csr_wr_reg, dma_isr, dma_csr, soft_flush, dma_done, dma_error) begin  if (csr_wr_reg = '1' and dma_csr(8) = '1') then  -- start chain isr_in(5) <= '1';  elsif (dma_isr(3) = '1' or soft_flush = '1' or dma_done = '1' or dma_error ='1') then isr_in(5) <= '0';  else isr_in(5) <= dma_isr(5);  end if; end process;
-- generate dma_on std_logic csr(6)  dma_on <= (dma_isr(4) and dma_csr(4) and not err_pend) or (isr_in(5) and dma_csr(4) and  not err_pend);
clk =>  clk, rstn =>  rstn, normal_termination =>  normal_termination, stop =>  stop, lm_tsr =>  lm_tsr, err_pend =>  err_pend, start =>  start , start_chain =>  start_chain, chain_end =>  chain_end, p2s_fifo_empty =>  p2s_fifo_empty, s2p_fifo_usedw =>  s2p_fifo_usedw, direction =>  direction, dma_bcr =>  dma_bcr, local_busy =>  local_busy, req =>  req_int, dma_done =>  dma_done, dma_error =>  dma_error, chain_acr_ld =>  chain_acr_ld, chain_bcr_ld =>  chain_bcr_ld, dma_fifo_rd =>  dma_fifo_rd, local_start =>  local_start, chain_dma_loading =>  reg_dat_sel );
-- DMA registers instantiation  dma_reg0 : dma_reg  port map ( clk =>  clk , rstn =>  rstn , adr =>  adr , dati =>  dma_reg_dati dati and dma_fifo_dato wen =>  reg_wen , acr_ld =>  chain_acr_ld bcr_ld =>  chain_bcr_ld acr_cnten =>  acr_cnten, lar_cnten =>  lar_cnten, bcr_cnten =>  bcr_cnten, isr_in =>  isr_in , dma_on =>  dma_on ,
, ,
=>  cs, =>  dma_acr , =>  dma_bcr , =>  dma_csr , =>  dma_isr , =>  dma_lar , =>  dato, =>  dma_reg_hit
 -- 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;  -- 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;
-- assign outputs bcr <= dma_bcr; acr <= dma_acr; lar <= dma_lar;
end rtl;