0

在以下代码中发生以下错误:

错误 (10821):ClockGen.vhd(33) 处的 HDL 错误:无法推断“cont [0]”的寄存器,因为它的行为与任何支持的寄存器模型都不匹配

我尝试使用有符号和无符号变量进行比较,但没有奏效。

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

3 回答 3

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;
于 2013-06-26T15:03:02.657 回答
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;

结束进程;

如果您找到支持该功能的综合工具,我会感到惊讶。您可能需要同时使用上升沿触发器和下降沿触发器来组合时钟使能。使用来自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 ; 
于 2013-06-26T00:33:57.850 回答
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;
于 2013-06-26T21:46:05.247 回答