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

📄 epp.vhd

📁 MicroBlaze 外设,opb_epp利用pc并可与MicroBlaze进行通信
💻 VHD
字号:
-- FPGA block to help in comunication between FPGA and CPLD
-- this blocks allows for Parallel Port (EPP) transfer
-- epp block is a master device
-- interface is compatible with WISHBONE (exept the rst_I signal)

-- by Erenst Jamro 
--//////////////////////////////////////////////////////////////////////
--//// Copyright (C) 2003 Authors                                   //// 
--////                                                              ////
--//// This source file may be used and distributed without         ////
--/// restriction provided that this copyright statement is not     ////
--//// removed from the file and that any derivative work contains  ////
--//// the original copyright notice and the associated disclaimer. ////
--////                                                              ////
--//// This source file is free software; you can redistribute it   ////
--//// and/or modify it under the terms of the GNU Lesser General   ////
--//// Public License as published by the Free Software Foundation; ////
--//// either version 2.1 of the License, or (at your option) any   ////
--//// later version.                                               ////
--////                                                              ////
--//// This source is distributed in the hope that it will be       ////
--//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
--//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
--//// PURPOSE. See the GNU Lesser General Public License for more  ////
--//// details.                                                     ////


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

entity epp is
	port (clk_I: in STD_LOGIC; 
	  arst: in STD_LOGIC; -- asynchronous global reset
		-- WISHBONE interface
		adr_O: buffer std_logic_vector(31 downto 0);
		we_O, cyc_O, stb_O: buffer std_logic;
		ack_I: in std_logic;
		dat_O: out std_logic_vector(7 downto 0);
		dat_I: in std_logic_vector(7 downto 0);
		cti_O: out std_logic_vector(2 downto 0); -- sequencial addressing
    buf_valid: in std_logic; -- write data in the external buffer are valid so do not change the address (only +1 is allowed)
		-- external (PIN) signals connected to CPLD and Parallel Port (FPGA is a slave device to CPLD!)
		pp_dck: in STD_LOGIC; -- Parallel Port Clock
		pp_dwr: in STD_LOGIC; -- PP data write
		pp_drd: out std_logic -- PP data read
	);
end epp;


architecture epp_arch of epp is
 component epp_asynch
	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 component;

 signal adr: std_logic_vector(31 downto 0); -- address bus
 signal dwr, drd: std_logic_vector(7 downto 0);
 signal count: std_logic_vector(1 downto 0); -- countrol counter
 signal rnw, adr_not_data, astb, aack: std_logic;

begin
-- double clock unite
asych:  epp_asynch
	port map(clk=> clk_I, arst=> arst,
    rnw=> rnw, adr_not_data=> adr_not_data,
    din=> drd(1 downto 0), dout=> dwr(7 downto 4), 
    stb=> astb, ack=> aack,
    -- external pins
    pp_dck=> pp_dck, pp_dwr=> pp_dwr, pp_drd=> pp_drd);
 -- counter
 pcount: process(arst, clk_I) begin
   if arst='1' then
     count<= (others=>'0');
   elsif clk_i'event and clk_i='1' then
     if aack='1' then
       if adr_not_data='1' or (rnw='0' and count/=0) then
         count<= (others=>'0');
       else
         count<= count + 1;
       end if;
     end if;
   end if;
 end process;
 -- strobe signal
 pstb: process(clk_I, arst) begin
  if arst='1' then stb_O<= '0';
  elsif clk_i='1' and clk_i'event then
    if rnw='1' and count=0 and ack_I='0' then -- read
      stb_O<= astb;
    elsif rnw='0' and count= 1 and ack_I='0' and adr_not_data='0' then -- write data
      stb_O<= astb;
    else
      stb_O<= '0';
    end if;
  end if;
end process;

-- read write data buffer
  dat_O<= dwr; 
  
pdata: process(clk_i, arst) begin
  if arst='1' then
    adr<= (others=>'0'); dwr(3 downto 0)<= (others=>'0'); drd(7 downto 2) <= (others=>'0');
  elsif clk_i'event and clk_i='1' then 
    -- data write
    if aack='1' then 
      dwr(3 downto 0)<= dwr(7 downto 4);
    end if;
    -- address write increase
    if aack='1' and rnw='0' and adr_not_data='1' then
      adr<= dwr(7 downto 4) & adr(31 downto 4);
    elsif ack_I='1' then
      adr<= adr + 1;
    end if;
    -- data read
    if ack_I= '1' then
      drd(7 downto 2)<= dat_I(7 downto 2);
    elsif aack='1' then
      drd(5 downto 2)<= drd(7 downto 4);
    end if;
   end if;
 end process;
   
 drd(1 downto 0)<= dat_I(1 downto 0) when count= 0 else drd(3 downto 2);
 aack<= '0' when astb='0' else
        ack_i when count=0 and rnw='1' else -- first read
        '1' when rnw='1' else -- next reads
        not buf_valid when adr_not_data='1' else -- address write and still valid data in the write buffer
        ack_i when count=1 else -- the second (last) wirte
        '1'; -- the first write or address write
 
 we_O<= not rnw;
 adr_O<= adr;
 cyc_O<= not adr_not_data;
 cti_O<= "000";
 
end epp_arch;

⌨️ 快捷键说明

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