2017-02-17 73 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