我正在使用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;
模拟后请参考波形。 提前谢谢。
答案 0 :(得分:3)
PC
信号通过连续分配驱动addressIR
输出:
addressIR <= PC;
但是,PC
在clk
的第一个上升沿之前未分配任何值,因此PC
最初都是'U'
,称为&#34;未初始化&# 34;在std_logic_1164
packge中,这是未分配的std_logic
元素的第一个初始值。
PC
信号可以使用以下方式给出初始值:
signal PC : std_logic_vector(31 downto 0) := (others => '0');
但通常最好不要这样做,因为在模拟中显示非'0'
/ '1'
值是其中一个好处,因为它可能会揭示丢失分配的实际问题,例如:由于遗漏重置或类似。
答案 1 :(得分:0)
信号addressIR
全部是&#39; U&#39;在第一个上升时钟边沿之前,因为您没有为其分配任何其他值。作业来自这句话:
addressIR <= PC;
并在模拟启动后执行一次,每次PC
更改。也就是说,{delta}周期后addressIR
等于PC
。信号PC
是在时钟上升沿的时钟进程中第一次分配的。在此之前,PC
的信号值由其声明定义。您没有在那里指定值,因此std_logic_vector
的所有元素都被初始化为类型std_logic
的枚举中的第一个值。这就是&#39; U &#39;,表示信号未初始化。
模拟显示了这里的真实行为,特别是如果您合成standard cell technology的VHDL代码。在FPGA上,您有时可以选择编程触发器的初始值。但是,无论如何,您都必须在启动后重置FPGA设计,如电气工程问题"Do I need to reset my FPGA design after startup?"中所述。 My answer there包含初始化失败的屏幕截图。因此,无论如何都必须断言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
是外部复位输入。如果你不需要它,而不仅仅用&#39; 0&#39;替换它。
是的,这个复位同步器在FPGA上使用初始化的触发器。但是,只有触发器reset_sync(0)
受到初始化问题的影响。该触发器的值可以是&#39; 0&#39; 0或者&#39; 1&#39;在Xilinx FPGA上的全局写入使能(GWE)发布后的第一个时钟上升沿之后。触发器reset_sync(1)
将是&#39; 1&#39;至少一个完整的时钟周期。