2016-04-20 19 views
1

initialisiert Ich verwende Xilinx. Derzeit arbeite ich an einem Projekt zur Entwicklung eines MIPS-Pipeline-Prozessors. Ich habe eine Komponentendatei namens Program_Counter.vhd gemacht. Wenn ich es mit einer Testbench simuliere, wird der Ausgang mit U initialisiert und danach ist es in Ordnung. Ich kann dieses Verhalten nicht verstehen. Jede Hilfe wird sehr geschätzt.Ausgang wird mit U-Logik in der Simulation in VHDL

Mein 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; 

Hier ist der Prüfstand

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; 

bitte die Wellenform nach der Simulation beziehen. Vielen Dank im Voraus.

enter image description here

Antwort

3

Die PC Signaltreiber die addressIR Ausgang durch die kontinuierliche assign:

addressIR <= PC; 

jedoch die PC keinen Wert, bis die erste ansteigende Flanke des clk zugeordnet, so dass die PC zunächst alle 'U', genannt "nicht initialisiert" in std_logic_1164 packge, das ist der erste und somit Anfangswert für nicht zugeordnete std_logic Elemente.

Das PC Signal kann einen Anfangswert verwendet wird gegeben:

signal PC : std_logic_vector(31 downto 0) := (others => '0'); 

aber es ist in der Regel besser, dass nicht zu tun, da zeigt nicht '0'/'1' Werte in der Simulation einer der Vorteile ist, wie es kann tatsächliche Probleme mit fehlenden Zuweisungen aufdecken, z wegen ausgelassenem Reset oder ähnlichem.

+0

Also ich sollte meine Uhr von asynchron auf asynchron ändern müssen oder gibt es eine andere Methode, um es zu vermeiden? –

+0

Nein, mein Punkt ist, vermeiden Sie es nicht; umarme es als Feature. Es ist an sich kein Problem, dass Signale beim Start nicht definiert sind; In der Tat ist es nur so, dass echte Hardware normalerweise funktioniert, also sollte die Simulation sie widerspiegeln. Wenn Sie im Entwurf wohldefinierte Werte benötigen, fügen Sie ein Reset-Signal hinzu, das den Flip-Flop-Zustand entweder durch asynchronen oder synchronen Reset zurücksetzen kann. –

+0

Danke, Sir, ich habe es behoben, indem ich das clk-Signal mit 1 anstelle von 0 gestartet habe. –

0

Das Signal addressIR ist alles 'U' vor der ersten steigenden Taktflanke, weil Sie ihm keinen anderen Wert zugewiesen haben. Die Zuordnung stammt aus dieser Aussage:

addressIR <= PC; 

und einmal nach der Simulation Start ausgeführt und jedes Mal PC Änderungen. Das heißt, addressIR entspricht nach einem Delta-Zyklus. Das Signal ist das erste Mal in Ihrem getakteten Prozess an der steigenden Taktflanke zugewiesen. Zuvor wird der Signalwert durch seine Deklaration definiert. Sie haben dort keinen Wert angegeben, so dass alle Elemente der std_logic_vector auf den ersten Wert in der Enumeration vom Typ std_logic initialisiert werden. Und das ist "U", was bedeutet, dass das Signal nicht initialisiert ist.

Die Simulation zeigt das Verhalten der realen Welt hier, besonders wenn Sie den VHDL-Code für eine standard cell technology synthetisieren. Auf FPGAs haben Sie manchmal die Möglichkeit, den Anfangswert eines Flip-Flops zu programmieren. Aber Sie müssen das FPGA-Design nach dem Start trotzdem zurücksetzen, wie in der Frage "Do I need to reset my FPGA design after startup?" auf Elektrotechnik beschrieben. My answer there enthält einen Screenshot einer fehlgeschlagenen Initialisierung. Also, müssen Sie reset auf jeden Fall bestätigen.

Der Wert von addressIR vor der ersten steigenden Taktflanke sollte nicht von Interesse sein, da die Einheit, die diesen Signalwert verwendet, ebenfalls zurückgesetzt sein sollte. Zum Beispiel sollte die Befehlsbuseinheit während des Zurücksetzens keine Bustransaktion ausgeben.

Alle Komponenten des gesamten Systems sollten einen Reset an der ersten steigenden Taktflanke ausführen.


Sie sollten einen Reset-Synchronizer in Ihre Testbench einfügen. Später wird dieser Reset-Synchronizer Teil des gesamten Systems sein. Sie werden diese Erklärungen benötigen:

signal reset_sync : std_logic_vector(1 downto 0) := (others => '1'); 
signal reset : std_logic; 

und diese Aussagen in der Architektur Körper (Register-Kette):

reset_sync <= reset_sync(reset_sync'high-1 downto 0) & reset_pin when rising_edge(clock); 
reset <= reset_sync(reset_sync'high); -- active-high 

Das Signal reset_pin ist der externe Reset-Eingang. Wenn Sie es nicht brauchen, ersetzen Sie es einfach durch "0".

Ja, dieser Reset-Synchronizer verwendet initialisierte Flip-Flops auf FPGAs. Aber nur das Flip-Flop reset_sync(0) unterliegt dem Initialisierungsproblem. Der Wert dieses Flip-Flops kann '0' oder '1' nach der ersten steigenden Taktflanke sein, nachdem die globale Schreibfreigabe (GWE) auf Xilinx FPGAs freigegeben wurde. Das Flip-Flop reset_sync(1) wird für mindestens einen vollen Taktzyklus '1' sein.