简体   繁体   English

Quartus II:简单的计数器,但行为怪异

[英]Quartus II : simple counter but weird behaviour

First of all I'm sorry to bother you guys with my very noob question, but I can't find any sense to what's happening with my (ModelSim simulated) circuit. 首先,很抱歉打扰我的菜鸟问题,但是我对我的(ModelSim模拟)电路发生的事情一无所知。

Here's my code, simple as can be : 这是我的代码,可能很简单:

LIBRARY ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

ENTITY Counter IS
    PORT(
    enable  : in std_logic;
    clk     : in std_logic;
    count       : out integer range 0 to 255);
END Counter;

ARCHITECTURE LogicFunction OF Counter IS

    signal count_i : integer range 0 to 255;

begin

    cnt : process(clk, enable, count_i)
    begin
        count <= count_i;
        if (enable = '0') then
            count_i <= 0;
        else
            count_i <= count_i + 1;
        end if;
    end process;

end LogicFunction;

My problem is : when I perform a timing simulation with ModelSim, with a clock signal, "enabled" is first '0' and then '1', the output ("count") stays at zero all the time. 我的问题是:当我使用ModelSim通过时钟信号执行时序仿真时,“启用”首先是“ 0”,然后是“ 1”,输出(“计数”)始终保持为零。 I tried a lot of different things, like setting the "count" out as a vector, doing all sorts of casts, but it still stays the same. 我尝试了很多不同的方法,例如将“ count”设置为向量,进行各种类型的转换,但是仍然保持不变。

The increment "count_i <= count_i + 1;" 增量“ count_i <= count_i + 1;” seems to be the problem : I tried to replace it with something like "count_i <= 55", and then the output changes (to "55" in the previous example). 似乎是问题所在:我尝试用“ count_i <= 55”之类的东西替换它,然后输出更改(在上一示例中为“ 55”)。

I've seen the exact same increment in the code on that webpage for example : http://surf-vhdl.com/how-to-connect-serial-adc-fpga/ I've created a project, simulated it and... it works ! 我在该网页上的代码中看到了完全相同的增量,例如: http : //surf-vhdl.com/how-to-connect-serial-adc-fpga/我创建了一个项目,并对其进行了仿真。 .. 有用 ! I really don't get what the guy did that I didn't, excepted for a bunch of "if" that I don't need in my code. 我确实不了解那个家伙所做的我没有做过的事情,只是我的代码中不需要一堆“如果”。

Any help would be greatly appreciated, I've spent like 3 hours of trial and errors... 任何帮助将不胜感激,我花了3个小时的尝试和错误...

Thanx in advance ! 提前感谢!

In addition to not using a clock edge to increment i_count you're using enable as a clear because it's both in the sensitivity list and encountered first in an if statement condition. 除了不使用时钟沿来增加i_count之外,您还使用enable作为清除对象,因为它既在敏感性列表中,又在if语句条件下首先遇到。

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all;

entity counter is
    port(
    enable  : in std_logic;
    clk     : in std_logic;
    count       : out integer range 0 to 255);
end counter;


architecture logicfunction of counter is

    signal count_i : integer range 0 to 255;

begin

    cnt : process (clk) -- (clk, enable, count_i)
    begin
        -- count <= count_i;   -- MOVED 
        -- if (enable = '0') then  -- REWRITTEN
        --     count_i <= 0;
        -- else
        --     count_i <= count_i + 1;
        -- end if;
        if rising_edge(clk) then
            if enable = '1' then
                count_i <= count_i + 1;
            end if;
        end if;
    end process;

    count <= count_i;  -- MOVED TO HERE

end architecture logicfunction;

Your code is modified to using the rising edge of clk and require enable = '1' before i_count increment. 您的代码已修改为使用clk的上升沿,并要求在i_count递增之前使能enable ='1'。 The superfluous use clause referencing package numeric_std has been commented out. 引用软件包numeric_std的多余use子句已被注释掉。 The only numeric operation you're performing is on an integer and those operators are predefined in package standard. 您要执行的唯一数字运算是在整数上,并且这些运算符在软件包标准中已预定义。

Note the replacement if statement doesn't surround it's condition with parentheses. 请注意,如果if语句不用括号括起来,则替换该语句。 This isn't a programming language and they aren't needed. 这不是编程语言,不需要它们。

The count assignment is moved to a concurrent signal assignment. 计数分配移至并发信号分配。 This removes the need of having i_count in the sensitivity list just to update count. 这样就无需在灵敏度列表中仅具有i_count即可更新计数。

Throw in a testbench to complete a Miminal Complete and Verifiable Example : 放入测试台以完成一个Miminal完整且可验证的示例

library ieee;
use ieee.std_logic_1164.all;

entity counter_tb is
end entity;

architecture foo of counter_tb is
    signal enable:  std_logic := '0';
    signal clk:     std_logic := '0';
    signal count:   integer range 0 to 255;
begin
DUT:
    entity work.counter
        port map (
            enable => enable,
            clk => clk,
            count => count
        );
CLOCK:
    process
    begin
        wait for 5 ns;  -- 1/2 clock period
        clk <= not clk;
        if now > 540 ns then
            wait;
        end if;
    end process;
STIMULUS:
    process
    begin
        wait for 30 ns;
        enable <= '1';
        wait for 60 ns;
        enable <= '0';
        wait for 30 ns;
        enable <= '1';
        wait;

    end process;
end architecture;

And that gives: 这给出了:

counter_tb.png

Which shows that the counter doesn't counter when enable is '0' nor does enable = '0' reset the value of i_count. 这表明当enable为0时计数器不计数,enable = 0也不会重置i_count的值。

The Quartus II Handbook Volume 1 Design and Synthesis doesn't give an example using a clock edge and an enable without an asynchronous clear or load signal. Quartus II手册第1卷“设计和综合”没有给出使用时钟沿和没有异步清除或加载信号的使能的示例。

The secret here is anything inside the if statement condition specified using a clock edge will be synchronous to the clock. 这里的秘密是使用时钟沿指定的if语句条件内的任何内容都将与时钟同步。 Any condition outside will be asynchronous. 外部的任何条件都是异步的。

The form of synthesis eligible sequential logic is derived from the now withdrawn IEEE Std 1076.6-2004 IEEE Standard for VHDL Register Transfer Level (RTL) Synthesis. 符合合成要求的顺序逻辑的形式来自现已撤销的IEEE Std 1076.6-2004 VHDL寄存器传输级别(RTL)合成的IEEE标准。 Using those behavioral descriptions guarantees you can produce hardware through synthesis that matches simulation. 使用这些行为描述可以保证您可以通过与仿真匹配的综合来生产硬件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM