Подравнивание FF/Latch в счетчике VHDL (XST: 1293) для Xilinx ISE
Я проектирую шину 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;