在Xilinx ISE的VHDL计数器(XST:1293)中修整FF / Latch

时间:2017-03-06 17:35:16

标签: vhdl constants counter 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;

0 个答案:

没有答案