📄 epp.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 + -