2013-06-25 64 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; - 它是非標準的,你使用的是整數,所以它是不必要的 –