2013-06-25 46 views
0

在下面的代码下面的错误发生:如何比较VHDL中的整数?我的错误是什么?

错误(10821):在ClockGen.vhd HDL错误(33):不能推断注册“CONT [0]”,因为它的性能不符合任何支持的寄存器模型

我试着用signed和unsigned变量来做比较,但没有奏效。

LIBRARY IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.STD_LOGIC_ARITH.ALL; 

ENTITY ClockGen IS 

GENERIC 
(Ratio : INTEGER RANGE 0 TO 100 := 10); 

PORT 
(clk : IN STD_LOGIC; 
reset : IN STD_LOGIC; 
clk_en : OUT STD_LOGIC); 

END ENTITY ClockGen; 

ARCHITECTURE Behavior OF ClockGen IS 
SIGNAL cont : INTEGER RANGE 0 TO 100 :=0; 

BEGIN 
--STATEMENTS 
Counting : PROCESS (clk, reset) 
BEGIN 
IF reset='1' 
    THEN 
    cont <= 0; clk_en <= '0'; 

ELSIF RISING_EDGE(clk) 
    THEN 
    cont <= cont + 1; 
END IF; 

IF cont=Ratio AND clk='1' --THE ERROR OCCURS IN THIS LINE 
    THEN 
    clk_en <= '1'; 
ELSIF cont=Ratio AND clk='0' 
    THEN 
    clk_en <= '0'; 
    cont<=0; 
END IF; 

END PROCESS Counting; 

END ARCHITECTURE Behavior; 
+0

我不是VHDL专家,但考虑到以下错误信息,我从你的程序有:'节点时序逻辑似乎是由多个clocks.'控制。我不认为实际问题是整数比较,而是周围的结构。 – phineas

回答

1

画出你真正想要的图片。

在您的代码中,您正在创建一个与复位信号异步复位的触发器。但是,您在时钟之后添加了一个附加条件,并且它也会影响输出连续性。实际上,当clk ='1'和cont = Ratio时,它也会异步复位触发器。我敢打赌,这不是你想要的。通常一个寄存器只有一个异步复位,它连接到全局复位线,而不是逻辑(逻辑可以干扰并产生复位)。另外,尽管1076.6-2004(VHDL RTL综合编码标准)规定了更简单的类似的异步复位编码风格,但它还不被很好地支持。这可能是为什么@phineas看到他的代码版本工作,而你没有。

你想用clk_en来完成什么?您是否打算仅在1/2时钟周期内有效,并且从不在Clk的上升沿有效?

如果CLK_EN是确定为一个时钟宽,然后尝试以下方法:

Counting1 : PROCESS (clk, reset) 
BEGIN 
IF reset='1' THEN 
    cont <= 0; 
    clk_en <= '0'; 

ELSIF RISING_EDGE(clk) THEN 
    if cont/=Ratio then 
     cont <= cont + 1; 
     clk_en <= '0'; 
    else 
     cout <= 0 ; 
     clk_en <= '1'; 
    end if; 
END IF; 

结束处理;

如果你真的需要clk_en作为半时钟宽,那么你有一些工作要做。在我扔掉额外的东西后,你为clk_en编码的内容类似于:

ClkEnProc : PROCESS (clk) 
BEGIN 
IF clk='0' THEN 
    clk_en <= '0'; 

ELSIF RISING_EDGE(clk) THEN 
    if cont=Ratio then 
     clk_en <= '1'; 
    end if; 
END IF; 

end process;

如果您发现支持该功能的综合工具,我会感到惊讶。您可能需要使用上升沿触发器和下降沿触发器来组成时钟使能。使用来自counting1进程的clk_en,请尝试以下操作:

ClkEnNegProc : PROCESS (clk) 
BEGIN 
IF FALLING_EDGE(clk) THEN 
    clk_en_neg <= clk_en; 
END IF; 
end process; 

clk_en_half <= clk_en and not clk_en_neg ; 
1

您的进程检测时钟边沿,然后检测时钟级别。这不符合可综合VHDL代码的标准。

试试这个骨架为您的流程:

name : process (clk, rst) is 
begin 
    if rst = '1' then 
     -- stuff here for resetting everything 
    elsif rising_edge(clk) then 
     -- more stuff here for doing useful things 
    end if; 
end process name; 
0

谢谢大家的帮助!有了我,我管理了它。用“IF”语句重组代码。结果如下:

LIBRARY IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.STD_LOGIC_ARITH.ALL; 

ENTITY ClockGen IS 

GENERIC 
(Ratio : INTEGER RANGE 0 TO 100 := 5); 

PORT 
(clk : IN STD_LOGIC; 
reset : IN STD_LOGIC; 
clk_en : OUT STD_LOGIC); 

END ENTITY ClockGen; 

ARCHITECTURE Behavior OF ClockGen IS 
SIGNAL cont : INTEGER RANGE 0 TO 100 :=1; 
SIGNAL IRatio : INTEGER RANGE 0 TO 100 :=0; 

BEGIN 

Counting : PROCESS (clk, reset) 
BEGIN 
IRatio <= Ratio; 

IF reset='0' 
THEN 
cont <= 1; 

ELSIF RISING_EDGE(clk) 
THEN 
cont <= cont + 1; 
    IF cont=IRatio 
    THEN 
    clk_en <= '1'; 
    cont<=1; 
    ELSE clk_en<='0'; 
    END IF; 
END IF; 

END PROCESS Counting; 

END ARCHITECTURE Behavior; 
+0

看起来比原来好多了,几乎符合典型的寄存器描述。 2件事:为什么信号IRatio?您可以直接比较Cont与比率。第二,如果你确实想使用IRatio,它应该不在这个过程之中(或者在它自己的组合过程中)。在一个描述寄存器的钟控过程中,'if(reset ='0')然后... elsif(rising_edge(clk))然后... end if;'应该包围所有内容,除此之外没有别的东西。本身,但一个风格的改进。 – zennehoy

+0

您可以删除'USE IEEE.STD_LOGIC_ARITH.ALL; - 它是非标准的,你使用的是整数,所以它是不必要的 –