2015-11-30 72 views
1

我試圖創建一個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; 

回答

2

看一看到Spartan-6 CLB Guide,你會發現兩個F7複用器和F8 MUX。

您的FPGA的LUT可以實現每個布爾6輸入函數(「F6」)。如果需要7輸入功能,則使用兩個LUT6和一個F7MUX將該功能映射到CLB。

8輸入功能需要4個LUT6兩個F7MUX和一個F8MUX。

時序比LUT6慢,但比LUT樹快。

發出此警告是爲了提醒您使用低輸入計數來描述功能。如果你改變你的代碼或者一些常量,優化可能再也找不到緊湊的6輸入函數了。