📄 i2c_7189.vhd
字号:
-- version 1.1
-- bug fixed: the last data cannot be send
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.i2c.all;
entity i2c_7189 is
port (
clk : in std_logic;
nReset : in std_logic;
SCL : out std_logic;
SDA : out std_logic;
done : out std_logic);
end entity;
architecture rtl of i2c_7189 is
constant SLAVE_ADDR : std_logic_vector(6 downto 0) := "0100000";
constant CLK_CNT : unsigned(7 downto 0) := conv_unsigned(100, 8); --Fc(MHz)*2-1
constant delay_time : integer range 0 to 1000000000 :=10000;
type c_state is (IDLE,INIT,START,SEND_ADR,SEND_DATA,ENDS);
signal state : c_state;
signal s_delay_cnt : integer range 0 to 1000000000;
signal s_delay : std_logic;
signal cmd_ack : std_logic;
signal s_lack : std_logic;
signal s_start, s_read, s_write, s_ack, s_stop : std_logic;
signal s_data_r : std_logic_vector(7 downto 0);
signal s_data_w : std_logic_vector(7 downto 0);
signal s_addr : std_logic_vector(5 downto 0);
signal s_q : std_logic_vector(7 downto 0);
signal s_rom_q : std_logic_vector(7 downto 0);
-- signal nReset : std_logic;
signal s_get : std_logic;
signal s_SDA : std_logic;
signal s_SCL : std_logic;
signal s_ctrl_scl : std_logic;
component rom7189 IS
PORT
(
address : IN STD_LOGIC_VECTOR (5 DOWNTO 0);
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END component;
begin
u1: simple_i2c
port map (clk => clk, ena => '1', clk_cnt => clk_cnt, nReset => nReset,
read => s_read, write => s_write, start => s_start, stop => s_stop, ack_in => s_ack,
cmd_ack => cmd_ack, Din => s_data_w, Dout => s_data_r, ack_out => s_lack,SCL => s_SCL, SDA => s_SDA);
u2: rom7189
port map (clock => clk, address => s_addr, q => s_q);
-- nReset <= Reset;
SDA <= s_SDA when s_ctrl_scl = '0' else '1';
SCL <= s_SCL when s_ctrl_scl = '0' else '1';
process (clk,nReset,state)
begin
if nReset = '0' then
s_ctrl_scl <= '0';
state <= IDLE;
s_start <= '0';
s_read <= '0';
s_write <='0';
s_ack <= '0';
s_stop <= '0';
s_get <= '1';
s_addr <= (others => '0');
done <= '0';
else
if clk'event and clk = '1' then
if s_get = '1' then
s_rom_q <= s_q;
s_addr <= s_addr + 1;
end if;
s_get <= '0';
case state is
when IDLE =>
if s_delay = '1' then
state <= INIT;
end if;
when INIT =>
state <= SEND_ADR;
s_start <= '1';
s_read <= '0';
s_write <= '1';
s_ack <= '0';
s_stop <= '0';
s_Data_w <= (slave_addr & '0'); -- write to slave (R/W = '0')
when START =>
if cmd_ack = '1' then
if s_rom_q = "10101010" then
s_ctrl_scl <= '1';
done <= '1';
state <= ENDS;
else
state <= SEND_ADR;
s_start <= '1';
s_read <= '0';
s_write <= '1';
s_ack <= '0';
s_stop <= '0';
s_Data_w <= (slave_addr & '0'); -- write to slave (R/W = '0')
end if;
end if;
when SEND_ADR =>
if cmd_ack = '1' then
-- if s_lack = '1' then
-- state <= ENDS;
-- else
s_start <= '0';
s_read <= '0';
s_write <= '1';
s_ack <= '0';
s_stop <= '0';
s_data_w <= s_rom_q;
s_get <= '1';
state <= SEND_DATA;
-- end if;
end if;
when SEND_DATA =>
if cmd_ack = '1' then
-- if s_lack = '1' then
-- state <= ENDS;
-- else
s_start <= '0';
s_read <= '0';
s_write <= '1';
s_ack <= '0';
s_stop <= '1';
s_data_w <= s_rom_q;
s_get <= '1';
state <= START;
-- end if;
end if;
when others =>
s_start <= '0';
s_read <= '0';
s_write <= '0';
s_ack <= '0';
s_stop <= '0';
end case;
end if;
end if;
end process;
-- process (clk)
-- variable rt : integer range 0 to 2000000 := 0;
-- begin
-- if clk = '1' and clk'event then
-- if rt < 1800000 then
-- rt := rt + 1;
-- nReset <= '0';
-- else
-- nReset <='1';
-- end if;
-- end if;
-- end process;
process (clk,nReset)
begin
if nReset = '0' then
s_delay <= '0';
s_delay_cnt <= 0;
else
if clk'event and clk = '1' then
if s_delay_cnt /= delay_time then
s_delay_cnt <= s_delay_cnt + 1;
s_delay <= '0';
else
s_delay_cnt <= s_delay_cnt;
s_delay <= '1';
end if;
end if;
end if;
end process;
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -