谢谢各位的解答,现在程序还是有点不稳定!现在贴出来,希望给点建议!
程序是在altera MAX7128上运行的!!
其功能是I2C的拦截程序!!
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--use ieee.std_logic_arith.all;
entity monitor is
port( RESET :in std_logic;
CLK16x :in std_logic;
SCL :in std_logic;---I2C clock signal
SDA :in std_logic;---I2C data signal
DACK ut std_logic;---IOSELA0 monitor the data condition
STACK ut std_logic;---IOSELA1 monitor the start or stop condition
DATA ut std_logic_vector(7 downto 0));---data BUS
end monitor;
architecture rtl of monitor is
signal REG :std_logic_vector(7 downto 0);
signal SHIFT :std_logic_vector(7 downto 0);
signal COUNT :std_logic_vector(3 downto 0);
signal SDA1 :std_logic;
signal DATAOUT :std_logic_vector(7 downto 0);
signal SCL1 :std_logic;
signal startb :std_logic;
signal stopb :std_logic;
signal datab :std_logic;
signal sbit :std_logic; ---the bit of starting receive data
signal dbit :std_logic; ---the bit of stop signal
signal cnt :std_logic_vector(3 downto 0);
signal RIDE :std_logic; ---the signal of SDA rising
signal FIDE :std_logic; ---the signal of SDA falling
signal DRIDE :std_logic; ---the signal of SCL rising
signal DFIDE :std_logic; ---the signal of SCL falling
signal DISPLAY :std_logic;
signal FLAG :std_logic;
begin
process(CLK16x,RESET,COUNT)
begin
if CLK16x'event and CLK16x='1' then
if RESET='0' then
COUNT<="0001";
REG<=(others=>'0');
SHIFT<=(others=>'0');
startb<='0';
stopb<='0';
datab<='0';
sbit<='0';
dbit<='0';
STACK<='1';
DACK<='1';
DISPLAY<='0';
cnt<="0010";
FLAG<='0';
elsif SCL1='1' and FIDE='1' then --monitor start bit ( 80)
stopb<='0';
startb<='1';
DATAB<='0';
REG<="10000000";
COUNT<="0000";
STACK<='1';
DACK<='1';
sbit<='1';
dbit<='0';
DISPLAY<='1';
elsif SCL1='1' and RIDE='1' and dbit='1' then --monitor stop bit(FF)
startb<='0';
stopb<='1';
DATAB<='0';
REG<=(others=>'1');
COUNT<="0000";
STACK<='0';
DACK<='1';
sbit<='0';
dbit<='0';
DISPLAY<='1';
elsif SCL1='1' and DRIDE='1' and sbit='1' then --monitor data
COUNT<=COUNT+"0001";
startb<='0';
stopb<='0';
--STACK<='1';
DACK<='1';
dbit<='1';
DISPLAY<='0';
FLAG<='1';
else
FLAG<='0';
end if;
if COUNT<="1000" and FLAG='1' then ---COUNT<"1000" and FLAG='1'
SHIFT<=SHIFT(6 downto 0)&SDA;
DATAB<='0';--//
elsif COUNT="1000" and DFIDE='1' then
REG<=SHIFT;
DACK<='0';
DATAB<='1';
elsif COUNT="1001" and DFIDE='1' then
COUNT<=(others=>'0');
end if;
if DISPLAY='1' then
cnt<=cnt+1;
else
cnt<=(others=>'0');
end if;
if cnt="0100" then ----reversion or DFIDE='1'
STACK<='0';
elsif cnt="1111" or DFIDE='1' then
STACK<='1';
DISPLAY<='0';
end if;
-- end if;
end if;
end process;
process(CLK16x,RESET)
begin
if CLK16x'event and CLK16x='1' then
SDA1<=SDA;
SCL1<=SCL;
--if RESET='0' then
-- SDA1<='0';
-- SCL1<='0';
-- RIDE<='0';
-- FIDE<='0';
-- DRIDE<='0';
-- DFIDE<='0';
-- else
if (SDA1='1' and SDA='0') then
FIDE<='1';
RIDE<='0';
elsif (SDA1='0' and SDA='1') then
RIDE<='1';
FIDE<='0';
else
RIDE<='0';
FIDE<='0';
end if;
if SCL1='0' and SCL='1' then
DRIDE<='1';
DFIDE<='0';
elsif SCL1='1' and SCL='0' then
DRIDE<='0';
DFIDE<='1';
else
DRIDE<='0';
DFIDE<='0';
end if;
-- end if;
end if;
end process;
process(RESET,CLK16x,DATAOUT)
begin
if CLK16x'event and CLK16x='1' then
-- if RESET='0' then
-- DATAOUT<=(others=>'0');
-- DATA<=(others=>'0');
--else
if startb='1' then
DATAOUT<=REG;
elsif datab='1' then
DATAOUT<=REG;
elsif stopb='1' then
DATAOUT<=REG;
end if;
DATA<=DATAOUT;
end if;
--end if;
end process;
end rtl;