100% found this document useful (2 votes)
9K views

DMA Controller Code in VHDL

This document describes a DMA controller entity and architecture in VHDL. The entity defines the input and output ports for the DMA controller including a clock, reset, start signal, data inputs/outputs, address inputs, and control signals. The architecture defines signals, instantiates subcomponents like the DMA state machine and registers, and contains logic for the control and data flow of the DMA controller.

Uploaded by

api-3730590
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
9K views

DMA Controller Code in VHDL

This document describes a DMA controller entity and architecture in VHDL. The entity defines the input and output ports for the DMA controller including a clock, reset, start signal, data inputs/outputs, address inputs, and control signals. The architecture defines signals, instantiates subcomponents like the DMA state machine and registers, and contains logic for the control and data flow of the DMA controller.

Uploaded by

api-3730590
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 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 : in std_logic; -- clock
rstn : in std_logic; -- reset
start : in std_logic; -- trigger state machine
dati : in std_logic_vector(31 downto 0); -- data input
adr : in std_logic_vector(7 downto 0); &nbsp-- address of the dma
register
reg_wen : in std_logic; -- dma register write enable
fifo_wen : in std_logic; -- dma fifo write enable
wr_rdn : in std_logic; -- write/read signal to dma registers
cs : in std_logic; -- chip select (dma_register)
bcr_cnten : in std_logic; -- byte counter count enable
acr_cnten : in std_logic; -- address counter count enable
lar_cnten : in std_logic; -- local address counter count
enable
p2s_fifo_empty : in std_logic; -- high and low p2s both empty
s2p_fifo_usedw : in std_logic_vector(6 downto 0);
mstr_busy : in std_logic;
stop : in std_logic; -- PCI core signals stop current dma
abort : in std_logic; -- PCI core signals abort current dma
last_xfr : in std_logic; -- PCI core signals last transfer
local_busy : in std_logic; -- sdram is busy
err_pend : in std_logic; -- target abort, parity error, master
abort
lm_tsr : in std_logic_vector(9 downto 0); &nbsp-- master status
std_logics
isr_rd : in std_logic; -- isr read signal

isr : out std_logic_vector(5 downto 0);


csr : out std_logic_vector(8 downto 0);
bcr : out std_logic_vector(16 downto 0);
acr : 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 normal_termination : std_logic;


signal start_chain : std_logic;
signal chain_end : std_logic;
signal dma_bcr : std_logic_vector(16 downto 0);
signal dma_csr : std_logic_vector(8 downto 0);
signal dma_done : std_logic;
signal dma_error : std_logic;
signal chain_acr_ld : std_logic;
signal chain_bcr_ld : std_logic;
signal dma_fifo_rd : std_logic;
signal trans64 : std_logic;
signal isr_in : std_logic_vector(5 downto 0);
signal dma_on : std_logic;
signal dma_acr : std_logic_vector(31 downto 0);
signal dma_isr : std_logic_vector(5 downto 0);
signal dma_lar : std_logic_vector(25 downto 0);
signal dma_fifo_dato : std_logic_vector(31 downto 0);
signal soft_flush : std_logic;
signal dma_reg_dati : std_logic_vector(31 downto 0);
signal reg_dat_sel : std_logic;
signal direction : std_logic;
signal acr_wr : std_logic;
signal csr_wr : std_logic;
signal csr_wr_reg : std_logic;
signal int_irq : std_logic;
signal local_irq : std_logic;
signal rst : std_logic;
signal req_int : std_logic;
signal high : std_logic;
signal dma_reg_hit : std_logic_vector(4 downto 0);
begin
&nbsphigh <= '1';
&nbsprst <= not rstn;
&nbspsoft_flush <= dma_csr(1); &nbsp-- flush std_logic of the control status
register
&nbspstart_chain <= dma_isr(5); &nbsp-- DMA chaining mode enable
&nbspdirection <= dma_csr(3); &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 , -- mux output select between
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 ,
cs => &nbspcs,
acr => &nbspdma_acr ,
bcr => &nbspdma_bcr ,
csr => &nbspdma_csr ,
isr => &nbspdma_isr ,
lar => &nbspdma_lar ,
dato => &nbspdato,
dma_reg_hit => &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'; &nbsp-- set when lm_last
elsif(req_int='1') then
normal_termination <= '0'; &nbsp-- reset when request
end if;
end if;
end process;

-- assign outputs

bcr <= dma_bcr;


acr <= dma_acr;
lar <= dma_lar;
csr <= dma_csr;
isr <= dma_isr;

end rtl;

You might also like