我正在设计一个I2C总线,并且已经构建了一个模块,可以按顺序将数据加载到REG / DATA线路中。它使用0到15的计数器来执行此操作。
这在模拟中工作正常,所以我已经合成并且在经历预期的警告:常数等等时我发现计数器的MSB是恒定的(显然对于一个计数器这应该不是这样!)。但我不明白为什么这应该来自它的VHDL描述。
Xst:1293 - FF / Latch" count_internal [3] _dff_11_7"具有恒定的价值 块中的0。这个FF / Latch将在期间进行修剪 优化过程。
我也不确定" ... _ dff_11_7"后缀是计数器的整个MSB还是只是内部优化?如果它是整个MSB,考虑到我没有得到1-3位的错误,我可以假设错误来自模块外部吗?
所以问题是!导致此警告的原因是什么,我该如何修复它,还是应该忽略它?
非常感谢,
大卫
仅供参考 - 我知道I2C通常使用标准的7位地址,8位寄存器和8位数据字段 - 泛型用于我自己的实验!
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY I2C_LOAD IS
GENERIC(
LOAD_L : INTEGER RANGE 1 to 16; --Number of reg/data pairs to load
REG_L : INTEGER RANGE 0 TO 8; -- Length of a register
DATA_L : INTEGER RANGE 0 TO 8 -- Length of a data packet
);
PORT(
SYSCLK : IN STD_LOGIC; --system clock
ACK_ERR : IN STD_LOGIC; --Error from I2C master
BUSY : IN STD_LOGIC; --is I2C driver busy
RESET_N : IN STD_LOGIC; --input reset_n
ENA : OUT STD_LOGIC; --Enabled flag (i.e. job complete)
COUNT : OUT INTEGER RANGE 0 TO LOAD_L - 1; --Registers transmitted so far
BUS_REGDATA : OUT STD_LOGIC_VECTOR(REG_L - 1 DOWNTO 0);
BUS_WDATA : OUT STD_LOGIC_VECTOR(DATA_L - 1 DOWNTO 0)
);
END I2C_LOAD;
ARCHITECTURE BEHAVIOURAL OF I2C_LOAD IS
signal count_internal : integer range 0 to LOAD_L - 1 := 0; -- Sequence number to send all values
type reg_val_pair is record
reg : std_logic_vector(7 downto 0); --register value to load to i2c
val : std_logic_vector(7 downto 0); --data to load to i2c
end record;
type data is array (0 to 15) of reg_val_pair; --Array to load values from
constant data_load : data := ((x"1C", x"00"), (x"1D", x"48"), (x"1E", x"C0"), (x"20", x"00"),
(x"21", x"00"), (x"23", x"04"), (x"31", x"80"), (x"33", x"08"), (x"34", x"16"), (x"35", x"30"),
(x"36", x"60"), (x"37", x"00"), (x"48", x"18"), (x"49", x"C0"), (x"56", x"00"), (x"1F", x"80")
);
BEGIN
increment_reset : process(SYSCLK)
variable edge : boolean := true; --To detect when i2c has finished sending
begin
if rising_edge(SYSCLK) then
if BUSY = '0' and edge then --if busy has dropped, old value has sent
if count_internal < LOAD_L - 1 then
ENA <= '1'; -- keep writing
count_internal <= count_internal + 1; --increment counter to get new data
else
ENA <= '0'; --Done loading, disable module
end if;
edge := false; --no longer an edge
elsif BUSY = '1' then --I2C still xmitting
edge := true; --next time will be an edge
end if;
if RESET_N = '0' or ACK_ERR = '1' then --when reset, set counter & reg_send back to defaults
count_internal <= 0; --reset to 0
ENA <= '1'; --go back to write mode
end if;
end if;
end process;
--Load correct data onto buses to xmit via i2c
BUS_REGDATA <= data_load(count_internal).reg(REG_L - 1 downto 0) when rising_edge(SYSCLK);
BUS_WDATA <= data_load(count_internal).val(DATA_L - 1 downto 0) when rising_edge(SYSCLK);
COUNT <= count_internal; --Output counter for debugging
END BEHAVIOURAL;
修改
根据建议,我已经包含了以下模块的实例化。我删除了非相关组件和类似组件(如果错误是在其他地方引起的,则无论如何都超出了问题的范围!)
ARCHITECTURE behavior OF TBUS IS
----Constants----
constant REG_LEN : INTEGER := 8; -- Register length
constant DATA_LEN : INTEGER := 8; -- Length of data field
constant LOAD_LEN : INTEGER := 16; -- Number of registers to set
COMPONENT I2C_LOAD
GENERIC(
LOAD_L : INTEGER RANGE 1 TO 16;
REG_L : INTEGER RANGE 0 TO 8;
DATA_L : INTEGER RANGE 0 TO 8
);
PORT(
SYSCLK : IN STD_LOGIC;
ACK_ERR : IN STD_LOGIC;
BUSY : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
ENA : OUT STD_LOGIC;
COUNT : OUT INTEGER RANGE 0 TO LOAD_L - 1;
BUS_REGDATA : OUT STD_LOGIC_VECTOR(REG_L - 1 DOWNTO 0);
BUS_WDATA : OUT STD_LOGIC_VECTOR(DATA_L - 1 DOWNTO 0)
);
END COMPONENT I2C_LOAD;
----Outputs ------
signal load_count : integer range 0 to LOAD_LEN - 1;
----Clocks-----
signal sysclk : std_logic; --system clock
-----Internal Control Signals ---
signal reset_n : std_logic; --active high
signal busy : std_logic; --low when not i2c not busy
signal ack_err : std_logic; --high when i2c ackknowledge error occurs
signal i2c_enable : std_logic;
----Internal Data-----
signal i2c_reg : STD_LOGIC_VECTOR(REG_LEN - 1 DOWNTO 0); --register data for I2C
signal i2c_data : STD_LOGIC_VECTOR(DATA_LEN - 1 DOWNTO 0); --Data for I2C
BEGIN
data_load : component I2C_LOAD
generic map(
LOAD_L => LOAD_LEN,
REG_L => REG_LEN,
DATA_L => DATA_LEN
)
port map(
SYSCLK => sysclk,
ACK_ERR => ack_err,
BUSY => busy,
RESET_N => reset_n,
COUNT => load_count,
ENA => i2c_enable,
BUS_REGDATA => i2c_reg,
BUS_WDATA => i2c_data
);
----------------Mappings---------------------------
reset_n <= not BTN; --when button pressed, reset
LED <= std_logic_vector(to_unsigned(load_count, 4));
end behavior;