在vhdl中的模拟中使用U逻辑初始化输出

时间:2016-04-20 11:09:31

标签: vhdl xilinx

我正在使用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;

模拟后请参考波形。 提前谢谢。

enter image description here

2 个答案:

答案 0 :(得分:3)

PC信号通过连续分配驱动addressIR输出:

addressIR <= PC;

但是,PCclk的第一个上升沿之前未分配任何值,因此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;至少一个完整的时钟周期。