2017-02-17 62 views
0

我有一個簡單的VHDL設計和測試平臺,它不會產生預期的輸出。 ISim顯示所有輸出的'U',直到達到'運行'狀態(myState ='1')。然後他們顯示0和X值。當ENABLE爲'0'時,第一個PROCESS塊應將所有輸出設置爲'0'。測試臺切換ENABLE 0-1-0以確保事件觸發過程,但輸出保持'U'。設計,測試或兩者都存在問題嗎?ISim爲所有輸出顯示U

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; 

試驗檯

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示出了在模擬早期使能脈衝,但輸出保持 'U',直到與使WCLK的上升沿= 1。然後他們開始改變(按照設計),但他們顯示了一些X值。

ISim Windowsenter image description here

改性VHDL

作爲參考,這裏是解決在模擬輸出將U和X的問題的改性VHDL。但是,PCM_DIN輸出有一個功能問題,似乎是延遲一個(BCLK)週期。在ENABLE之後第一次ADAT_WDCLK變爲高電平時,我預計它是'1'。但是直到BLCK週期後纔會進入'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; 

上述(包括內部myState信號)...的ISIM爲什麼PCM_DIN延遲一個週期BCLK?

enter image description here

+0

即使治癒多個驅動程序,您的代碼也不會顯示合成條件。似乎不可能在一個時鐘的兩個邊沿上清除計數器並用另一個時鐘遞增。 – user1155120

+0

清除WDCLK邊沿上的計數器無論如何都是冗餘的,它每8位就會包裝一次,並且在字時鐘週期內發送的整數個字節(因此它在時鐘週期的開始/結束時始終爲零)。所以我刪除了這些陳述。 – user3191192

回答

0

關於「X」(強制未知)值,您看到:

你所駕駛的信號PCM_FS,從多個進程PCM_CLKtmp,導致在模擬器暫時無法解析價值被驅動。你需要解決這個問題,使它們只能從一個進程中驅動,或者在不使用時驅動'Z'

關於'U'值,它們的存在是因爲您沒有信號的初始值。第一次寫入信號後(啓用後),它們將首次被分配。

+0

啊,這是有道理的,我猜想像一個組合邏輯塊的過程,他們不能同時驅動相同的電路節點,除非明確設置爲高Z.仍然不確定U的,但我的重組代碼沒有他們了(甚至在ENABLE之前)。 我張貼更新的代碼。沒有U'x或X,但我不明白爲什麼PCM_DIN輸出延遲一個時鐘週期...當WDCLK在ENABLE後第一次變爲高電平時應該爲'1'。 – user3191192