我在Vivado中遇到了一个奇怪的问题。目标是使用 VHDL 中的 Xilinx Artix-100T FPGA 为 adc 初始化 spi。但是,Vivado 2021.1 中的行为仿真和综合后功能仿真之间存在不匹配情况。
在行为模拟中,信号reset_n在一个时钟周期内为0,然后上升为1(理应如此)。但是,在综合后的功能仿真中,它总是0。请问有什么解释吗?我还尝试了 KEEP、DONT_TOUCH 等综合属性,但没有成功。
我将整个逻辑简化为几行代码以显示发生这种情况的部分。
主文件:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity Main is
port(
clock : IN STD_LOGIC; --system clock;
res : out std_logic := '0';
reset_done : out std_logic := '0');
signal init_done :boolean := false;
-- signal res : std_logic := '0';
end Main;
architecture Behavioral of Main is
begin
test: process is
begin
if (reset_done = '0') then
res <= '0';
wait until rising_edge(clock);
res <= '1';
reset_done <= '1';
else
wait until rising_edge(clock);
end if;
end process test;
end Behavioral;
测试台文件:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Main_tb is
end Main_tb;
architecture Behavioral of Main_tb is
component Main is
port(
clock : IN STD_LOGIC;
res : out std_logic := '0';
reset_done : out std_logic := '0');
end component;
--signals
signal clock : std_logic := '1';
signal res :std_logic := '0';
signal reset_done : std_logic := '0';
begin
simulation: Main
port map (clock, res, reset_done);
--100 MHz clock
clk_stimulus: process
begin
wait for 5 ns;
clock <= not clock;
end process clk_stimulus;
end Behavioral;
新工作代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity Main is
port(
clock : IN STD_LOGIC; --system clock;
res : out std_logic := '0'; --init signal
reset_done : out std_logic := '0'); --init signal
end Main;
architecture Behavioral of Main is
begin
test: process(clock) is
begin
if (rising_edge(clock)) then -- preferred syntax
res <= '1';
reset_done <= '1';
end if;
end process test;
end Behavioral;
不匹配意味着合成器无法从您的 VHDL 描述中推断出正确的逻辑:合成器无法理解整个 VHDL。您必须以特定方式对其进行编程,如 HDL 编码指南中所述。
这就是我们进行综合后仿真的全部原因:验证合成器是否理解我们的代码。
由于信号初始化,好的设计中很少需要上电复位。
无论如何,如果你将代码剥离到核心,它会说:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Main is
port(
clock : in std_logic;
res : out std_logic;
reset_done : out std_logic);
end Main;
architecture Behavioral of Main is
signal i_res : std_logic := '0'; -- initialize
signal i_reset_done : std_logic := '0';
begin
test: process(clk) is
begin
if (rising_edge(clk)) then -- preferred syntax
i_res <= i_reset_done;
i_reset_done <= '1'; -- set once.
end if;
end process test;
res <= i_res;
reset_done <= i_reset_done;
end Behavioral;
我不明白为什么
reset_done
必须在res
之前一个时钟断言,但无论如何。
你也可以推断一个移位寄存器来实现多时钟周期复位。
@Sebastian90 你解决错配问题了吗?