我試圖創建一個I2C總線進行測試,作爲我嘗試編程DVI Ch7301c的一部分。不理想的時序執行警告 - F7多路複用器
我用測試數據提供它,但是,當我嘗試和發送的數據值十六進制77,它拋出這樣的警告:
Pack:2574 - The F7 multiplexer symbol
"I2C_Master/Mmux_bit_cnt[2]_DAT_WR[7]_Mux_45_o_2_f7" and its I1 input driver
"I2C_Master/Mmux_bit_cnt[2]_DAT_WR[7]_Mux_45_o_3" were implemented
suboptimally in the same slice component. The function generator could not be
placed directly driving the F7 multiplexer. The design will exhibit
suboptimal timing.
縮小下來之後,似乎在被拋出case語句,但只有當發送價值十六進制值77.此外,我可以在case語句中的其他地方發送值爲十六進制77,而不是在when counter <= 3
這個警告表示爲什麼它似乎只罷工顯然是隨機的值爲十六進制77.
我的代碼如下 - 我沒有添加I2C_Master模塊的代碼,因爲它d似乎沒有爲這個錯誤負責。
非常感謝!
大衛
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity I2CBus is
PORT(
SYSCLK_N : IN STD_LOGIC; --system 200MHz differential clock
SYSCLK_P : IN STD_LOGIC;
BTN : IN STD_LOGIC; -- to manually change reset
SCL : INOUT STD_LOGIC; --SCL & SDA lines
SDA : INOUT STD_LOGIC;
SCL_cpy : OUT STD_LOGIC; --SCL & SDA lines
SDA_cpy : OUT STD_LOGIC
);
end I2CBus;
architecture Behavioral of I2CBus is
component IIC_Master is
Generic(input_clock : integer; --system clock
bus_clock : integer);
Port(CLOCK : in STD_LOGIC;
RESET_N : in STD_LOGIC; --Active low
ENA : in STD_LOGIC; --Enable active high
ADR : in STD_LOGIC_VECTOR(6 downto 0); --target address
RW : in STD_LOGIC; --read low, write high
REG : in STD_LOGIC_VECTOR(7 downto 0); --target register
DAT_WR : in STD_LOGIC_VECTOR(7 downto 0); --data to write to slave
DAT_RD : out STD_LOGIC_VECTOR(7 downto 0); --data to read from slave
BUSY : out STD_LOGIC; --high when busy
SCL : inout STD_LOGIC; --serial clock of i2C bus
SDA : inout STD_LOGIC; --serial data on bus
ACK_ERR : buffer STD_LOGIC); --flag if wrong ack from slave
end component;
component DCM
port(
SYSCLK_P : in std_logic; -- Clock in ports 200MHz differential
SYSCLK_N : in std_logic;
-- Clock out ports
SYSCLK : out std_logic --300 MHz clock out
);
end component;
-----Clock signals -------------
signal sysclk : std_logic; --300 mhz system clock
----Internal Signals------------
signal ack_err : std_logic; --error from dvi slave
signal busy : std_logic; --is I2C master busy?
signal slave_dout : std_logic_vector(7 downto 0); --data out from slave
signal reset_n : std_logic; --reset low
signal i2c_wr : STD_LOGIC; --R/W value to send
signal i2c_wdata : STD_LOGIC_VECTOR(7 downto 0); --data to send
signal i2c_regdata : STD_LOGIC_VECTOR(7 downto 0); --target register
begin
--------Instantiate DCM------------------
DCM_Clks : DCM
port map( -- Clock in ports
SYSCLK_P => SYSCLK_P, --Map input clocks directly
SYSCLK_N => SYSCLK_N,
-- Clock out ports
SYSCLK => SYSCLK);
------------------------------------------
---Instantiate I2C Bus Driver-------------
I2C_Master : IIC_Master
Generic map(input_clock => 300000000, --system clock
bus_clock => 300000000/16)
Port map(CLOCK => sysclk, --300 MHz system clock (runs at 1/8th that)
RESET_N => RESET_N, --get reset from dvi initialiser
ENA => '1', --enable signal from above
ADR => "1010110", --target DVI address straight from input
RW => i2c_wr, --get R/W from initialiser
DAT_WR => i2c_wdata, --data to write from initialiser
REG => i2c_regdata, -- target register
DAT_RD => open, --data read from DVI device (inactive at present)
BUSY => busy, --I2C finished writing
SCL => SCL, -- output straight to SCL
SDA => SDA, -- output straight to SDA
ACK_ERR => ack_err); --flag if wrong ack from slave
--------------------------------------------
reset_proc : process(sysclk)
variable counter : integer range 0 to 4;
variable edge : boolean; --used to detect busy falling edge
begin
if rising_edge(sysclk) then
if busy = '1' then
edge := true; --next '0' will be an edge
end if;
if busy = '0' and edge and counter < 3 then
counter := counter + 1; --increment counter
edge := false; --reset edge
end if;
case counter is
when 0 =>
i2c_wr <= '0'; --set to write
i2c_regdata <= x"AA"; --send new target register
i2c_wdata <= x"99"; --send new write data
when 1 =>
i2c_regdata <= x"FF";
i2c_wdata <= x"55";
when 2 =>
i2c_regdata <= x"BB";
i2c_wdata <= x"77"; --WARNING occurs here when sending x"77"
when others => null;
end case;
end if;
end process;
reset_n <= not BTN; --reset process;
SDA_cpy <= SDA; --copy SDA & SCL to observable pins
SCL_cpy <= SCL;
end Behavioral;