[英]VHDL what is more efficient to use : an integer with range or a std_logic_vector
[英]VHDL: Finding out/reporting bit width/length of integer (vs. std_logic_vector)?
假設我需要一個信號來表示從 0 到 5 的數字; 顯然這需要 3 位 std_logic 來表示(即如果 MAXVAL=5,則 bitwidth= { wcalc "floor(logtwo($MAXVAL))+1"
} )。
我知道我可以這樣做:
SIGNAL myLogicVector : STD_LOGIC_VECTOR(2 downto 0) := 5;
使用它我會明確指定一個包含三個 std_logic 'bits' 的數組,並設置初始值; 然后我可以使用 REPORT 打印出長度(在本例中為 3):
report("Bit width of myLogicVector is "& integer'image(myLogicVector'length));
到現在為止還挺好。 但是,假設我使用整數(數字)類型:
SIGNAL myInteger : NATURAL range 0 to 5 := 5;
我猜這里的“編譯器”(“合成器”)會自動推斷它需要 3 位的存儲長度,因為這個整數的范圍是 0 到 5 之間的值。如果是這種情況,我的問題是:有可能以某種方式在報告中打印出這個位寬/長/大小嗎?
當然,訣竅是這樣的:
report("Bit width of myInteger is "& integer'image(myInteger'length));
...將失敗(例如,“ HDLParsers:3389 - 屬性'length 的前綴必須是一個數組對象”),因為據我所知,所有這些屬性,如'length
和'range
僅適用於數組( 理解VHDL 屬性),而整數(自然)不是數組 - 它是一個數字:)( VHDL 向量整數轉換問題)
同樣,我知道我可能會使用 log2( 從最大值計算無符號變量的寬度? ) - 但我想要的只是快速查看(在合成期間)“合成器”有多少“位”分配給最終的綜合設計,因此在最終 FPGA 資源方面大約會使用多少(特別是如果我使用“泛型”以某種方式計算整數的特定最大值)。
好吧,提前感謝您的任何回復,干杯!
編輯:一些上下文:我使用的是 ISE Webpack 9.2; 我正在嘗試使用“通用”變量/常量作為參數,然后使用方程來計算計數器的最大值。 我猜這個計算發生在“編譯”時(在 ISE 中將是“合成”,而不是“實施設計”),因此我希望報告消息發生在這里(實際上我得到了它們,對於 std_logic_vector 正確,在綜合日志中 - 但是,在行為模擬開始時也會出現對我來說相同的報告消息,這很好)。
這些報告消息的目標是確保我的方程是正確的,並且合成器不會嘗試推斷 32 位計數器 - 即使我只想從 0 數到 5 :)
原則上,VHDL 整數的表示是未定義的。
在實踐中,您通常可以假設綜合工具將使用 2 的補碼表示,同時考慮到范圍約束。 因此,范圍約束和實現的位寬之間的關系很簡單,即使從 VHDL 中報告位寬不是這樣。
我猜這里的“編譯器”(“合成器”)會自動推斷它需要 3 位的存儲長度,因為這個整數的值介於 0 和 5 之間
根據規范它應該,但不是必需的。 來自 IEEE 1076.6-2004:
1.3 術語
應表示必須嚴格遵守的強制性要求,以符合標准,不得偏離(應等於要求)。 “應該”這個詞用來表示某種行動是首選的,但不一定是必需的;
8.3.1.2 整數類型
建議綜合工具應將具有整數子類型指示的信號或變量轉換為相應的位向量。 如果范圍不包含負值,則該項目應具有無符號二進制表示。 如果范圍包含一個或多個負值,則該項目應具有二進制補碼實現。 向量應具有與這些表示一致的最小寬度。
綜合工具應支持整數類型和正、負和無約束(通用)整數,其范圍在 –2 147 483 648 到 +2 147 483 647 范圍內(包括成功映射 32 位二進制補碼的范圍)
示例: “INTEGER range 9 to 10”應該使用等效的 4 位向量長度合成,就像它是用“INTEGER range 0 to 15”的子類型指示定義的一樣。
我可以說明確至少一個綜合工具不使用這種方式的范圍內,我不得不調試形式驗證的錯誤比較。
對於 Xilinx FPGA,XST 綜合報告將說明哪些存儲元件具有未使用的位,但不會說明簡單的連線。
是否有可能以某種方式在報告中打印出這個位寬/長/大小?
基礎數學:
位寬 = ceil(log2(my_integer + 1))
但是VHDL需要更多的努力......
內聯代碼:
use ieee.math_real.all;
...
report "Bit width of myInteger is " & integer'image(integer(ceil(log2(real(myInteger) + real(1)))));
作為一個函數:
use ieee.math_real.all;
...
-- Returns the bit width of i as a positive integer.
function BitWidth(constant i: in positive) return positive is
begin
return positive(ceil(log2(real(i) + real(1)))); -- Add one to prevent errors when i = 2**n
end function;
-- Overload for returning the string representation of the bit width of i.
function BitWidth(constant i: in positive) return string is
variable bit_width: positive := BitWidth(i);
begin
return positive'image(bit_width);
end function;
signal myInteger: positive := 8;
...
report "Bit width of myInteger is " & BitWidth(myInteger);
您可以將這些函數放在一個輔助函數包中。
這可以解決如下:
首先,聲明一個新的(子)類型,表示應用於myInteger
的范圍。 (然后將myInteger
聲明為這種類型的信號,而不是直接屬於整數范圍的信號)。
然后,使用聲明的范圍作為索引范圍聲明一個虛擬數組類型,然后使用'length
of that :
subtype myInteger_range is natural range 0 to 5;
signal myInteger : myInteger_range;
type myInteger_dummy_array is array (myInteger_range) of boolean; -- or whatever
report integer'image(myInteger_dummy_array'length); --> "6"
你總是可以使用:
report("myInteger 的位寬為 "& integer'image(myInteger'left - myInteger'Right));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.