编辑 - 无法推断注册,因为它的行为与任何支持的寄存器模型VHDL

时间:2017-04-16 17:43:22

标签: vhdl fpga intel-fpga

这是我提出的另一个问题的分支。我将更深入地解释我正在尝试做什么以及它不喜欢什么。这是一个学校项目,不需要遵循标准。

我正在尝试制作SIMON游戏。现在,我要做的是使用一个开关盒用于电平,每个电平应该更快(因此不同的分频器)。第一级应该是第一级,LED的模式应该点亮并消失。在我放入开关盒之前,第一级是单独的(没有第二级的东西)并且它点亮并且像它应该消失。我还使用compare = 0来比较输出和输入。 (用户应该在他们看到的灯光图案中翻转开关)。这在第一级别本身时起作用,但现在它处于切换的情况下,它不像compare。我不知道如何解决这个问题以便将输出与输入进行比较。

我得到的错误与以前类似:

错误(10821):FP.vhd(75)处的HDL错误:无法推断注册"比较"因为它的行为与任何支持的寄存器模型都不匹配

错误(10821):FP.vhd(75)处的HDL错误:无法推断注册" count [0]"因为它的行为与任何支持的寄存器模型都不匹配

错误(10821):FP.vhd(75)处的HDL错误:无法推断注册" count [1]"因为它的行为与任何支持的寄存器模型都不匹配

错误(10821):FP.vhd(75)处的HDL错误:无法推断注册" count [2]"因为它的行为与任何支持的寄存器模型都不匹配

错误(10822):FP.vhd(80)处的HDL错误:无法在此时钟边沿上为分配实现寄存器

错误(10822):FP.vhd(102)处的HDL错误:无法在此时钟边沿上为分配实现寄存器

错误(12153):无法详细说明顶级用户层次结构

我也明白它不喜欢rising_edge(toggle),但我需要这样才能使LED模式亮起并消失。

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

entity FP is
    port(
    clk, reset : in std_logic;
    QF : out std_logic_vector (3 downto 0);
    checkbtn : in std_logic;
    Switch : in std_logic_vector(3 downto 0);
    sel : in std_logic_vector (1 downto 0);
    score : out std_logic_vector (6 downto 0)

    );
end FP;

architecture behavior of FP is

signal time_count: integer:=0;
signal toggle : std_logic;
signal toggle1 : std_logic;
signal count : std_logic_vector (2 downto 0);
signal seg : std_logic_vector (3 downto 0);
signal compare : integer range 0 to 1:=0;
type STATE_TYPE is (level1, level2);
signal level : STATE_TYPE;    
--signal input : std_logic_vector (3 downto 0);
--signal sev : std_logic_vector (6 downto 0);
begin

process (clk, reset, sel)
    begin
        if (reset = '0') then
            time_count <= 0;
            toggle <= '0';
        elsif rising_edge (clk) then
            case sel is
            when "00" =>
                if (time_count = 1249999) then
                        toggle <= not toggle;
                        time_count <= 0;
                    else
                        time_count <= time_count+1;
                    end if;            
            when "01" =>
                if (time_count = 2499999) then
                    toggle1 <= not toggle1;
                    time_count <= 0;
                else
                    time_count <= time_count+1;
                    end if;
            when "10" =>
                if (time_count = 4999999) then
                    toggle <= not toggle;
                    time_count <= 0;
                else
                    time_count <= time_count+1;
                    end if;
            when "11" =>
                if (time_count = 12499999) then
                    toggle <= not toggle;
                    time_count <= 0;
                else
                    time_count <= time_count+1;
                end if;
            end case;
        end if;
    end process;



Process (toggle, compare, switch)
    begin                

    case level is
    when level1 =>
        if sel = "00" then
            count <= "001"; 
            seg <= "1000";
        elsif (rising_edge (toggle)) then
            count <= "001";
            compare <= 0;
            if (count = "001") then
                count <= "000";
            else
            count <= "000";
            end if;
        end if;

        if (switch = "1000") and (compare = 0) and (checkbtn <= '0') then
            score <= "1111001";
            level <= level2;
        else
            score <= "1000000";
            level <= level1;
        end if;

    when level2 =>
        if sel = "01" then
            count <= "010";
            seg <= "0100";
        elsif (rising_edge (toggle1)) then
            count <= "010";
            compare <= 1;
            if (count = "010") then
                count <= "000";
            else
            count <= "000";
            end if;
        end if;

        if (switch = "0100") and (compare = 1) and (checkbtn <= '0') then
            score <= "0100100";
        else
            score <= "1000000";
            level <= level1;
        end if;
    end case;


    case count is
        when "000"=>seg<="0000";
        when "001"=>seg<="1000";
        when "010"=>seg<="0100";
        when "011"=>seg<="0110";
        when "100"=>seg<="0011";
        when others=>seg<="0000";
    end case;    
end process;


QF <= seg;
end behavior;

提前再次感谢!

1 个答案:

答案 0 :(得分:0)

嗯...很难说出错是什么,因为这个状态机是以错误的方式编写的。您应该在VHDL中查找有关正确建模FSM的参考资料。一个很好的例子是here。 如果您使用Quartus,您还可以查找Altera关于如何专门为其编译器建模FSM的描述。

我现在给你两个建议。首先是你不应该(或者甚至你不能使用)是两个

if rising_edge (clk)

检查一个过程。如果您的进程应该在时钟边缘敏感,请在开头写一次。

第二件事是,如果你想用一个具有同步复位的进程建模FSM,那么只需将clk放在灵敏度列表上。

在问题和代码编辑后编辑:

好的,现在好多了。但另外几件事:

  1. 您的FSM仍然不是应该的。再看一下上面给出的源代码中的示例,并将其编辑为像那里一样,或者将其作为一个进程FSM,就像在link中的示例一样。
  2. 有意!很重要。在我对你的代码做出适当的修改之前,我无法发现一些明显的错误。这导致我......
  3. 查看这些地方,在那里指定要计数的值,特别是if语句。无论如何,你指定了相同的&#34; 000&#34;。
  4. 与另一个信号类似的故事 - seg。您在流程中为其分配了一些值,然后在此流程结束时会有一个case语句,您可以在其中为其分配一些其他值,使之前的赋值无关紧要。
  5. 在进程中只使用rising_edge一次,仅用于时钟,并且仅在进程的最开始时,或者在第一个进程中使用异步重置的方式。在第二个过程中,你做了所有这三件事。
  6. 在使用rising_edge的顺序过程中,就像第一个一样,你不必为灵敏度列出超过时钟的任何内容,如果它是异步的,则重置,就像你的情况一样。
  7. 第二个过程中的敏感度列表。它是并行过程,因此您应该放置信号,检查进程,并在其外部进行更改。比较并非如此。但应该有信号:level,sel和toggle1。
  8. 由于我还不确定你想要达到什么目的,我不会告诉你究竟要做什么。根据以上几点修复你的代码,然后它可能会起作用。