Vhdl ISim显示所有输出的U

Vhdl ISim显示所有输出的U,vhdl,Vhdl,我有一个简单的VHDL设计和测试平台,不能产生预期的输出。ISim显示所有输出的“U”,直到达到“运行”状态(myState='1')。然后显示0和X值。当启用为“0”时,第一个进程块应将所有输出设置为“0”。测试台切换启用0-1-0以确保事件触发过程,但输出保持在“U”。问题是在设计、测试中,还是两者兼而有之 VHDL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity TestHarness1 is port ( ADAT_WDCLK

我有一个简单的VHDL设计和测试平台,不能产生预期的输出。ISim显示所有输出的“U”,直到达到“运行”状态(myState='1')。然后显示0和X值。当启用为“0”时,第一个进程块应将所有输出设置为“0”。测试台切换启用0-1-0以确保事件触发过程,但输出保持在“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;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
实体TestHarness1是
港口(
ADAT_WDCLK:标准逻辑中;
ADAT_BCLK:标准逻辑中;
ADAT_OUT12:标准逻辑中;
启用:在std_逻辑中;
PCM_FS:输出标准逻辑;
PCM_时钟:输出标准_逻辑;
PCM_DIN:输出标准逻辑
);
末端测试治理1;
TestHarness1的行为架构是
--类型状态为(停止、运行);
信号tmp:std_逻辑;
信号状态:标准逻辑;
开始
PCM_DIN关于您看到的“X”(强制未知)值:

您正在驱动来自多个进程的信号
PCM_FS
PCM_CLK
tmp
,这导致模拟器无法解析所驱动的值。您需要修复此问题,使它们仅由一个进程驱动,或者在不使用时驱动
'Z'


关于“U”值,它们的存在是因为没有信号的初始值。一旦您第一次写入信号(在启用后),它们将第一次被分配。

即使您修复了多个驱动程序,您的代码也不符合条件。清除一个时钟边缘上的计数器并用另一个时钟增加它似乎是不可能的。清除WDCLK边缘上的计数器是多余的,它每8位环绕一次,并且在一个字时钟周期内发送整数个字节(因此在时钟周期的开始/结束时总是零)。所以我删除了这些语句。啊,这是有道理的,我想这是一个类似组合逻辑块的过程,它们不能同时驱动同一个电路节点,除非其中一个显式地设置为高Z。仍然不确定U,但我重构的代码不再有它们(甚至在启用之前)。我张贴更新的代码。没有U'x或x's,但我不明白为什么PCM_DIN输出延迟一个时钟周期。。。当WDCLK在启用后第一次变高时,它应为“1”。
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;
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;