Vivado中基于LUT6的环形振荡器时序仿真输出X报错求助
环形振荡器Vivado时序仿真输出X的问题解决
问题背景
在Xilinx Vivado中使用LUT6原语实现环形振荡器,行为仿真运行正常(可观察到信号每5ns切换一次),但开展功耗仿真所需的时序仿真(综合后、实现后)均输出X。尝试Stack Overflow上的环形振荡器代码,也出现行为仿真正常、时序仿真失败的问题。已配置允许环形振荡器的约束文件,且Vivado目标语言设为Verilog(因时序仿真仅支持该语言)。
核心问题分析
- 环形振荡器逻辑错误:原代码中
size=2,使用偶数个反相器(LUT配置为反相器逻辑),偶数个反相器串联会形成同相反馈,无法产生振荡——仅行为仿真中因人为添加的after 1 ns延迟强制触发了信号变化,实际硬件和时序仿真中无法正常工作。 - 时序仿真初始状态缺失:时序仿真依赖器件精确时序模型,组合环路无明确初始状态时,仿真器会将信号判定为未知状态(X)。
- 行为仿真延迟不被时序仿真识别:代码中的
after 1 ns仅在行为仿真中生效,时序仿真会忽略该人为延迟,导致环路无触发条件。
解决方案步骤
1. 修正环形振荡器逻辑(奇数个反相器)
将size改为奇数(如3),确保环路形成奇数级反相,满足振荡的必要条件。
2. 添加初始复位信号(解决仿真初始状态问题)
在设计中加入复位信号,强制给环路一个初始状态,让时序仿真器能解析信号变化。
3. 调整约束与仿真设置
确保约束文件正确允许组合环路,同时在测试台中添加复位激励,触发初始状态。
修改后的代码与约束
修正后的RO_LUT_I0.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; library UNISIM; use UNISIM.VComponents.all; entity RO_LUT_I0 is Port ( rst_n : in STD_LOGIC; -- 低电平复位 EndAND : out STD_LOGIC ); end RO_LUT_I0; architecture rtl of RO_LUT_I0 is -- 改为奇数个反相器,确保振荡 constant size : integer := 3; signal I0 : std_logic_vector(0 to size - 1); signal O : std_logic_vector(0 to size - 1); signal I1 : std_logic := '0'; signal I2 : std_logic := '0'; signal I3 : std_logic := '0'; signal I4 : std_logic := '0'; signal I5 : std_logic := '0'; begin gen_LUT6: for i in 0 to size - 1 generate LUT6_inst : LUT6 generic map ( INIT => X"0000000000000001") -- I0=0时输出1,I0=1时输出0,实现反相器 port map ( O => O(i), I0 => I0(i), I1 => I1, I2 => I2, I3 => I3, I4 => I4, I5 => I5 ); end generate gen_LUT6; process(rst_n, O) variable TempAND : std_logic; begin -- 复位时强制初始状态 if rst_n = '0' then I0 <= (others => '0'); else -- 直接连接反馈,去掉行为仿真的人为延迟 I0 <= O; end if; TempAND := '1'; for i in 0 to size - 1 loop TempAND := TempAND and O(i); end loop; EndAND <= TempAND; end process; end rtl;
修正后的RO_LUT_I0_TB.vhd
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity RO_LUT_I0_TB is end RO_LUT_I0_TB; architecture sim of RO_LUT_I0_TB is signal rst_n : STD_LOGIC := '0'; signal EndAND : STD_LOGIC; begin i_RO_LUT_I0 : entity work.RO_LUT_I0(rtl) port map( rst_n => rst_n, EndAND => EndAND ); -- 复位激励:先拉低复位,10ns后释放 process is begin wait for 10 ns; rst_n <= '1'; wait; end process; end architecture;
调整后的RO_LUT_constr.xdc
set_property IOSTANDARD LVCMOS33 [get_ports EndAND] set_property PACKAGE_PIN A2 [get_ports EndAND] # 复位信号如果引到引脚的话,添加约束,否则可以注释 # set_property IOSTANDARD LVCMOS33 [get_ports rst_n] # set_property PACKAGE_PIN B2 [get_ports rst_n] set_property DONT_TOUCH TRUE [get_cells *LUT6*] set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets] set_property SEVERITY {Warning} [get_drc_checks LUTLP-1] set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
额外注意事项
- 时序仿真时,需确保使用实现后的网表(Post-Implementation),并加载正确的器件时序库。
- 若仍出现X状态,可在Vivado仿真设置中开启
Enable SDF Annotation,确保时序模型正确加载。
内容的提问来源于stack exchange,提问作者hasnieking
相关产品推荐
相关产品推荐

