2012-06-18 141 views
3

我試圖在VGA控制器中使用50MHz時鐘降至25.175MHz。我已經有了一個時鐘分頻器,但是無論何時當前時鐘速度和所需時鐘速度的分頻不是整數,都無法減慢時鐘速度。 I.E. 50000000/25175000~1.98。時鐘分頻器編譯並運行,但如果除法是十進制數,則不輸出。這裏是我的代碼:具有小數點的VHDL時鐘分頻器

LIBRARY IEEE; 
    USE IEEE.STD_LOGIC_1164.ALL; 

    ENTITY Clockdiv IS PORT (
     Clkin: IN STD_LOGIC; 
     Clk: OUT STD_LOGIC); 
    END Clockdiv; 

    ARCHITECTURE Behavior OF Clockdiv IS 
     CONSTANT max: INTEGER := 50000000/25175000; 
     CONSTANT half: INTEGER := max/2; 
     SIGNAL count: INTEGER RANGE 0 TO max; 
    BEGIN 
     PROCESS 
     BEGIN 
      WAIT UNTIL Clkin'EVENT and Clkin = '1'; 

      IF count < max THEN 
       count <= count + 1; 
      ELSE 
       count <= 0; 
      END IF; 

      IF count < half THEN 
       Clk <= '0'; 
      ELSE 
       Clk <= '1'; 
      END IF; 
     END PROCESS; 
    END Behavior; 

我搜索的谷歌,發現使用REAL數據類型將允許您使用小數,但是當我改變了我使用的REAL變量中,Quartus給我的錯誤:Error (10414): VHDL Unsupported Feature error at Clockdiv.vhd(12): cannot synthesize non-constant real objects or values

然後,如果我將「count」更改爲CONSTANT類型,則會顯示錯誤:Error (10477): VHDL error at Clockdiv.vhd(18): name "count" must represent signal

有沒有人知道我可以如何減慢時鐘到25.175MHz?另外,是否有人知道如何減慢時鐘速度,以便編譯器對得到的除法是十進制值感到滿意?

感謝

+0

你在做什麼板子?它可能帶有一個數字時鐘管理器(DCM),它可以提供更好的分割結果和更簡單的實現。我知道Xilinx的Spartan 3a主板有他們 –

+0

我正在使用Altera DE1主板。該電路板上的FPGA有4個PLL,但據我所知,它沒有Paul Seeb提到的數字時鐘管理器。所以,我想我的下一個問題是,我如何利用Quartus中的PLL作爲時鐘分頻器? –

+0

如果你有PLL,只要硬件可以達到所需的頻率,就可以製作更高/更低頻率的時鐘。我認爲大多數DCM都是這樣做的。例如,通過將時鐘與90度相移時鐘信號異或來實現時鐘速度翻倍 –

回答

4

雷亞爾,在一般情況,不綜合的,所以你需要拿出一個整數基礎的解決方案。

這個比例相當棘手,因爲它幾乎是2:1,但並不完全。大多數基於邊緣的時鐘分頻器電路只能在原始時鐘的一個邊沿上工作,因此可以將其除以的最小比率爲2.在這種情況下,您必須在時鐘的兩個邊沿上工作。

一旦你得到了,你需要有一個計數器,你的比率分母遞增,並且它是在分子之上,然後輸出一個時鐘邊緣。

PROCESS 
    BEGIN 
     WAIT UNTIL Clkin'EVENT; 

     IF count < max THEN 
      count <= count + DENOMINATOR; 
     ELSE 
      count <= 0; 
     END IF; 

     IF count > NOMINATOR THEN 
      Clk <= ~Clk; 
     END IF; 
    END PROCESS; 

對於這個比例,我認爲你可以代表它的最小方式是2000/1007。

這樣做的麻煩是,你會得到一個基本上25MHz的時鐘,但偶爾(每個2000/7迭代)你會得到一個額外的優勢。它不會是25.175MHz的時鐘。沒有PLL,從50MHz獲得25.175MHz是不可能的。

2

我寫了大量的VGA控制器,只使用25 MHz的時鐘從來沒有太多的問題。如果您絕對想要更近一些,那麼您的FPGA可能有某種時鐘管理器(我只熟悉Xilinx器件),這將允許您通過倍增和分頻輸入時鐘來合成輸出時鐘。

另外,在這種情況下,使用派生/門控時鐘(可直接在進程中設置值的時鐘)可能適用於您,但會導致很多難以調試的問題。更好的解決方案是生成時鐘使能,然後在同一個(快速)時鐘上運行所有內容。

最後一件事情,雖然它可能是一個首選樣式的問題,但我通常使用時鐘進程語句而不是WAIT語句(如下圖所示,具有上升沿觸發,同步復位和時鐘使能)。我發現閱讀和理解更加清晰,並且不太可能編寫諸如wait for 10ns;之類的不可合成的構建體,或者具有多個WAIT的陳述。

process(clk) 
begin 
    if(rising_edge(clk)) then 
     if(sync_reset = '1') then 
      --Reset logic 
     elsif(clk_enable = '1') then 
      --Actual functionality 
     end if; 
    end if; 
end process; 
+0

等待語句是絕對可綜合的。有些情況下合成器不能實現你所要求的(例如,你推斷寄存器對兩邊都敏感,這對我的答案中的代碼來說是一個問題),但是OP的使用很好工具(Synopsys Design-Compiler for one)。 –

+0

夠公平的,我調整了我的答案。在我看到它被使用的90%的案例中,我可能會受到這種影響,人們一直在問爲什麼他們「等待xxx ns;'代碼不能被合成;」) – sonicwave

+0

Ahhh同意了。 '等待xxx ns;'沒有被合成的希望。 –