【问题标题】:ERROR 10818 - Can't infer register because it does not hold its value outside the clock edge错误 10818 - 无法推断寄存器,因为它没有在时钟沿之外保持其值
【发布时间】:2018-01-23 18:35:21
【问题描述】:

我正在编写修改后的 Gauss-Jordan 消除器的代码,但出现错误:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;
USE IEEE.STD_LOGIC_ARITH.ALL;

PACKAGE matriz IS
    TYPE matrix IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(1 TO 7);
    TYPE vector IS ARRAY (NATURAL RANGE <>) OF INTEGER;
END matriz;

USE work.matriz.all;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;
USE IEEE.STD_LOGIC_ARITH.ALL;

ENTITY bloco2 IS
    GENERIC (m: integer:= 4;
                n: integer:= 7;
                k: integer:= 3);
    PORT (clk,rst: IN STD_LOGIC;
            s: IN vector(1 TO n);
            G: IN matrix(1 TO m);
            Gr0, Gr: OUT matrix(1 TO m));
END bloco2;

ARCHITECTURE bloco2 OF bloco2 IS

SIGNAL Grt: matrix(1 TO m):= (OTHERS=>(OTHERS=>'0'));
SIGNAL Gr0t: matrix(1 TO m):= (OTHERS =>(OTHERS=>'0'));
SIGNAL st: vector(1 TO n):= (OTHERS=>0);

SIGNAL temp1: STD_LOGIC_VECTOR(1 TO n):= (OTHERS=>'0');
SIGNAL temp2: STD_LOGIC_VECTOR(1 TO n):= (OTHERS=>'0');
SIGNAL verify: STD_LOGIC:= '0';

BEGIN

    PROCESS(clk, rst, G, Grt, Gr0t, st, s, verify, temp1, temp2)
    VARIABLE L: INTEGER:= 1;
    VARIABLE c: INTEGER:= 1;
    VARIABLE count: INTEGER:= 0;
    BEGIN

        Grt<=G;
        st<=s;

        IF rst='0' THEN
            IF (rising_edge(clk))THEN
                IF count <= 3 THEN
                    IF Grt(L)(st(c))='1' THEN
                                Gr0t(L)(st(c))<='1';
                                FOR i IN 1 TO m LOOP
                                    verify <= Grt(i)(st(c));
                                    FOR j IN 1 TO n LOOP
                                        IF ((i/=L) and (verify/='0')) THEN
                                            Grt(i)(j)<= Grt(L)(j) xor Grt(i)(j);
                                        END IF;
                                    END LOOP;
                                END LOOP;
                                count:=count+1;
                                L:=L+1;
                                c:=c+1;
                    END IF;

                    IF Grt(L)(st(c))='0' THEN
                        FOR i IN 1 TO m LOOP
                                IF i > L THEN
                                    IF Grt(i)(st(c)) ='1' THEN
                                     temp1<= Grt(L)(1 TO n);
                                     temp2<= Grt(i)(1 TO n);
                                     Grt(i)(1 TO n)<= temp1;
                                     Grt(L)(1 TO n)<= temp2;
                                     exit;
                                    END IF;
                                END IF;
                        END LOOP;   

                        IF Grt(L)(st(c)) /='1' THEN
                            c:=c+1;
                        END IF;
                    END IF;

                END IF;
            END IF;

        END IF;

        IF rst='1' THEN
            Gr0t <= (OTHERS=>(OTHERS=>'0'));
            Grt <= (OTHERS => (OTHERS =>'0'));

        END IF;
    Gr<=Grt;
    Gr0<=Gr0t;
END PROCESS;
END bloco2;

错误 (10818):无法在 bloco2.vhd(50) 处推断“Grt[4][7]”的寄存器,因为它没有在时钟沿之外保持其值。

P.S.:矩阵 Grt 的每个位置都会发生这种情况。

有人能帮我理解这里发生了什么吗?
PS:在我的代码中,我只是使用IF 结构,没有任何类型的ELSEELSIF ,因为我读过这可能是问题的原因,但在我的情况下,这个提示不起作用。

【问题讨论】:

  • 可能最后单独的异步复位使合成器感到困惑,毕竟它是时钟进程之外的分配。在同一个 if/then/elsit 语句中使用组合 reset 和rising_edge(clock) 的正常形式之一。 (顺便说一句,那个“小费”是垃圾)
  • 请阅读供应商的 HDL 开发人员指南,了解有关如何描述同步和异步电路的正确 VHDL 代码模式。

标签: compiler-errors vhdl fpga intel-fpga quartus


【解决方案1】:

需要了解的一些基本知识。

  • 信号仅在进程挂起时更新。这将在过程敏感度列表(您的情况)或等待语句(通常在测试台中)。
  • 综合工具只能理解非常有限的语言子集,并且是特别挑剔的 WRT 触发器。
  • 如果您的流程结构合理,便于使用综合工具进行移植,那么您只需要灵敏度列表中的时钟和异步控件(以及异步加载的数据,但不需要)。

让我们以 1076.6-1999 的方式重新编写您的代码。

由于您的进程没有等待语句,所有代码都在同一个增量周期内执行。在进程的时钟/复位部分之外完成的任何信号分配都可以同时完成。因此,我们将在设计的架构代码区域(而不是在进程中)编写以下代码:

Grt<=G;
st<=s;
Gr<=Grt;
Gr0<=Gr0t;

您编码的重置是异步的。一种可移植模板是:

PROCESS(clk, rst)
BEGIN
    IF rst='1' THEN
      . . . 

    elsif (rising_edge(clk))THEN
      .  .  .

    END IF;
END PROCESS;

您的代码更接近下面的模板。我喜欢的一个,但它的便携性稍差。请注意,在此分支中,时钟分支不是以复位为条件的,并且复位分支中的任何分配都只会覆盖时钟分支中的设置。我建议先从上面的开始,让它在模拟和综合中正常工作,然后如果你真的想再切换回来。

PROCESS(clk, rst)
BEGIN
    if (rising_edge(clk))THEN
      .  .  .

    END IF;
    IF rst='1' THEN
      . . . 
    END IF;
END PROCESS;

以下是您的代码,其中排除了并发信号。我没有对其他可能存在问题的问题进行任何更改。

PROCESS(clk, rst)
VARIABLE L: INTEGER:= 1;
VARIABLE c: INTEGER:= 1;
VARIABLE count: INTEGER:= 0;
BEGIN
    IF rst='1' THEN
        Gr0t <= (OTHERS=>(OTHERS=>'0'));
        Grt <= (OTHERS => (OTHERS =>'0'));

    elsif (rising_edge(clk))THEN
            IF count <= 3 THEN
                IF Grt(L)(st(c))='1' THEN
                            Gr0t(L)(st(c))<='1';
                            FOR i IN 1 TO m LOOP
                                verify <= Grt(i)(st(c));
                                FOR j IN 1 TO n LOOP
                                    IF ((i/=L) and (verify/='0')) THEN
                                        Grt(i)(j)<= Grt(L)(j) xor Grt(i)(j);
                                    END IF;
                                END LOOP;
                            END LOOP;
                            count:=count+1;
                            L:=L+1;
                            c:=c+1;
                END IF;

                IF Grt(L)(st(c))='0' THEN
                    FOR i IN 1 TO m LOOP
                            IF i > L THEN
                                IF Grt(i)(st(c)) ='1' THEN
                                 temp1<= Grt(L)(1 TO n);
                                 temp2<= Grt(i)(1 TO n);
                                 Grt(i)(1 TO n)<= temp1;
                                 Grt(L)(1 TO n)<= temp2;
                                 exit;
                                END IF;
                            END IF;
                    END LOOP;   

                    IF Grt(L)(st(c)) /='1' THEN
                        c:=c+1;
                    END IF;
                END IF;
            END IF;
    END IF;
END PROCESS;

需要考虑的一些事情:

  • Grt0 只分配在一个地方。复位后会累积 1。
  • 您对 Temp1 和 Temp2 的意图是什么?信号不会立即更新,因此它们不会交换值。如果您想要这种行为,请使用变量或删除 Temp1 和 Temp2 并直接进行赋值。
  • 您验证的意图是什么?根据它的用法,它可能也需要是一个变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多