停车场大门模拟中的未知值(X)
Unknown values (X) in simulation of parking lot gate
我正在用 VHDL 设计停车场大门。当我使用 Quartus VWF 文件对其进行仿真时,我得到了未知值 (X),但我不知道为什么。
基本上您只需验证您的卡 (Sin
),然后门会打开 10 秒。
而当一辆车离开停车场时(Sout
),它会统计此时停车场内的车辆总数。
我已经为计时器创建了信号 Ncarros
(用于计算汽车数量)和 s_count
。
全部编译正确。但是当我使用 VWF 文件对其进行测试时,这就是我得到的:
Original simulation output
我正在使用 Altera Quartus Prime 精简版。
有人可以检查我的代码并告诉我哪里做错了吗?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity MicroProj is
port (clk : in std_logic;
Sin : in std_logic;
Sout : in std_logic;
cancela : out std_logic;
timerOut : out std_logic);
end MicroProj;
architecture Behavioral of MicroProj is
signal Ncarros : integer := 0;
signal s_count : integer := 0;
begin
process (Sin,Sout,clk)
begin
if (Sin = '0') then
cancela <= '0';
else
if (Ncarros < 99) then
Ncarros <= Ncarros + 1;
cancela <= '1';
if(rising_edge(clk)) then
if(s_count /= 0) then
if(s_count = 499999999) then
timerOut <= '1';
s_count <= 0;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
end if;
end if;
end if;
if (Sout ='1') then
Ncarros <= Ncarros - 1;
end if;
end process;
end Behavioral;
当您使用矢量波形文件 (VWF) 进行仿真时,Quartus-II 实际上会仿真综合网表的行为(在此处使用 Quartus-II 13.1 检查)。如果您还没有 运行 步骤 "Analysis & Synthesis",Quartus 会要求您这样做。当您在再次模拟 VWF 之前更改 VHDL 文件时,您必须 always 运行 手动执行此步骤。综合网表以 Verilog 代码的形式写出,它将作为 ModelSim 模拟器的输入。您可以在文件 simulation/qsim/microproj.vo
.
中找到它
只要 Quartus 报告警告(或错误),综合设计的行为可能与 VHDL 描述不同。下面指出的就是这种情况。要直接模拟 VHDL 描述的行为,您必须编写一个测试台。
以下测试平台将是一个很好的入门。它为前 200 ns 分配与 VWF 文件中相同的输入值。您必须在指定位置扩展代码以添加更多信号转换。
library ieee;
use ieee.std_logic_1164.all;
entity microproj_tb is
end entity microproj_tb;
architecture sim of microproj_tb is
-- component ports
signal clk : std_logic := '0';
signal Sin : std_logic;
signal Sout : std_logic;
signal cancela : std_logic;
signal timerOut : std_logic;
begin -- architecture sim
-- component instantiation
DUT: entity work.microproj
port map (
clk => clk,
Sin => Sin,
Sout => Sout,
cancela => cancela,
timerOut => timerOut);
-- clock generation
clk <= not clk after 10 ns;
-- waveform generation
WaveGen : process
begin
Sin <= '0';
Sout <= '0';
wait for 40 ns; -- simulation time = 40 ns
Sin <= '1';
wait for 70 ns; -- simulation time = 110 ns
Sin <= '0';
wait for 50 ns; -- simulation time = 160 ns
Sin <= '1';
-- Extend here to add more signal transistions
wait;
end process WaveGen;
end architecture sim;
Quartus Prime Lite Edition 包括 ModelSim Altera Edition 的安装。您可以直接在 Quartus 项目设置中使用 ModelSim 设置和启动仿真。使用我的测试台的前 200 ns 的模拟输出如下:
如您所见,输出与您对 VWF 文件的仿真不同,因为现在仿真了 VHDL 设计本身。
在您的 VHDL 代码中,您描述了信号 cancela
和 Ncarros
的锁存器,同样由 "Analysis & Synthesis" 步骤报告:
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(26): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(27): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(48): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "cancela", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "Ncarros", which holds its previous value in one or more paths through the process
Info (10041): Inferred latch for "Ncarros[0]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[1]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[2]" at MicroProj.vhdl(20)
...
Info (10041): Inferred latch for "Ncarros[31]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "cancela" at MicroProj.vhdl(20)
在 Altera FPGA 上,锁存器是使用查找 table (LUT) 和逻辑元件 (LE) 内的组合反馈路径实现的。在对 FPGA 编程后,这种锁存器的状态是不确定的。综合网表的仿真显示为“X”。
我建议无论如何都要修复锁存器并将您的代码转换为完全同步的时钟边沿驱动设计。也就是说,仅在时钟的上升沿为 cancela
和 Ncarros
分配新值。 VHDL代码模式为:
process(clk)
begin
if rising_edge(clk) then
-- put all your assignments to cancela and Ncarros here
end if;
end process;
我正在用 VHDL 设计停车场大门。当我使用 Quartus VWF 文件对其进行仿真时,我得到了未知值 (X),但我不知道为什么。
基本上您只需验证您的卡 (Sin
),然后门会打开 10 秒。
而当一辆车离开停车场时(Sout
),它会统计此时停车场内的车辆总数。
我已经为计时器创建了信号 Ncarros
(用于计算汽车数量)和 s_count
。
全部编译正确。但是当我使用 VWF 文件对其进行测试时,这就是我得到的:
Original simulation output
我正在使用 Altera Quartus Prime 精简版。
有人可以检查我的代码并告诉我哪里做错了吗?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity MicroProj is
port (clk : in std_logic;
Sin : in std_logic;
Sout : in std_logic;
cancela : out std_logic;
timerOut : out std_logic);
end MicroProj;
architecture Behavioral of MicroProj is
signal Ncarros : integer := 0;
signal s_count : integer := 0;
begin
process (Sin,Sout,clk)
begin
if (Sin = '0') then
cancela <= '0';
else
if (Ncarros < 99) then
Ncarros <= Ncarros + 1;
cancela <= '1';
if(rising_edge(clk)) then
if(s_count /= 0) then
if(s_count = 499999999) then
timerOut <= '1';
s_count <= 0;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
else
timerOut <= '0';
s_count <= s_count + 1;
end if;
end if;
end if;
end if;
if (Sout ='1') then
Ncarros <= Ncarros - 1;
end if;
end process;
end Behavioral;
当您使用矢量波形文件 (VWF) 进行仿真时,Quartus-II 实际上会仿真综合网表的行为(在此处使用 Quartus-II 13.1 检查)。如果您还没有 运行 步骤 "Analysis & Synthesis",Quartus 会要求您这样做。当您在再次模拟 VWF 之前更改 VHDL 文件时,您必须 always 运行 手动执行此步骤。综合网表以 Verilog 代码的形式写出,它将作为 ModelSim 模拟器的输入。您可以在文件 simulation/qsim/microproj.vo
.
只要 Quartus 报告警告(或错误),综合设计的行为可能与 VHDL 描述不同。下面指出的就是这种情况。要直接模拟 VHDL 描述的行为,您必须编写一个测试台。
以下测试平台将是一个很好的入门。它为前 200 ns 分配与 VWF 文件中相同的输入值。您必须在指定位置扩展代码以添加更多信号转换。
library ieee;
use ieee.std_logic_1164.all;
entity microproj_tb is
end entity microproj_tb;
architecture sim of microproj_tb is
-- component ports
signal clk : std_logic := '0';
signal Sin : std_logic;
signal Sout : std_logic;
signal cancela : std_logic;
signal timerOut : std_logic;
begin -- architecture sim
-- component instantiation
DUT: entity work.microproj
port map (
clk => clk,
Sin => Sin,
Sout => Sout,
cancela => cancela,
timerOut => timerOut);
-- clock generation
clk <= not clk after 10 ns;
-- waveform generation
WaveGen : process
begin
Sin <= '0';
Sout <= '0';
wait for 40 ns; -- simulation time = 40 ns
Sin <= '1';
wait for 70 ns; -- simulation time = 110 ns
Sin <= '0';
wait for 50 ns; -- simulation time = 160 ns
Sin <= '1';
-- Extend here to add more signal transistions
wait;
end process WaveGen;
end architecture sim;
Quartus Prime Lite Edition 包括 ModelSim Altera Edition 的安装。您可以直接在 Quartus 项目设置中使用 ModelSim 设置和启动仿真。使用我的测试台的前 200 ns 的模拟输出如下:
如您所见,输出与您对 VWF 文件的仿真不同,因为现在仿真了 VHDL 设计本身。
在您的 VHDL 代码中,您描述了信号 cancela
和 Ncarros
的锁存器,同样由 "Analysis & Synthesis" 步骤报告:
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(26): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(27): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10492): VHDL Process Statement warning at MicroProj.vhdl(48): signal "Ncarros" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "cancela", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at MicroProj.vhdl(21): inferring latch(es) for signal or variable "Ncarros", which holds its previous value in one or more paths through the process
Info (10041): Inferred latch for "Ncarros[0]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[1]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "Ncarros[2]" at MicroProj.vhdl(20)
...
Info (10041): Inferred latch for "Ncarros[31]" at MicroProj.vhdl(20)
Info (10041): Inferred latch for "cancela" at MicroProj.vhdl(20)
在 Altera FPGA 上,锁存器是使用查找 table (LUT) 和逻辑元件 (LE) 内的组合反馈路径实现的。在对 FPGA 编程后,这种锁存器的状态是不确定的。综合网表的仿真显示为“X”。
我建议无论如何都要修复锁存器并将您的代码转换为完全同步的时钟边沿驱动设计。也就是说,仅在时钟的上升沿为 cancela
和 Ncarros
分配新值。 VHDL代码模式为:
process(clk)
begin
if rising_edge(clk) then
-- put all your assignments to cancela and Ncarros here
end if;
end process;