在 vhdl 中的模拟中使用 U 逻辑初始化输出
Output get initialized with U logic in simulation in vhdl
我正在使用 Xilinx。目前我正在从事一个开发流水线 MIPS 处理器的项目。我制作了一个名为 Program_Counter.vhd 的组件文件。当我使用测试台模拟它时,输出会用 U 初始化,然后就可以了。我无法理解这种行为。任何帮助将不胜感激。
我的Program_Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Program_Counter is
port (clk,reset,Last : in std_logic;
addressALU : in std_logic_vector(31 downto 0);
addressIR : out std_logic_vector(31 downto 0)
) ;
end entity ; -- Program_Counter
architecture Behavioral of Program_Counter is
signal PC : std_logic_vector(31 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
PC <= (others => '0');
elsif Last ='1' then
null;
else
PC <= addressALU;
end if ;
end if ;
end process;
addressIR <= PC;
end Behavioral;
这是测试平台
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY PC_tb IS
END PC_tb;
ARCHITECTURE behavior OF PC_tb IS
COMPONENT Program_Counter
PORT(
clk : IN std_logic;
reset : IN std_logic;
Last : IN std_logic;
addressALU : IN std_logic_vector(31 downto 0);
addressIR : OUT std_logic_vector(31 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal Last : std_logic := '0';
signal addressALU : std_logic_vector(31 downto 0) := (others => '0');
--Outputs
signal addressIR : std_logic_vector(31 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Program_Counter PORT MAP (
clk => clk,
reset => reset,
Last => Last,
addressALU => addressALU,
addressIR => addressIR
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 35 ns;
--reset <= '0';
for i in 1 to 10 loop
addressALU <= addressALU + "1";
wait for clk_period ;
end loop;
wait for clk_period*10;
wait;
end process;
END;
请参考仿真后的波形。
提前致谢。
PC
信号通过连续赋值驱动addressIR
输出:
addressIR <= PC;
但是PC
直到clk
的第一个上升沿才赋值,所以PC
最初全是'U'
,称为"uninitialized" 在 std_logic_1164
包中,这是未分配的 std_logic
元素的第一个也是初始值。
PC
信号可以使用以下方法给定初始值:
signal PC : std_logic_vector(31 downto 0) := (others => '0');
但通常最好不要这样做,因为在模拟中显示非 '0'
/'1'
值是好处之一,因为它可能揭示缺少分配的实际问题,例如由于遗漏了重置或类似问题。
信号 addressIR
在第一个时钟上升沿之前都是 'U',因为您没有为其分配任何其他值。赋值来自这个语句:
addressIR <= PC;
and在模拟启动后执行一次,每次PC
变化。也就是说,addressIR
在增量循环后等于 PC
。信号 PC
在时钟上升沿的时钟过程中第一次被分配。在此之前,PC
的信号值由其声明定义。您没有在那里指定值,因此 std_logic_vector
的所有元素都被初始化为 std_logic
类型枚举中的第一个值。那就是'U',表示信号是未初始化.
模拟在这里显示了真实世界的行为,特别是如果您为 standard cell technology. On FPGAs you have sometimes the option to program the initial value of a flip-flop. But, you will have to reset the FPGA design after startup anyway as discussed in the question "Do I need to reset my FPGA design after startup?" on Electrical Engineering. My answer there 合成 VHDL 代码,包括初始化失败的屏幕截图。因此,无论如何你都必须断言reset
。
第一个时钟上升沿之前 addressIR
的值应该没有意义,因为使用该信号值的单元也应该处于复位状态。例如,指令总线单元不应在复位时发出总线事务。
整个系统的所有组件都应在第一个时钟上升沿执行复位。
您应该在您的测试平台中包含一个重置同步器。稍后,这个重置同步器将成为整个系统的一部分。您将需要这些声明:
signal reset_sync : std_logic_vector(1 downto 0) := (others => '1');
signal reset : std_logic;
以及架构主体(寄存器链)中的这些语句:
reset_sync <= reset_sync(reset_sync'high-1 downto 0) & reset_pin when rising_edge(clock);
reset <= reset_sync(reset_sync'high); -- active-high
信号reset_pin
为外部复位输入。如果您不需要它,只需将其替换为“0”即可。
是的,此重置同步器使用 FPGA 上的已初始化触发器。但是,只有触发器 reset_sync(0)
会遇到初始化问题。在 Xilinx FPGA 上的全局写入使能 (GWE) 释放后的第一个时钟上升沿之后,该触发器的值可能为“0”或“1”。触发器 reset_sync(1)
将在至少一个完整时钟周期内为“1”。
我正在使用 Xilinx。目前我正在从事一个开发流水线 MIPS 处理器的项目。我制作了一个名为 Program_Counter.vhd 的组件文件。当我使用测试台模拟它时,输出会用 U 初始化,然后就可以了。我无法理解这种行为。任何帮助将不胜感激。
我的Program_Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Program_Counter is
port (clk,reset,Last : in std_logic;
addressALU : in std_logic_vector(31 downto 0);
addressIR : out std_logic_vector(31 downto 0)
) ;
end entity ; -- Program_Counter
architecture Behavioral of Program_Counter is
signal PC : std_logic_vector(31 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
PC <= (others => '0');
elsif Last ='1' then
null;
else
PC <= addressALU;
end if ;
end if ;
end process;
addressIR <= PC;
end Behavioral;
这是测试平台
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY PC_tb IS
END PC_tb;
ARCHITECTURE behavior OF PC_tb IS
COMPONENT Program_Counter
PORT(
clk : IN std_logic;
reset : IN std_logic;
Last : IN std_logic;
addressALU : IN std_logic_vector(31 downto 0);
addressIR : OUT std_logic_vector(31 downto 0)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal Last : std_logic := '0';
signal addressALU : std_logic_vector(31 downto 0) := (others => '0');
--Outputs
signal addressIR : std_logic_vector(31 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: Program_Counter PORT MAP (
clk => clk,
reset => reset,
Last => Last,
addressALU => addressALU,
addressIR => addressIR
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 35 ns;
--reset <= '0';
for i in 1 to 10 loop
addressALU <= addressALU + "1";
wait for clk_period ;
end loop;
wait for clk_period*10;
wait;
end process;
END;
请参考仿真后的波形。 提前致谢。
PC
信号通过连续赋值驱动addressIR
输出:
addressIR <= PC;
但是PC
直到clk
的第一个上升沿才赋值,所以PC
最初全是'U'
,称为"uninitialized" 在 std_logic_1164
包中,这是未分配的 std_logic
元素的第一个也是初始值。
PC
信号可以使用以下方法给定初始值:
signal PC : std_logic_vector(31 downto 0) := (others => '0');
但通常最好不要这样做,因为在模拟中显示非 '0'
/'1'
值是好处之一,因为它可能揭示缺少分配的实际问题,例如由于遗漏了重置或类似问题。
信号 addressIR
在第一个时钟上升沿之前都是 'U',因为您没有为其分配任何其他值。赋值来自这个语句:
addressIR <= PC;
and在模拟启动后执行一次,每次PC
变化。也就是说,addressIR
在增量循环后等于 PC
。信号 PC
在时钟上升沿的时钟过程中第一次被分配。在此之前,PC
的信号值由其声明定义。您没有在那里指定值,因此 std_logic_vector
的所有元素都被初始化为 std_logic
类型枚举中的第一个值。那就是'U',表示信号是未初始化.
模拟在这里显示了真实世界的行为,特别是如果您为 standard cell technology. On FPGAs you have sometimes the option to program the initial value of a flip-flop. But, you will have to reset the FPGA design after startup anyway as discussed in the question "Do I need to reset my FPGA design after startup?" on Electrical Engineering. My answer there 合成 VHDL 代码,包括初始化失败的屏幕截图。因此,无论如何你都必须断言reset
。
第一个时钟上升沿之前 addressIR
的值应该没有意义,因为使用该信号值的单元也应该处于复位状态。例如,指令总线单元不应在复位时发出总线事务。
整个系统的所有组件都应在第一个时钟上升沿执行复位。
您应该在您的测试平台中包含一个重置同步器。稍后,这个重置同步器将成为整个系统的一部分。您将需要这些声明:
signal reset_sync : std_logic_vector(1 downto 0) := (others => '1');
signal reset : std_logic;
以及架构主体(寄存器链)中的这些语句:
reset_sync <= reset_sync(reset_sync'high-1 downto 0) & reset_pin when rising_edge(clock);
reset <= reset_sync(reset_sync'high); -- active-high
信号reset_pin
为外部复位输入。如果您不需要它,只需将其替换为“0”即可。
是的,此重置同步器使用 FPGA 上的已初始化触发器。但是,只有触发器 reset_sync(0)
会遇到初始化问题。在 Xilinx FPGA 上的全局写入使能 (GWE) 释放后的第一个时钟上升沿之后,该触发器的值可能为“0”或“1”。触发器 reset_sync(1)
将在至少一个完整时钟周期内为“1”。