⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 epp_asynch.vhd

📁 MicroBlaze 外设,opb_epp利用pc并可与MicroBlaze进行通信
💻 VHD
字号:
-- Convert logic synchronous to the pp_dck to logic synchrounous to clk

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity epp_asynch is
	port (clk: in STD_LOGIC; 
	  arst: in STD_LOGIC; -- asynchronous global reset
    rnw: out std_logic; -- read not write
    adr_not_data: out std_logic; -- transfer of address or data (valid only for rnw='0')
    din: in std_logic_vector(1 downto 0); -- input data
    dout: out std_logic_vector(3 downto 0); -- output data
    stb: out std_logic; -- ready to transfer data
    ack: in std_logic; -- external device is ready to accept/send a new word
    -- external pins
    pp_dck: in std_logic; -- external PP clock
    pp_dwr: in std_logic; -- external PP data in (write)
    pp_drd: out std_logic); -- external PP data out (read)
end epp_asynch;

architecture arch of epp_asynch is
  signal dout1: std_logic_vector(3 downto 0); -- internal dout
  signal din_q: std_logic_vector(1 downto 0); -- internal din
  signal rnw1, stb1, stb_rd, adr_not_data1: std_logic; -- internal stb
  signal count: std_logic_vector(2 downto 0); -- counter
  signal valid_dout: std_logic;
  signal ack_q: std_logic; -- ack signal clocked by clk
  signal arst_valid_dout, arst_ackq_rd, arst_ackq: std_logic;
begin
process(arst, pp_dck) begin
  if arst='1' then
    adr_not_data1<= '0'; rnw1<='0';
    count<= (others=>'0');
  elsif pp_dck'event and pp_dck='1' then
    if count=0 then -- adress/data
      adr_not_data1<= pp_dwr;
    elsif count=1 then -- read not write
      rnw1<= pp_dwr;
    else
      dout1<= pp_dwr & dout1(3 downto 1);
    end if;

    if (rnw1='0' and count= 5) or (rnw1='1' and count=4) then
      count<= (others=>'0');
    else 
      count<= count + 1;
    end if;
  end if; 
end process;
dout<= dout1;

-- valid_dout
process(pp_dck, arst, arst_valid_dout) begin
  if arst='1' or arst_valid_dout='1' then
    valid_dout<= '0';
  elsif pp_dck='1' and pp_dck'event then
    if rnw1='0' and count=5 then
      valid_dout<='1';
    end if;
  end if;
end process;
arst_valid_dout<= valid_dout and ack_q;

-- read strobe and data read
process(pp_dck, arst) begin
  if arst='1' then 
    stb_rd<='0'; arst_ackq_rd<= '0';
  elsif pp_dck='1' and pp_dck'event then
    if count=1 and pp_dwr='1' then -- read data
      stb_rd<='1';
    else
      stb_rd<= '0';
    end if;
    arst_ackq_rd<= stb_rd;
  end if;
end process;

--- adres not data
process(clk, arst) begin
  if arst='1' then adr_not_data<= '1';
  elsif clk='1' and clk'event then
    if ack='0' and ack_q='0' and (valid_dout='1' or stb_rd='1') then
      adr_not_data<= adr_not_data1;
    end if;
  end if;
end process;

process(clk, arst, arst_ackq) begin
  if arst='1' or arst_ackq='1' then
    stb1<= '0'; ack_q<='0';
  elsif clk='1' and clk'event then
    -- stb
    if ack='0' and ack_q='0' and (valid_dout='1' or stb_rd='1') then
      stb1<= '1';
    else
      stb1<='0';
    end if;
    -- ack_q
    if ack='1' then
      ack_q<='1';
      din_q<= din;
    elsif stb_rd='0' then -- read process is finished
      ack_q<='0';
    end if;     
  end if;
end process;
arst_ackq<= arst_valid_dout or arst_ackq_rd;
 
pp_drd<= '0' when valid_dout='1' else -- write buffer is still not empty so wait
         '1' when rnw1= '0' else -- no wait for writes
         ack_q when count=2  else -- ready signal for reads
         din_q(0) when count=3 else -- data read 0
         din_q(1); -- data read 1 (or don't care)

stb<= stb1;
rnw<= (not valid_dout) and rnw1;

end arch;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -