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