2013-09-22 89 views
0

VHDL,在生成的語句VHDL,使用功能爲生成聲明

我有一個應該被實例化約8000倍的成分,我用-產生一些常數值的幫助下減少語句中使用函數代碼量,但我不得不聲明一個用於組件連接參數化的函數。

我的功能看起來是這樣的:

function dim1_calc (
     cmp_index : integer; 
     prt_index : integer 
    ) return integer is 
     variable updw : integer := 0; 
     variable shft_v : integer := 0; 
     variable result : integer := 0; 
    begin 

     if (cmp_index < max_up) then 
     updw := 1; 
     else 
     updw := 2; 
     end if; 

     case prt_index is 
     when 1 => 
      shft_v := cnst_rom(updw)(1) + (i-1); 
     when 2 => 
      shft_v := cnst_rom(updw)(2) + (i); 
      -- 
      -- 
      -- 
     when 32 => 
      shft_v := cnst_rom(updw)(32) + (i); 
     when others => 
      shft_v := 0; 
     end case; 

     if (updw = 1) then 
     if (shft_v = min_up & ((prt_index mod 2) = 0)) then 
      result <= max_up; 
     elsif (shft_v = max_up & ((prt_index mod 2) = 1)) then 
      result <= min_up; 
     elsif (shft_v < max_up) then 
      result <= shft_v; 
     else 
      result <= shft_v - max_up; 
     end if; 
     else 
     --something like first condition statements... 
     -- 
     -- 
     end if; 


     return result; 

    end function; 

和我的代碼部分使用此函數加上一些相關的部分看起來像這樣:

--these type definitions are in my package 
     type  nx_bits_at is array (natural range <>) of std_logic_vector (bits-1 downto 0); 
     type  mxn_bits_at is array (natural range <>) of nx_bits_at; 
    -- 
    -- 
    -- 
     component pn_cmpn is 
     port(
      clk  : in std_logic; 
      bn_to_pn : in nx_bits_at(1 to row_wght); 
      pn_to_bn : out nx_bits_at(1 to row_wght) 
     ); 
     end component; 
     -- 
     -- 
     -- 
     signal v2c : mxn_bits_at(1 to bn_num)(1 to col_wght); 
     signal c2v : mxn_bits_at(1 to pn_num)(1 to row_wght); 
     -- 
     -- 
     -- 
     gen_pn : for i in (1 to pn_num) generate 

     ins_pn : pn_cmpn port map (
     clk   => clk, 
     bn_to_pn(1) => b2p (dim1_calc(i, 1)) (dim2_calc(i, 1)), 
     bn_to_pn(2) => b2p (dim1_calc(i, 2)) (dim2_calc(i, 2)), 
     . 
     . 
     . 
     bn_to_pn(32) => b2p (dim1_calc(i, 32)) (dim2_calc(i, 32)), 
     pn_to_bn  => p2b (i) 
     ); 

     end generate; 

我知道,使用過多的順序語句一起通常是不恰當的,我儘可能避免它們,但在這種情況下,我認爲這個函數不會合成一些真實的硬件,合成器只是計算輸出值,並將它放入相應的實例中該組件。我對嗎?或者這種編碼方式導致額外的硬件相比,只有8000實例。我最初使用「0 ...」來定義我的數組的第二維和第三維的範圍,但是由於在基於for-generate語句參數的維度計算函數中進行了混淆,所以我將其替換爲他們與「1到..​​.」。這是好的!編碼風格還是應該避免它?

PS2:有沒有在上面的代碼中的端口映射部分組合到像這樣的方式: (我知道這是強烈的錯,它只是澄清了我想要的東西)

 gen_pn : for i in (1 to pn_num) generate 

     ins_pn : pn_cmpn port map (
     clk   => clk, 

     gen_bn_to_pn : for j in (1 to 32) generate 
      bn_to_pn(j) => b2p (dim1_calc(i, j)) (dim2_calc(i, j)), 
     end generate; 

     pn_to_bn  => p2b (i) 
     ); 

     end generate; 

讓我再舉一個例子 假設我有一個組件實例是這樣的:

ins_test : test_comp port map (
     clk   => clk, 
     test_port(1) => test_sig(2) 
     test_port(2) => test_sig(3) 
     test_port(3) => test_sig(4) 
     ); 

有沒有我可以使用這裏生成的方式?是這樣的:

ins_test : test_comp port map (
     clk   => clk, 
     gen_pn : for i in (1 to 3) generate 
      test_port(i) => test_sig(i+1) 
     end generate; 
     ); 

PS3:是否可以調用VHDL另一個函數裏面的函數嗎?

回答

2

功能可用這種方式。如果遇到問題,我相信他們會在設計或設計工具中考慮細節,而不是基本方法。

一個潛在的問題是該函數引用了一些外部的「事物」,如max_up, i, cnst_rom其聲明不是函數的一部分,也不是參數。這使得它成爲一個「不純的函數」,因爲它涉及到外部狀態,甚至修改它 - 在調用它時有限制(因爲外部狀態可能會改變,結果可能取決於評估順序等)。

如果你可以使它變得純淨,那就這樣做。我有一種感覺max_up, cnst_rom是常數:如果它們不在其他地方使用,請將它們聲明爲函數的本地。而i可能應該是一個參數。

如果這是不可能的,使外部聲明常量,並最好將它們和函數一起打包在一個包中。

這隻會產生你需要的值,只是一個小的,易於理解的,可維護的形式,而不是無限量的硬件。我已經使用了一組複雜的函數來執行浮點運算,然後簡化了範圍縮減和整數四捨五入來初始化查找表,所以基本上這種方法確實有效。

潛在的缺陷:

一些設計工具具有完全有效的VHDL麻煩,如果它的使用稍微非正統的。 Synplicity不能合成某些形式的函數(它會生成硬件),儘管通過OUT參數返回結果的等效過程沒有問題! XST要好得多。

XST解析我的查找表init有一個荒謬的減速,在函數調用次數方面是二次的。但只有當你使用舊的VHDL解析器時(Spartan-3的默認設置)。 Spartan-6使用新的解析器,並且與Modelsim和Isim一樣工作正常(不到一秒鐘,而不是半小時!)。 (在該項目中沒有嘗試過Synplicity)

一些工具反對在端口映射中使用非正統的東西:您可能會在那裏使用函數調用;或者您可能必須通過調用常量來初始化工具錯誤,並在端口映射中使用這些常量。

而且你的補充問題:

PS1)的陣列範圍正確的編碼風格是......不管是什麼讓你的意圖明確。 如果你發現自己精神錯位1,並且感到困惑甚至犯錯,停止!並改進設計。

一些好的數組索引方式:

type colour is (red, green, blue); 
subtype brightness is natural range 0 to 255; 

hue : array (colour) of brightness; 
gamma : array (brightness) of brightness; 
-- here 0 is a legitimate value 
channel : array (1 to 99) of frequency; 

PS2)我覺得你問,如果你能巢生成報表。是。

細節可能很尷尬和困難,但是。

PS3)當然可以!你甚至可以在其他地方聲明函數;消除他們被無意中稱爲某個地方的可能性。它們(不純的函數)可以訪問外部函數(或過程)的執行範圍,從而簡化參數列表。

+0

感謝您的回答。 你對max_up,cnst_rom和我的感覺是對的,我會讓我的函數變得純粹。 我的合成器是XST,我的FPGA是virtex-5,所以它會很好。 關於數組索引樣式:謝謝,這是一種解脫:) 是的,我問的是嵌套的生成語句。但這是一個特例,顯然我沒有解釋清楚。我補充說明了另一個例子。 –

0
Q1 - in this case I assumed that this function won't synthesize into some ... 

這取決於你正在使用哪個合成器。請參閱下面的this相關問題和意見。


Q2 - PS1: Initially I used "0 to..." for defining ranges of the ... 

當然,它的確定。請允許我們在這裏發佈關於編碼風格的建議。 (from this book
定義循環參數規範時,可以使用類型(或子類型)定義,或使用預定義的對象屬性(例如PredefinedObject'range,PredefinedObject'length-1 downto 0)。避免使用離散範圍(例如1到4)。
該規則使得代碼更具可重用性和靈活性,便於維護。


Q3 - PS2: Is there a way that port mapping part in above code combines into ... 

我想這就是爲什麼你問第四個問題。所以請參考下一個答案:)。


Q4 - Is it possible to call a function inside another function in VHDL? 

雖然我不能找到一些這方面的官方參考,答案是肯定的。

PS:編碼規則由合成器工具定義。所以找到答案的最好方法是自己嘗試一下。

+0

感謝您的回答和課程參考。 我的合成器是XST所以幸運的是不會有問題。 我不知道我的最後兩個問題是關聯的!所以請讓我知道如何使用函數來達到我的目的。 關於你的PS:我會記住它,並會更頻繁地做它。 –