次优时序实现警告 - F7 多路复用器
Suboptimal Timing Implementation Warning - F7 Multiplexer
我正在尝试创建一个 I2C 总线进行测试,作为我尝试对 DVI Ch7301c 进行编程的一部分。
我正在向它提供测试数据,但是,当我尝试传输十六进制数据值 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 语句中被抛出,但只有在发送值 value hex 77 时才会抛出。此外,我可以在 case 语句的其他地方发送 value hex 77,只是不在 when counter <= 3
这个警告是什么意思,为什么它似乎只打击明显随机的十六进制值 77。
我的代码如下 - 我没有添加 I2C_Master 模块的代码,因为它似乎不对错误负责。
非常感谢!
大卫
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;
查看 Spartan-6 CLB Guide,您会发现两个 F7 多路复用器和一个 F8 多路复用器。
您的 FPGA 的 LUT 可以实现每个布尔 6 输入函数 ("F6")。如果需要一个7输入的功能,用两个LUT6和一个F7MUX把这个功能映射到CLB中。
一个8输入函数需要四个LUT6,两个F7MUX,一个F8MUX。
时序比 LUT6 慢,但比 LUT 树快。
发出警告是为了提醒您描述输入计数较低的功能。如果您更改代码或某些常量,优化可能无法再找到紧凑的 6 输入函数。
我正在尝试创建一个 I2C 总线进行测试,作为我尝试对 DVI Ch7301c 进行编程的一部分。
我正在向它提供测试数据,但是,当我尝试传输十六进制数据值 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 语句中被抛出,但只有在发送值 value hex 77 时才会抛出。此外,我可以在 case 语句的其他地方发送 value hex 77,只是不在 when counter <= 3
这个警告是什么意思,为什么它似乎只打击明显随机的十六进制值 77。
我的代码如下 - 我没有添加 I2C_Master 模块的代码,因为它似乎不对错误负责。
非常感谢!
大卫
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;
查看 Spartan-6 CLB Guide,您会发现两个 F7 多路复用器和一个 F8 多路复用器。
您的 FPGA 的 LUT 可以实现每个布尔 6 输入函数 ("F6")。如果需要一个7输入的功能,用两个LUT6和一个F7MUX把这个功能映射到CLB中。
一个8输入函数需要四个LUT6,两个F7MUX,一个F8MUX。
时序比 LUT6 慢,但比 LUT 树快。
发出警告是为了提醒您描述输入计数较低的功能。如果您更改代码或某些常量,优化可能无法再找到紧凑的 6 输入函数。