Xilinx ISE VHDL计数器(XST:1293)中FF/锁存器的微调
我正在设计一个I2C总线,并构建了一个模块,用于按顺序将数据加载到REG/数据线中。它使用0到15之间的计数器来执行此操作 这在模拟中工作得很好,所以我已经合成了,在查看预期的警告:constant等时,我发现计数器的MSB是常量(显然,对于计数器来说,这不应该是常量!)。但我不明白为什么这应该是从它的VHDL描述 1293-FF/Latch“count_internal[3]_dff_11_7”具有一个常量值 块中0的值。此FF/闩锁将在安装过程中进行修剪 优化过程 我也不确定“…..dff_11_7”后缀是计数器的整个MSB还是仅仅是内部优化?如果是整个MSB,考虑到我没有得到位1-3的错误,我可以假设错误来自模块外部吗 所以问题是!导致此警告的原因是什么?我如何修复它,还是应该忽略它 非常感谢 大卫 仅供参考-我知道I2C通常使用标准的7位地址、8位reg和8位数据字段-泛型用于我自己的实验Xilinx ISE VHDL计数器(XST:1293)中FF/锁存器的微调,vhdl,constants,counter,xilinx-ise,Vhdl,Constants,Counter,Xilinx Ise,我正在设计一个I2C总线,并构建了一个模块,用于按顺序将数据加载到REG/数据线中。它使用0到15之间的计数器来执行此操作 这在模拟中工作得很好,所以我已经合成了,在查看预期的警告:constant等时,我发现计数器的MSB是常量(显然,对于计数器来说,这不应该是常量!)。但我不明白为什么这应该是从它的VHDL描述 1293-FF/Latch“count_internal[3]_dff_11_7”具有一个常量值 块中0的值。此FF/闩锁将在安装过程中进行修剪 优化过程 我也不确定“…..dff_
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;
ieee库;
使用ieee.std_logic_1164.ALL;
使用ieee.numeric_std.ALL;
实体I2C_负载为
一般的(
LOAD_L:整数范围1到16;--要加载的注册表/数据对数
REG_L:整数范围0到8;--寄存器的长度
DATA_L:整数范围0到8——数据包的长度
);
港口(
SYSCLK:标准逻辑中;--系统时钟
确认错误:在标准逻辑中;--来自I2C主机的错误
忙:在STD_逻辑中;--I2C驱动程序忙吗
复位:在标准逻辑中;--输入复位
ENA:OUT STD_LOGIC;--启用标志(即作业完成)
COUNT:输出整数范围0以加载\u L-1;--到目前为止传输的寄存器
总线REGDATA:OUT标准逻辑向量(REG-1向下至0);
总线数据:输出标准逻辑向量(数据-1向下至0)
);
端I2C_负载;
I2C_负载的架构行为是
信号计数\u内部:从0到加载的整数范围\u L-1:=0;--发送所有值的序列号
类型reg_val_对为记录
reg:std_逻辑_向量(7到0)--要加载到i2c的寄存器值
val:std_逻辑_向量(7到0)--要加载到i2c的数据
结束记录;
类型数据是reg_val_对的数组(0到15)--要从中加载值的数组
恒定数据负荷:数据:=((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”)
);
开始
增量_重置:进程(SYSCLK)
可变边:布尔值:=true--检测i2c何时完成发送
开始
如果上升沿(SYSCLK),则
if BUSY='0'和edge然后--若BUSY已删除,则旧值已发送
如果内部计数i2c_启用,
总线注册数据=>i2c注册,
总线数据=>i2c数据
);
----------------映射---------------------------
重置\n我们需要查看此实体的实例化,特别是通用负载的实际值。如果为8或更小,则计数\u internal的第3位将始终为“0”,如消息所示。是否为信号计数\u internal分配值0
是冗余的,因为它的默认值将是0
如果一个变量没有给出显式值,它的默认值将是它声明类型中最左边的值('left')。@BrianDrummond我已经添加了实例化,但它的值肯定是16,它给出了从15到0
的向量。我们需要看一下这个实体的实例化,特别是通用负载的实际值。如果为8或更小,则count\U internal的第3位将始终为“0”,如消息所示。是否会出现这样的情况,即为信号count\U internal
分配值0
是冗余的,因为其默认值将为0
如果一个变量没有给出显式值,它的默认值将是其声明类型中最左边的值('left')。@BrianDrummond我已经添加了实例化,但它的值肯定是16,它给出了从15到0的向量
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;