2017-02-17 6 views
0

Ich habe einen einfachen VHDL-Design- und Prüfstand, der nicht die erwartete Ausgabe liefert. ISim zeigt für alle Ausgaben 'U' an, bis der Zustand 'running' erreicht ist (myState = '1'). Dann zeigen sie 0 und X Werte. Der erste PROCESS-Block sollte alle Ausgänge auf '0' setzen, wenn ENABLE '0' ist. Der Prüfstand schaltet ENABLE 0-1-0 ein, um sicherzustellen, dass ein Ereignis den Prozess auslöst, aber die Ausgänge bleiben auf "U". Ist das Problem beim Design, beim Test oder bei beiden?ISim zeigt U für alle Ausgänge an

VHDL

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity TestHarness1 is 
port (
    ADAT_WDCLK : in std_logic; 
    ADAT_BCLK: in std_logic; 
    ADAT_OUT12: in std_logic; 
    ENABLE: in std_logic; 

    PCM_FS : out std_logic; 
    PCM_CLK : out std_logic; 
    PCM_DIN : out std_logic 
); 
end TestHarness1; 

architecture Behavioral of TestHarness1 is 
    --type state is (STOPPED, RUNNING); 
    signal tmp : std_logic; 
    signal myState : std_logic; 
begin 
    PCM_DIN <= tmp; 

    -- State management process 
    process (ENABLE, ADAT_WDCLK) begin -- Eval on input changes 
     if (ENABLE = '0') then 
      myState <= '0'; --STOPPED; 
      PCM_FS <= '0'; -- All outputs muted 
      PCM_CLK <= '0'; 
      tmp <= '0'; 
     else 
      if (myState = '0' and rising_edge(ADAT_WDCLK)) then 
       -- Move to running state only at start of a frame 
       myState <= '1'; --RUNNING; 
      end if; 
     end if; 
    end process; 

    -- Output process 
    process (ADAT_WDCLK, ADAT_BCLK, myState) variable counter: integer := 0; begin 
     -- Only do something if we are in running state, process above 
     -- sets outputs when stopped. 
     if (myState = '1') then 

      -- Pass the clocks through, inverting the bit clock 
      PCM_FS <= ADAT_WDCLK; 
      PCM_CLK <= not ADAT_BCLK; 

      -- Generate fixed bit pattern data '11000101' 
      if rising_edge(ADAT_WDCLK) then 
       -- This would happen naturally since there are 4 bytes per word clock 
       counter := 0; 
      end if; 
      if falling_edge(ADAT_WDCLK) then 
       -- This would happen naturally since there are 4 bytes per word clock 
       counter := 0; 
      end if; 
      if rising_edge(ADAT_BCLK) then -- Change data state only on falling edge of output PCM_CLK 
       if counter = 0 or counter = 1 or counter = 5 or counter = 7 then 
        tmp <= '1'; 
       else 
        tmp <= '0'; 
       end if; 
       if (counter = 7) then 
        counter := 0;  -- Reset counter 
       else 
        counter := counter + 1; -- Just inc counter 
       end if; 

      end if; 
     end if; 
    end process; 
end Behavioral; 

Prüfstands

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 

ENTITY TH1TestBench3 IS 
END TH1TestBench3; 

ARCHITECTURE behavior OF TH1TestBench3 IS 

    -- Component Declaration for the Unit Under Test (UUT) 

    COMPONENT TestHarness1 
    PORT(
     ADAT_WDCLK : IN std_logic; 
     ADAT_BCLK : IN std_logic; 
     ADAT_OUT12 : IN std_logic; 
     ENABLE : IN std_logic; 
     PCM_FS : OUT std_logic; 
     PCM_CLK : OUT std_logic; 
     PCM_DIN : OUT std_logic 
     ); 
    END COMPONENT; 


    --Inputs 
    signal ADAT_WDCLK : std_logic := '0'; 
    signal ADAT_BCLK : std_logic := '0'; 
    signal ADAT_OUT12 : std_logic := '0'; 
    signal ENABLE : std_logic := '0'; 

    --Outputs 
    signal PCM_FS : std_logic; 
    signal PCM_CLK : std_logic; 
    signal PCM_DIN : std_logic; 

    -- Clock period definitions. Note WDCLK is defined in terms of the bit clock 
    -- to insure they are exactly in sync. 
    constant ADAT_BCLK_period : time := 326 ns; -- About 3.072MHz (https://www.sensorsone.com/frequency-to-period-calculator/) 
    constant ADAT_WDCLK_period : time := ADAT_BCLK_period * 64; -- 48KHz 

BEGIN 

    -- Instantiate the Unit Under Test (UUT) 
    uut: TestHarness1 PORT MAP (
      ADAT_WDCLK => ADAT_WDCLK, 
      ADAT_BCLK => ADAT_BCLK, 
      ADAT_OUT12 => ADAT_OUT12, 
      ENABLE => ENABLE, 
      PCM_FS => PCM_FS, 
      PCM_CLK => PCM_CLK, 
      PCM_DIN => PCM_DIN 
     ); 


    -- Clock process definitions 
    ADAT_WDCLK_process :process 
    begin 
     ADAT_WDCLK <= '0'; 
     wait for ADAT_WDCLK_period/2; 
     ADAT_WDCLK <= '1'; 
     wait for ADAT_WDCLK_period/2; 
    end process; 

    ADAT_BCLK_process :process 
    begin 
     ADAT_BCLK <= '1'; 
     wait for ADAT_BCLK_period/2; 
     ADAT_BCLK <= '0'; 
     wait for ADAT_BCLK_period/2; 
    end process; 


    -- Stimulus process 
    stim_proc: process 
    begin   
     -- hold reset state for 100 ns. 
     wait for 100 ns; 
     ENABLE <= '1'; 
     wait for 100 ns; 
     ENABLE <= '0'; 
     wait for 7500 ns; 
     ENABLE <= '1'; 


     wait for ADAT_WDCLK_period*10; 

     -- insert stimulus here 

     wait; 
    end process; 

END; 

ISIM zeigt die Puls früh in der Simulation ENABLE, aber die Ausgänge bleiben 'U', bis die ansteigende Flanke des WCLK mit ENABLE = 1. Dann beginnen sie sich zu ändern (wie geplant), aber sie zeigen einige X-Werte.

ISim Windowsenter image description here

VHDL Modifizierte

Als Referenz ist hier der modifizierte VHDL dass das Problem des U ist und X die in der Simulationsausgabe löst. Es gibt jedoch ein funktionelles Problem mit der PCM_DIN-Ausgabe ... scheint wie ein verzögerter Zyklus (BCLK) zu sein. Ich habe erwartet, dass es "1" ist, sobald ADAT_WDCLK das erste Mal nach ENABLE auf Hoch geht. Aber es geht nicht bis zu einem BLCK-Zyklus später auf "1".

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity TestHarness1 is 
port (
    ADAT_WDCLK : in std_logic; 
    ADAT_BCLK: in std_logic; 
    ADAT_OUT12: in std_logic; 
    ENABLE: in std_logic; 

    PCM_FS : out std_logic; 
    PCM_CLK : out std_logic; 
    PCM_DIN : out std_logic 
); 
end TestHarness1; 

architecture Behavioral of TestHarness1 is 
    --type state is (STOPPED, RUNNING); 
    signal tmp : std_logic; 
    signal myState : std_logic; 
begin 
    PCM_DIN <= tmp; 

    -- State management process 
    process (ENABLE, ADAT_WDCLK) begin -- Eval on input changes 
     if (ENABLE = '0') then 
      myState <= '0'; --STOPPED; 
     else 
      if (myState = '0' and rising_edge(ADAT_WDCLK)) then 
       -- Move to running state only at start of a frame 
       myState <= '1'; --RUNNING; 
      end if; 
     end if; 
    end process; 

    -- Output process 
    process (ADAT_WDCLK, ADAT_BCLK, myState) variable counter: integer := 0; begin 
     -- Only do something if we are in running state 
     if (myState = '0') then 
      PCM_FS <= '0'; -- All outputs muted 
      PCM_CLK <= '0'; 
      tmp <= '0'; 
     elsif (myState = '1') then 
      -- Pass the clocks through, inverting the bit clock 
      PCM_FS <= ADAT_WDCLK; 
      PCM_CLK <= not ADAT_BCLK; 

      if rising_edge(ADAT_BCLK) then -- Generate fixed serial bit pattern 
       if counter = 0 or counter = 1 or counter = 5 or counter = 7 then 
        tmp <= '1'; 
       else 
        tmp <= '0'; 
       end if; 
       if (counter = 7) then 
        counter := 0;  -- Reset counter 
       else 
        counter := counter + 1; -- Just inc counter 
       end if; 

      end if; 
     end if; 
    end process; 

end Behavioral; 

isim der oben (einschließlich des internen MyState-Signal) ... warum PCM_DIN verzögert ein BCLK-Zyklus?

enter image description here

+0

Ihr Code erscheint nicht als Synthese geeignet, auch wenn Sie mehrere Treiber aushärten. Es scheint nicht möglich, den Zähler an beiden Flanken einer Uhr zu löschen und ihn mit einer anderen zu erhöhen. – user1155120

+0

Das Löschen des Zählers an den Kanten von WDCLK war sowieso redundant, es wird alle 8 Bits umgebrochen und es gibt eine ganzzahlige Anzahl von Bytes, die in einer Worttaktperiode gesendet werden (so ist es am Anfang/Ende eines Taktzyklus immer Null). Also entferne ich diese Aussagen. – user3191192

Antwort

0

In Bezug auf das ‚X‘ (Erzwingen Unbekannt) Werte, die Sie sehen:

Sie fahren die Signale PCM_FS, PCM_CLK und tmp von mehreren Prozessen, die im Simulator führt nicht in der Lage zu lösen der Wert wird gefahren. Sie müssen dies so beheben, dass sie nur von einem Prozess gesteuert werden, oder 'Z' fahren, wenn sie nicht verwendet werden.

In Bezug auf die U-Werte existieren sie, weil Sie keine Anfangswerte für die Signale haben. Sobald Sie die Signale zum ersten Mal schreiben (nach der Freigabe), werden sie zum ersten Mal zugewiesen.

+0

Ah, das macht Sinn, ich schätze einen Prozess wie einen Block kombinatorischer Logik und sie können nicht beide den gleichen Schaltungsknoten treiben, wenn man nicht ausdrücklich auf hohe Z gesetzt ist. Noch immer nicht sicher über die U's, aber mein restrukturierter Code hat sie nicht mehr (noch vor dem ENABLE). Ich poste aktualisierten Code. Keine U'x oder X, aber ich verstehe nicht, warum der PCM_DIN-Ausgang um einen Taktzyklus verzögert wird ... er sollte '1' sein, wenn WDCLK das erste Mal nach ENABLE auf High geht. – user3191192

Verwandte Themen