2011-06-07 64 views
1

主編:在VHDL中創建一個分頻器

在閱讀Will Dean的評論後問題解決了。原來的問題是下面的修改後的代碼:

-- REVISED CODE (NOW WORKS) 
LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 

entity CLOCK_DIVIDER is 
    port(
     reset : in std_logic; 
     clk : in std_logic; 
     half_clk : out std_logic 
     ); 
end CLOCK_DIVIDER; 


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is 
signal tick : std_logic; 

begin 

    process(clk, reset) 
    begin 
     if reset = '1' then 
      tick <= '0'; 
     elsif clk = '1' and clk'EVENT then 
      if tick = '0' then 
       tick <= '1'; 
      elsif tick = '1' then 
       tick <= '0'; 
      end if; 
     end if; 
    end process; 

    process(tick) 
    begin 
     half_clk <= tick; 
    end process 

end CLOCK_DIVIDER; 

的修改後的代碼所合成的邏輯塊是單個異步復位DFF即需要half_clk作爲輸出和反相half_clk作爲輸入,這意味着值的half_clk改變上每一個clk的上升沿。

謝謝,請問院長:)

==== ==== ==== ==== ====

下面

原題:

==== ==== ==== ==== ====

我需要一個簡單的時鐘分頻器(只需除以二),而不是使用模板,我想我會嘗試寫一個自己繼續訓練。

不幸的是,合成的邏輯塊似乎不起作用 - 我按順序呈現邏輯塊和代碼(我真的認爲應該工作)。

logic block http://img808.imageshack.us/img808/3333/unledly.png

什麼我真的不知道是魔鬼是什麼了「嘀」 DFF - 它顯然需要它的輸入來自復-選擇是...是啊。

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 

entity CLOCK_DIVIDER is 
    port(
     reset : in std_logic; 
     clk : in std_logic; 
     half_clk : out std_logic 
     ); 
end CLOCK_DIVIDER; 


architecture CLOCK_DIVIDER of CLOCK_DIVIDER is 
signal tick : std_logic; 

begin 
    process(clk, reset) 
    begin 
     if reset = '1' then 
      half_clk <= '0'; 
      tick <= '0'; 
     elsif clk = '1' and clk'EVENT then 
      if tick = '0' then 
       half_clk <= '0'; 
       tick <= '1'; 
      elsif tick = '1' then 
       half_clk <= '1'; 
       tick <= '0'; 
      end if; 
     end if; 
    end process; 
end CLOCK_DIVIDER; 

我敢肯定,在代碼中的錯誤是明顯的,但我一直在盯着自己瞎試圖找到它。

+3

我是一個Verilog的人,而不是VHDL,但我不明白爲什麼你需要兩個寄存器做除法兩個。 'tick'的(延遲)反轉除外'half_clock'是什麼? – 2011-06-07 07:47:30

+0

我不需要兩個寄存器,我不知道它爲什麼推斷兩個寄存器。 half_clck是邏輯塊的輸出,而tick是內部信號 - 如果我打勾輸出,它不能讀取它,如果我將half_clk作爲內部信號,我不能輸出它。但是:它現在可以工作了 - 記住你所說的話,我從if語句中刪除了half_clk,並創建了一個單獨的進程,它將tick的值始終分配給half_clk,現在它可以工作。 – medivh 2011-06-07 08:29:43

回答

1

根據修改後的代碼,我提供這個修改架構:

-- REVISED CODE (NOW WORKS) and simplified and synthesisable 
architecture CLOCK_DIVIDER of CLOCK_DIVIDER is 
    signal tick : std_logic; 
begin 
    process(clk, reset) 
    begin 
     if reset = '1' then 
      tick <= '0'; 
     elsif rising_edge(clk) then -- use of rising_edge() is the correct idiom these days 
      tick <= not tick; 
     end if; 
    end process; 

    half_clk <= tick; 
end CLOCK_DIVIDER; 

我已經刪除了這個過程,並替換爲併發作業:

process(tick) 
    begin 
     half_clk <= tick; 
    end process 

因爲這是要求的一個觸發器在tick的兩個邊沿計時。

這將看起來實現你想要的波形方式擺動你想要的方式,但不會合成。它還會爲輸出增加一個額外的delta延遲,如果您將其用作「下路」的時鐘,則可能會導致問題,也可能不會造成問題。正如其他人所評論的,在大多數體系結構中,這不是一個好計劃(但對於某些人來說這是「正確的方式」)。

3

如果halfclk是用作使能,而不是一個真正的時鐘,忽略此建議...

如果這是一個FPGA目標和「half_clk」實在是被用作時鐘(例如去DFF上的時鐘引腳,而不是啓用引腳)... 不要這樣做。使用通用FPGA邏輯/ fabic創建派生時鐘將導致構建工具出現問題,最終可能導致構建失敗(不會滿足時序),或者構建的行爲不如預期,因爲約束未正確傳遞到所有時鐘網絡。

取而代之的是使用內置於FPGA架構中的時鐘管理模塊,特別是用於此目的。在賽靈思部分的世界中,這些被稱爲數字時鐘管理器(DCM)或混合模式時鐘管理器(MMCM)。我不確定等效的Altera組件是什麼。閱讀文檔以確定您的應用程序的最佳用途。

+0

您會驚訝地發現,這實際上是用戶指南爲我正在使用的CPLD所推薦的方式。 clk是一個外部晶振,half_clk將被路由到一個內置的全局時鐘網絡。 – medivh 2011-06-07 13:23:13

+0

好的,太好了。想要向你和其他人指出,我發現這樣的事情發生了很多(當不推薦這種做法時),並且會導致很多痛苦。 – Josh 2011-06-07 13:52:13

0

您確定您在啓動時重置嗎?你定義tick的條件的方式是,如果tick不爲零或一(即:可以是U,Z,X等),則不會發生。

我通常建議覆蓋所有的情況下與你的條件表達式,即:

 if tick = '0' then 
      half_clk <= '0'; 
      tick <= '1'; 
     else 
      half_clk <= '1'; 
      tick <= '0'; 
     end if; 

 if tick = '0' then 
      half_clk <= '0'; 
      tick <= '1'; 
     elsif tick = '1' then 
      half_clk <= '1'; 
      tick <= '0'; 
     else 
      -- Throw error or something here 
     end if; 
+0

使用elsif是如此根深蒂固,我甚至沒有考慮到這一點,但它的聲音建議 - 我絕對希望它初始化,即使剔有一個奇怪的值開始。 – medivh 2011-06-07 13:24:25

0

簡單的計數器的伎倆(正確的方法當然是DCM):

signal cnt : std_logic_vector(3 downto 0); 

... 

clk_div_2 <= cnt(0); 
clk_div_4 <= cnt(1); 
clk_div_8 <= cnt(2); 
clk_div_16 <= cnt(3); 

... 

process(clk) 
if clk'event and clk = '1' then 
    cnt <= cnt + 1; 
end if; 
end process;