Vhdl 次优定时实施警告-F7多路复用器

Vhdl 次优定时实施警告-F7多路复用器,vhdl,timing,xilinx,synthesis,spartan,Vhdl,Timing,Xilinx,Synthesis,Spartan,我试图创建一个I2C总线进行测试,作为我尝试编程DVI Ch7301c的一部分 我正在向它提供测试数据,但是,当我尝试传输数据值hex 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_

我试图创建一个I2C总线进行测试,作为我尝试编程DVI Ch7301c的一部分

我正在向它提供测试数据,但是,当我尝试传输数据值hex 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语句中抛出,但只有在发送值hex 77时才会抛出。此外,我可以将值hex 77发送到case语句中的其他位置,而不是直接在
when counter SYSCLK_P,--Map输入时钟中
SYSCLK_N=>SYSCLK_N,
--时钟输出端口
SYSCLK=>SYSCLK);
------------------------------------------
---实例化I2C总线驱动程序-------------
I2C_主机:IIC_主机
通用映射(输入时钟=>300000000,--系统时钟
总线(时钟=>300000000/16)
端口映射(时钟=>sysclk,--300 MHz系统时钟(以1/8的速率运行)
重置\u N=>重置\u N,--从dvi初始化器获取重置
ENA=>‘1’,--来自上方的启用信号
ADR=>“1010110”-直接从输入的目标DVI地址
RW=>i2c_-wr,--从初始化器获取R/W
DAT_WR=>i2c_wdata,--从初始化器写入的数据
REG=>i2c_regdata,--目标寄存器
DAT_RD=>打开,--从DVI设备读取的数据(目前处于非活动状态)
忙=>忙,--I2C已完成写入
SCL=>SCL,--直接输出到SCL
SDA=>SDA,--直接输出到SDA
确认错误=>确认错误)--如果从机确认错误,则标记
--------------------------------------------
重置进程:进程(sysclk)
变量计数器:0到4的整数范围;
可变边:布尔--用于检测忙下降沿
开始
如果上升沿(sysclk),则
如果忙='1',则
边:=真--下一个“0”将是边
如果结束;
如果忙='0'且边缘和计数器<3,则
计数器:=计数器+1--增量计数器
边:=假--重置边缘
如果结束;
柜位是
当0=>
i2c_-wr查看一下,您会发现两个F7多路复用器和一个F8多路复用器

FPGA的LUT可以实现每个布尔6输入函数(“F6”)。如果需要7输入函数,则使用两个LUT6和一个F7MUX将此函数映射到CLB

8输入函数需要四个LUT6、两个F7MUX和一个F8MUX

计时比LUT6慢,但比LUT树快

发出警告是为了提醒您描述输入计数较低的功能。如果您更改了代码或某些常量,优化可能再也找不到compact 6输入函数了

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;