जब VHDL लेखन, मैं अत्यधिक के लिए पूर्णांक (पूर्णांक) के बजाय std_logic_vector (SLV) उपयोग करने की अनुशंसा सिग्नल । (दूसरी ओर, जेनेरिक, कुछ स्थिरांक, और कुछ चर के लिए int का उपयोग करना अत्यधिक उपयोगी हो सकता है।) सीधे शब्दों में कहें, यदि आप टाइप इंट का संकेत देते हैं, या पूर्णांक के लिए एक सीमा निर्दिष्ट करना है तो आप शायद कर रहे हैं। कुछ गलत।
Int के साथ समस्या यह है कि VHDL प्रोग्रामर को यह पता नहीं है कि int का आंतरिक तर्क प्रतिनिधित्व क्या है, और इसलिए हम इसका लाभ नहीं उठा सकते हैं। उदाहरण के लिए, यदि मैं 1 से 10 के अंतर को परिभाषित करता हूं तो मुझे पता नहीं है कि कंपाइलर उन मानों को कैसे एनकोड करता है। उम्मीद है कि इसे 4 बिट्स के रूप में एन्कोड किया जाएगा, लेकिन हम इससे आगे नहीं जानते हैं। यदि आप FPGA के अंदर संकेतों की जांच कर सकते हैं तो इसे "0001" से "1010" के रूप में एन्कोड किया जा सकता है, या "0000" के रूप में "1001" में एन्कोड किया जा सकता है। यह भी संभव है कि यह एक तरह से एनकोडेड हो जो कि हम इंसानों के लिए बिलकुल समझ में न आए।
इसके बजाय हमें int के बजाय बस slv का उपयोग करना चाहिए, क्योंकि तब हमारे पास एन्कोडिंग पर नियंत्रण होता है और व्यक्तिगत बिट्स तक भी सीधी पहुंच होती है। प्रत्यक्ष पहुंच महत्वपूर्ण है, जैसा कि आप बाद में देखेंगे।
जब भी हमें अलग-अलग बिट्स तक पहुंच की आवश्यकता होती है, हम सिर्फ एक एसएलवी डालने का इरादा रख सकते हैं, लेकिन यह वास्तव में गड़बड़ है, बहुत तेज है। यह दोनों दुनिया के सर्वश्रेष्ठ के बजाय दोनों दुनिया के सबसे खराब होने जैसा है। आप कोड को कंपाइलर के लिए ऑप्टिमाइज़ करना मुश्किल होगा, और आपके लिए पढ़ना लगभग असंभव है। मैं इसकी अनुशंसा नहीं करता।
इसलिए, जैसा कि मैंने कहा, एसएलवी के साथ आपको बिट एनकोडिंग पर नियंत्रण और बिट्स तक सीधी पहुंच है। तो आप इससे क्या कर सकते हैं? मैं आपको कुछ उदाहरण दिखाता हूँ। मान लीजिए कि आपको हर 4,294,000,000 घड़ियों को एक बार एक पल्स आउटपुट करने की आवश्यकता है। यहां बताया गया है कि आप इंट के साथ ऐसा कैसे करेंगे:
signal count :integer range 0 to 4293999999; -- a 32 bit integer
process (clk)
begin
if rising_edge(clk) then
if count = 4293999999 then -- The important line!
count <= 0;
pulse <= '1';
else
count <= count + 1;
pulse <= '0';
end if;
end if;
end process;
और एसएलवी का उपयोग कर एक ही कोड:
use ieee.numeric_std.all;
signal count :std_logic_vector (32 downto 0); -- a 33 bit integer, one extra bit!
process (clk)
begin
if rising_edge(clk) then
if count(count'high)='1' then -- The important line!
count <= std_logic_vector(4293999999-1,count'length);
pulse <= '1';
else
count <= count - 1;
pulse <= '0';
end if;
end if;
end process;
इस कोड का अधिकांश अंतर और एसएलवी के बीच समान है, कम से कम परिणामस्वरूप तर्क के आकार और गति के अर्थ में। बेशक एक की गिनती हो रही है और दूसरी की गिनती हो रही है, लेकिन इस उदाहरण के लिए यह महत्वपूर्ण नहीं है।
अंतर "महत्वपूर्ण पंक्ति" में है।
अंतर उदाहरण के साथ, यह एक 32-इनपुट तुलनित्र में परिणाम करने वाला है। 4-इनपुट LUT के साथ कि Xilinx संयमी -3 का उपयोग करता है, इसके लिए 11 LUTs और तर्क के 3 स्तरों की आवश्यकता होती है। कुछ संकलक इसे एक घटाव में परिवर्तित कर सकते हैं जो कैरी चेन का उपयोग करेगा और 32 LUT के बराबर होगा लेकिन तर्क के 3 स्तरों से अधिक तेज़ हो सकता है।
एसएलवी उदाहरण के साथ, कोई 32-बिट तुलना नहीं है, इसलिए यह "शून्य लुट्स, तर्क के शून्य स्तर" है। एकमात्र दंड यह है कि हमारा काउंटर एक अतिरिक्त बिट है। क्योंकि इस अतिरिक्त बिट काउंटर के लिए अतिरिक्त समय सभी कैरी चेन में है, इसलिए अतिरिक्त समय की देरी "लगभग शून्य" है।
बेशक यह एक चरम उदाहरण है, क्योंकि ज्यादातर लोग इस तरह से 32-बिट काउंटर का उपयोग नहीं करेंगे। यह छोटे काउंटरों पर लागू होता है, लेकिन अंतर कम नाटकीय होगा, हालांकि अभी भी महत्वपूर्ण है।
यह केवल एक ही उदाहरण है कि तेजी से समय प्राप्त करने के लिए एसएलवी का उपयोग कैसे करें। Slv का उपयोग करने के कई अन्य तरीके हैं - यह केवल कुछ कल्पना लेता है।
अपडेट: मार्टिन थॉमप्सन की टिप्पणियों को संबोधित करने के लिए सामान जोड़ा गया, "अगर (गिनती -1) <0"
(ध्यान दें: मेरा मानना है कि "यदि आप गणना करें तो <0", क्योंकि यह मेरे एसएलवी संस्करण के बराबर होगा और उस अतिरिक्त घटाव की आवश्यकता को दूर करेगा।)
कुछ परिस्थितियों में यह इच्छित तर्क कार्यान्वयन उत्पन्न कर सकता है लेकिन यह सभी समय काम करने की गारंटी नहीं है। यह आपके कोड पर निर्भर करेगा और आपका कंपाइलर इंट वैल्यू को कैसे एन्कोड करता है।
आपके कंपाइलर पर निर्भर करता है, और आप अपने इंट की सीमा को कैसे निर्दिष्ट करते हैं, यह पूरी तरह से संभव है कि शून्य का एक इंटेंस एफपीजीए लॉजिक में "0000 ... 0000" के बिट वेक्टर को एनकोड नहीं करता है। काम करने के लिए आपकी भिन्नता के लिए, इसे "0000 ... 0000" को एन्कोड करना होगा।
उदाहरण के लिए, मान लें कि आप -5 से +5 तक की सीमा को परिभाषित करते हैं। आप "0000", और +5 को "0101" और -5 को "1011" के रूप में एन्कोड करने के लिए 0 के मान की अपेक्षा कर रहे हैं। यह विशिष्ट टॉक्सो-पूरक एन्कोडिंग योजना है।
लेकिन यह मत समझिए कि कंपाइलर ट्वायस-सप्लीमेंट का उपयोग करने वाला है। हालांकि असामान्य, लोगों के पूरक "बेहतर" तर्क हो सकते हैं। या, संकलक "पक्षपातपूर्ण" एन्कोडिंग का एक प्रकार का उपयोग कर सकता है जहां -5 को "0000", 0 को "0101", और +5 को "1010" के रूप में एन्कोड किया गया है।
यदि इंट की एन्कोडिंग "सही" है, तो संकलक को अनुमान होगा कि कैरी बिट के साथ क्या करना है। लेकिन अगर यह गलत है तो परिणामी तर्क भयानक होगा।
यह संभव है कि इस तरह से इंट का उपयोग करने से उचित तर्क आकार और गति हो सकती है, लेकिन यह कोई गारंटी नहीं है। एक अलग संकलक (उदाहरण के लिए एक्सॉप्स से सिनोप्सिस) पर स्विच करना, या एक अलग FPGA वास्तुकला में जाने से सटीक गलत बात हो सकती है।
निरस्त / हस्ताक्षरित बनाम स्लेव अभी तक एक और बहस है। आप हमें VHDL में इतने सारे विकल्प देने के लिए अमेरिकी सरकार की समिति का धन्यवाद कर सकते हैं। :) मैं एसएलवी का उपयोग करता हूं क्योंकि यह मॉड्यूल और कोर के बीच अंतर करने के लिए मानक है। इसके अलावा, और सिमुलेशन में कुछ अन्य मामलों में, मुझे नहीं लगता कि हस्ताक्षरित / अहस्ताक्षरित से अधिक एसएलवी का उपयोग करने का एक बड़ा लाभ है। मुझे यकीन नहीं है कि यदि हस्ताक्षरित / अहस्ताक्षरित समर्थन त्रिकोणीय संकेतों के साथ है।