VHDL我的计时器不起作用

时间:2015-05-14 19:32:53

标签: vhdl

我的FPGA中有一个25MHz的时钟,我想制作一个计时器,当它计数60秒时返回'1'。但我有两个问题:

  • 我不明白为什么我模拟它时Vivado中的outpout信号“count_sortie”未定义。
  • 要强制定义我的信号count_sortie,我在testbench文件中添加“:= 0”进行模拟,但是在60秒延迟后“count_sortie”保持等于'0'。

以下是我的VHDL文件:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.all;
    use IEEE.STD_LOGIC_UNSIGNED.all;


    entity count is
        Port ( clk : in  STD_LOGIC;
               count_entree : in STD_LOGIC;
               count_sortie : out STD_LOGIC
              );
    end count;

    architecture Behavioral of count is

    signal q : integer range 0 to 30000000 :=0;

    begin

        process(clk)
        begin
        if (clk'event and clk='1')
        then 

              while ((count_entree = '1') and (q < 25000000)) loop

                 if (q < 25000000) then

                      q := q + 1;
                      count_sortie <= '0';  
                 else 

                    count_sortie <= '1';

                 end if;
              end loop;
        end if;
        end process;

    end Behavioral;

以及testbench文件:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

ENTITY tbcount IS
END tbcount;

ARCHITECTURE behavior OF tbcount IS 

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

    COMPONENT count
    PORT(
           clk : in  STD_LOGIC;
           count_entree : in STD_LOGIC;
           count_sortie : out STD_LOGIC
        );
    END COMPONENT;


    --Inputs

   signal clk : std_logic := '0';
   signal count_entree : std_logic;

    --Outputs

   signal count_sortie : std_logic;

    --Clock

   constant clk_period : time := 40 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: count PORT MAP (
          clk => clk,
          count_entree => count_entree,
          count_sortie => count_sortie
        );

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

    count_entree <= '1';

      wait;
   end process;

END;

感谢您的支持。

2 个答案:

答案 0 :(得分:2)

除了我对您的语法无效的评论,即有一个混淆,q是一个信号或变量,以下代码将无法达到您的预期:

while ((count_entree = '1') and (q < 25000000)) loop
    if (q < 25000000) then
        q := q + 1;
        count_sortie <= '0';  
    else 
        count_sortie <= '1';
    end if;
end loop;

如果在count_entree = '1'q是信号时输入,则此循环为无限循环,如果为count_sortie <= '0',则该循环将解析为单个语句q是一个变量。

你的循环没有任何等待声明。如果q是一个信号,它将永远不会更新为新值,因为当一个进程结束或遇到一个等待语句时会发生这种情况,然后你会得到一个无限循环。

如果q是变量,则循环展开,只有最后一个赋值有效。请注意,如果q < 25000000退出循环,则永远不会执行else语句。

最后,请注意,如果这是您的最终目标,这种结构将无法合成。

答案 1 :(得分:1)

实际上没有人回答你的问题:

  • 我不明白为什么我的输出信号&#34; count_sortie&#34;当我模拟它时,在Vivado中是未定义的。
  • 要强制定义我的信号count_sortie,我添加&#34;:= 0&#34;在testbench文件中模拟但是&#34; count_sortie&#34;等于&#39; 0&#39;延迟60秒后。

使用变量赋值:=编写时,您的设计描述不是有效的VHDL。

可能值得重新审视警告信息,那里发生的事情应该是显而易见的。标记为count的实例化uut在测试平台tbcount中未绑定,并且其输出信号未被驱动。就测试平台而言,没有count的实例化。

至于未提出的问题&#39;如何使其发挥作用&#39;

正如乔纳森所指出的那样,你的代码在任何情况下都无法做到你想要的。 Jonathan对while循环的作用的解释基本上是正确的,即使uut被实例化,你也不会按预期工作。

基本思路是计算直到q达到25,000,000并设置输出count_sortie。请注意,评估25000000实际上会为count_sortie添加额外的时钟延迟。

if clk'event and clk = '1' then
    if q /= 24999999 and count_entree = '1' then
        q <= q + 1;
    end if;
    if q = 24999999 then
        count_sortie <= '1';
    else 
        count_sortie <= '0';
    end if;
end if;

这将计入24999999并停止计数。一个时钟后count_sortie将被设置(1)。

如果您要清除或加载q以重新启动定时器,那么count_sortie转到&#39; 0&之前会有一个时钟延迟。 #39;

如果这可能是有害的,你可以将比较恢复到25000000,并将if语句的赋值移动到count_sortie超出if语句边界的范围,评估clk的上升沿,甚至制作它是一个并发的条件信号赋值语句。

在过程中保留作业可能更节俭,它在合成中与count共享相同的比较,保证。

上面这个答案中的代码看起来像这样:

if clk'event and clk = '1' then
    if q /= 25000000 and count_entree = '1' then
        q <= q + 1;
    end if;
end if;
if q = 25000000 then
    count_sortie <= '1';
else 
    count_sortie <= '0';
end if;

q应该在敏感列表中。另请注意,整数q的范围只需要从它最左边延伸到它最右边的赋值。

为了证明这一点,我将所有计数值除以100,000(出于演示目的,数字文字250可以在所有三个位置设置为25000000):

architecture behavioral of count is

    signal q: integer range 0 to 250 ;

begin

timer: 
    process (clk,q)
    begin
        if clk'event and clk = '1' then
            if q /= 250 and count_entree = '1' then
                q <= q + 1;
            end if;
        end if;
        if q = 250 then
            count_sortie <= '1';
        else 
            count_sortie <= '0';
        end if;
     end process;

end architecture;

缩放q是关于等待所有那些不必要的时钟 演示count_sortie与您的测试平台一起使用:

tbcount for q in range 0 to 250 (点击)

现在我们不仅直接回答了您的问题,还展示了如何使其正常运行。

如果你打算使用count_sortie作为时钟,你想要使用第一种方法(使用24999999)。