atahost_dma_actrl.vhd
来自「ATA接口的IP核,经过量产的验证,已经在quartus5.1下编译通过了.」· VHDL 代码 · 共 478 行 · 第 1/2 页
VHD
478 行
end if;
end process gen_Tfw;
-- transmit data part
gen_writed_pipe:process(clk)
begin
if (clk'event and clk = '1') then
if (TxRd = '1') then -- reload registers
if (BeLeC = '1') then -- Do big<->little endian conversion
writeDfw(15 downto 8) <= TxbufQ( 7 downto 0); -- TxbufQ = data from transmit buffer
writeDfw( 7 downto 0) <= TxbufQ(15 downto 8);
writeDlw(15 downto 8) <= TxbufQ(23 downto 16);
writeDlw( 7 downto 0) <= TxbufQ(31 downto 24);
else -- don't do big<->little endian conversion
writeDfw <= TxbufQ(31 downto 16);
writeDlw <= TxbufQ(15 downto 0);
end if;
elsif (wr_dstrb = '1') then -- next word to transfer
writeDfw <= writeDlw;
end if;
end if;
end process gen_writed_pipe;
DDo <= writeDfw; -- assign DMA data out
-- generate transmit register read request
gen_Tx_rreq: process(clk, nReset)
begin
if (nReset = '0') then
TxRd <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
TxRd <= '0';
else
TxRd <= go and DMActrl_dir;
end if;
end if;
end process gen_Tx_rreq;
-- receive
gen_readd_pipe:process(clk)
begin
if (clk'event and clk = '1') then
if (rd_dstrb = '1') then
readDfw <= readDlw; -- shift previous read word to msb
if (BeLeC = '1') then -- swap bytes
readDlw(15 downto 8) <= DDi( 7 downto 0);
readDlw( 7 downto 0) <= DDi(15 downto 8);
else -- don't swap bytes
readDlw <= DDi;
end if;
end if;
end if;
end process gen_readd_pipe;
-- RxD = data to receive buffer
RxbufD <= (readDfw & readDlw) when (BeLeC = '0') else (readDlw & readDfw);
-- generate receive register write request
gen_Rx_wreq: process(clk, nReset)
begin
if (nReset = '0') then
RxWr <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
RxWr <= '0';
else
RxWr <= not Tfw and rd_dstrb;
end if;
end if;
end process gen_Rx_wreq;
end block gen_DMA_sigs;
--
-- Hookup DMA read / write buffers
--
gen_DMAbuf: block
signal DMArst : std_logic;
signal RxRd, TxWr : std_logic;
signal iRxEmpty : std_logic;
begin
-- generate DMA reset signal
DMArst <= rst or IDEctrl_rst;
Txbuf: atahost_reg_buf
generic map (WIDTH => 32)
port map (
clk => clk,
nReset => nReset,
rst => DMArst,
D => TxD,
Q => TxbufQ,
rd => TxRd,
wr => TxWr,
valid => TxFull
);
Rxbuf: atahost_fifo
generic map (DEPTH => 7, SIZE => 32)
port map (
clk => clk,
nReset => nReset,
rst => DMArst,
D => RxbufD,
Q => RxQ,
rreq => RxRd,
wreq => RxWr,
empty => iRxEmpty,
full => RxFull
);
RxEmpty <= iRxEmpty; -- avoid 'cannot associate OUT port with BUFFER port' error
--
-- generate DMA buffer access signals
--
RxRd <= sel and not we and not RxEmpty;
TxWr <= sel and we and not TxFull;
ack <= RxRd or TxWr; -- DMA buffer access acknowledge
end block gen_DMAbuf;
--
-- generate request signal for external DMA engine
--
gen_DMA_req: block
signal hgo : std_logic;
signal iDMA_req : std_logic;
signal request : std_logic;
begin
-- generate hold-go
gen_hgo : process(clk, nReset)
begin
if (nReset = '0') then
hgo <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
hgo <= '0';
else
hgo <= go or (hgo and not (wr_dstrb and not Tfw) and DMActrl_dir);
end if;
end if;
end process gen_hgo;
request <= (DMActrl_dir and DMARQ and not TxFull and not hgo) or not RxEmpty;
process(clk, nReset)
begin
if (nReset = '0') then
iDMA_req <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
iDMA_req <= '0';
else
iDMA_req <= DMActrl_DMAen and not DMA_ack and (request or iDMA_req);
-- DMA_req <= (DMActrl_DMAen and DMActrl_dir and DMARQ and not TxFull and not hgo) or not RxEmpty;
end if;
end if;
end process;
DMA_req <= iDMA_req;
end block gen_DMA_req;
--
-- DMA timing controller
--
DMA_timing_ctrl: block
signal Tm, Td, Teoc, Tdmack_ext : unsigned(TWIDTH -1 downto 0);
signal dTfw, igo : std_logic;
begin
--
-- generate internal GO signal
--
gen_igo : process(clk, nReset)
begin
if (nReset = '0') then
igo <= '0';
dTfw <= '0';
elsif (clk'event and clk = '1') then
if (rst = '1') then
igo <= '0';
dTfw <= '0';
else
igo <= go or (not Tfw and dTfw);
dTfw <= Tfw;
end if;
end if;
end process gen_igo;
--
-- select timing settings for the addressed device
--
sel_dev_t: process(clk)
begin
if (clk'event and clk = '1') then
if (SelDev = '1') then -- device1 selected
Tm <= dev1_Tm;
Td <= dev1_Td;
Teoc <= dev1_Teoc;
else -- device0 selected
Tm <= dev0_Tm;
Td <= dev0_Td;
Teoc <= dev0_Teoc;
end if;
end if;
end process sel_dev_t;
--
-- hookup timing controller
--
DMA_timing_ctrl: atahost_dma_tctrl
generic map (
TWIDTH => TWIDTH,
DMA_mode0_Tm => DMA_mode0_Tm,
DMA_mode0_Td => DMA_mode0_Td,
DMA_mode0_Teoc => DMA_mode0_Teoc
)
port map (
clk => clk,
nReset => nReset,
rst => rst,
Tm => Tm,
Td => Td,
Teoc => Teoc,
go => igo,
we => DMActrl_dir,
done => Tdone,
dstrb => dstrb,
DIOR => dior,
DIOW => diow
);
done <= Tdone and not Tfw; -- done transfering last word
rd_dstrb <= dstrb and not DMActrl_dir; -- read data strobe
wr_dstrb <= dstrb and DMActrl_dir; -- write data strobe
end block DMA_timing_ctrl;
end architecture structural;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?