मैं VHDL में संकेतों की "परवाह नहीं" कैसे निर्दिष्ट कर सकता हूं?


11

लॉजिक डिज़ाइन पाठ्यक्रमों में हम सभी ने यह सीखा कि लॉजिक फ़ंक्शन को कम करना संभव है, उदाहरण के लिए कर्णघ मानचित्र या क्वीन-मैकक्लूस्की एल्गोरिथ्म का उपयोग करके । हमने यह भी सीखा कि " डोन्ट केयर" मूल्य न्यूनतम क्षमता को बढ़ाते हैं।

उदाहरण के लिए एक रजिस्टर फ़ाइल लें। write_addressऔर write_dataसंकेत वास्तव में कोई फर्क नहीं है जब write_enableसंकेत है '0'। इस प्रकार, उन्हें इन संकेतों को चलाने वाले तर्क में अधिक अनुकूलन की अनुमति देने के लिए "डोन्ट केयर" मान सौंपा जाना चाहिए (अर्थात रजिस्टर फाइल में ही नहीं)।

VHDL में ऐसे "डोन्ट केयर" मूल्यों को निर्दिष्ट करने का सही तरीका क्या है ताकि संभावित अनुकूलन के लिए संश्लेषण उपकरण को अधिक जगह मिल सके?


अब तक मुझे निम्नलिखित चीजें मिली हैं जो उपयुक्त हो सकती हैं। लेकिन मुझे वास्तव में यकीन नहीं है कि प्रत्येक दृष्टिकोण के पेशेवरों और विपक्ष क्या हैं:

  • बस संकेत नहीं दे रहा है। ऐसा लगता है कि यह काम कर सकता है। हालाँकि मैंने पाया कि यह तब काम नहीं करता है जब आप कुछ recordप्रकार के "कुछ भी नहीं करना चाहते हैं" को परिभाषित करना चाहते हैं , क्योंकि रिकॉर्ड स्थिरांक को पूरी तरह से निर्दिष्ट करने की आवश्यकता है (कम से कम मॉडलिम मुझे ऐसा बताता है)।
  • std_logic_1164पैकेज मूल्य को परिभाषित करता है '-' -- Don't careके लिए std_ulogic। ऐसा लगता है कि यह एक स्पष्ट "परवाह नहीं" के लिए शब्दार्थ सही विकल्प है, लेकिन मैंने इसे कभी भी कहीं भी इस्तेमाल नहीं किया है (असंबंधित VHDL-2008 case?निर्माणों को छोड़कर )।
  • मॉडलिम 'X'अपरिभाषित संकेतों को प्रदर्शित करने के लिए मूल्य का उपयोग करता है। हालांकि मुझे यकीन नहीं है कि अगर संश्लेषण उपकरण एक स्पष्ट-समझ को समझते हैं, 'X'तो "परवाह न करें"।

यहाँ स्पष्टीकरण के लिए एक ओवरसाइम्प्लिफ़ाइड कोड स्निपेट है, जहाँ मैंने आरंभिक संकेतों की देखभाल नहीं की है '-'

आप देख सकते हैं, संकेत control.reg_write_address3 अलग मान हो सकते हैं: "----", instruction(11 downto 8);और instruction(3 downto 0);। अब मैं उम्मीद करता हूँ कि इसे 2-इनपुट मल्टीप्लेक्स के लिए संश्लेषित किया जाए अगर '-'इसे "परवाह न करें" के रूप में व्याख्या की जाए। अगर मैंने (others => '0')इसके बजाय सिग्नल को इनिशियलाइज़ किया था '-', तो टूल को इसके बजाय 3-इनपुट मल्टीप्लेक्स उत्पन्न करना होगा।

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package mytypes is
    type control_signals_t is record
        write_enable  : std_logic;
        write_address : std_ulogic_vector(3 downto 0);
        read_address  : std_ulogic_vector(3 downto 0);
    end record;

    -- All members of this constant must be fully specified.
    -- So it's not possible to simply not assign a value.
    constant CONTROL_NOP : control_signals_t := (
        write_enable  => '0',
        write_address => (others => '-'),
        read_address  => (others => '-')
    );
end package;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library cfx;
use cfx.mytypes.all;

entity control_unit is
    port(
        instruction : in  std_ulogic_vector(15 downto 0);
        write_data  : out std_ulogic_vector(15 downto 0);
        ctrl        : out control_signals_t
    );
end entity;

architecture rtl of control_unit is
begin
    decode_instruction : process(instruction) is
    begin
        -- Set sensible default values that do nothing.
        -- Especially all "write_enable" signals should be '0'.
        -- Everything else is mostly irrelevant (don't care).
        ctrl       <= CONTROL_NOP;
        write_data <= (others => '-');

        if instruction(15 downto 12) = "1100" then
            -- Load 8 bit of data into the register file
            ctrl.write_enable  <= '1';
            write_data         <= std_ulogic_vector(resize(signed(instruction(7 downto 0)), 16));
            ctrl.write_address <= instruction(11 downto 8);
        elsif instruction(15 downto 8) = "11111001" then
            -- Load 4 bit of data into the register file
            write_data         <= std_ulogic_vector(resize(signed(instruction(7 downto 4)), 16));
            ctrl.write_address <= instruction(3 downto 0);
        elsif instruction(15 downto 8) = "10110101" then
            -- Read from the register file. Don't use the write signals at all.
            ctrl.read_address <= instruction(3 downto 0);
        end if;
    end process;
end architecture;

क्या आप इस बारे में विस्तार से बता सकते हैं कि आप क्या करने की कोशिश कर रहे हैं write_addressऔर write_data? आप किस अनुकूलन की उम्मीद करते हैं?
fru1tbat

मुझे आशा है कि उदाहरण यह स्पष्ट करता है कि मैं क्या हासिल करना चाहता हूं।
फ्रिट्ज़

जवाबों:


9

मैं अधिक विस्तृत उत्तर प्रदान करने के लिए LRM विशेषज्ञ के पास इसे छोड़ दूंगा, लेकिन संक्षेप में, आपका दृष्टिकोण मान्य होना चाहिए - मैंने क्वार्टस के हाल के संस्करण के साथ एक त्वरित परीक्षण चलाया, और यह इस '-'तरह से हैंडल करता है जैसे यह माना जाता है - उत्पन्न तर्क कम हो गया है उम्मीद के मुताबिक जब आउटपुट डिफॉल्ट हो जाता है '-'( 'X'वैसे भी काम करता है)। आपके द्वारा सूचीबद्ध दृष्टिकोणों पर अधिक:

  • संकेत नहीं असाइन करना वास्तव में आपके उदाहरण के लिए एक विकल्प नहीं है, निश्चित रूप से, यदि आप कुंडी नहीं चाहते हैं। यदि यह एक क्लॉक की गई प्रक्रिया है, तो आप थोड़ा बेहतर हैं, लेकिन आप अभी भी सक्षम होंगे जहां आपको उनकी आवश्यकता नहीं है। हो सकता है कि मुझे यहां आपकी मंशा याद आ रही हो।

  • '-', जैसा कि पहले उल्लेख किया गया है, संभवतः अर्थ और व्यावहारिक दोनों कारणों के लिए सबसे अच्छा विकल्प है।

  • आप "अपरिभाषित" से क्या मतलब है पर निर्भर करता है। 'X'तकनीकी रूप से "अज्ञात" है। 'U'Uninitialized संकेतों के लिए है, जो ModelSim "X"हेक्स अभ्यावेदन के लिए प्रदर्शित करता है । 'X'काम करने लगता है, हालांकि, जैसा कि मैंने ऊपर उल्लेख किया है।

एक अन्य विकल्प यह होगा कि आप अनुकूलन स्वयं करें और एक मामले को स्पष्ट रूप से जांचे जाने से दूर करें:

if instruction(15 downto 8) = "11111001" then
  write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 4)), 16));
else
  write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 0)), 16));
end if;

यह महत्वपूर्ण नुकसान है (ज्यादातर कोड स्पष्टता से संबंधित है), हालांकि, और मैं शायद अधिक आदर्श समाधान का विकल्प चुनूंगा।

संयोग से, '-'आमतौर पर भी उपयोग किया जाता है std_match(), जिसे मैं आपके डिकोडिंग के लिए उपयोग करने पर विचार करूंगा, जैसे:

if std_match(instruction(15 downto 8), "1100----") then

हालांकि उस बिंदु पर, आप शायद सिर्फ उपयोग करने से बेहतर हैं case?


6

संक्षेप में: यह कानूनी VHDL है और यह आमतौर पर संश्लेषण उपकरण द्वारा समर्थित है।

हालांकि इसका इस्तेमाल किया जाना असामान्य है। मैं सच में पता नहीं क्यों। आपका कोड मुझे इसका एक अच्छा उदाहरण लगता है जब इसका उपयोग करना सार्थक होगा।

हालांकि एक दोष यह है कि किसी को इसके बारे में पता होना चाहिए: संश्लेषण पर, फ़ंक्शन ड्राइविंग आउटपुट जहां देखभाल नहीं करते हैं वे संश्लेषण रन के बीच भिन्न हो सकते हैं । यह संश्लेषण को कम निर्धारक बनाता है। अगर ऐसे आउटपुट को परिभाषित किया गया है जो देखभाल नहीं करते हैं (गलती से), यह त्रुटि को खोजने के लिए कठिन बना सकता है।

उपकरण का समर्थन

कम से कम निम्नलिखित उपकरण स्वीकार नहीं करेंगे और अनुकूलन संभावनाओं का उपयोग करेंगे:

  • Xilinx (Ref .: "XST उपयोगकर्ता गाइड")
  • Altera (Ref।: "अनुशंसित एचडीएल कोडिंग शैलियाँ")
  • Synplify (Ref।: "संदर्भ मैनुअल को सम्‍मिलित करें")

Xilinx और Altera व्यवहार करेगा '-'और 'X'के रूप में कोई परवाह नहीं है, Synplify उन और इसके अलावा व्यवहार करेगा 'U'और 'W'(कमजोर) के रूप में परवाह नहीं है।


1
मेरे पास उस खामी का एक और आवेदन था। कोड ने सिमुलेशन में काम किया, लेकिन FPGA पर नहीं, क्योंकि मेरा कोड जैसा दिखता था if signal = '1' then a; else b; end if;:। दुर्भाग्य से signalनहीं था 1या 0लेकिन -। तो सिमुलेशन में, elseशाखा को निष्पादित किया गया था, लेकिन हार्डवेयर में -निकला एक 1, इसलिए सच्ची शाखा को निष्पादित किया गया ...
Fritz

हाँ, मैं इसी तरह के कीड़े पास सिमुलेशन था, लेकिन अक्सर मेरे मामले 'U'में सिमुलेशन की शुरुआत में एस, आम हैं, जो कुछ elseकोड ब्लॉक के लिए इस्तेमाल किया जा रहा है निष्पादित किया जा रहा है। यह अद्भुत होगा यदि सशर्त किसी तरह से 'U'एस प्रचार करने के लिए बनाया जा सकता है , समवर्ती बूलियन अभिव्यक्तियों के व्यवहार के समान।
कार्ल

मैंने उस बग को ढूंढने के बाद हमेशा कुछ न कुछ लिखना सुनिश्चित किया if signal = '1' then output <= '1'; elsif signal='0' then output <= '0'; else output <= '-'; end if;। और मैंने निम्नलिखित सभी रजिस्टरों और यादों को जोड़ा: assert not is_X(write_enable) report "we=" & str(A_write_enable) severity ERROR;और if write_enable = '1' then assert not is_X(write_addr) report "write_addr=str(write_addr) severity ERROR; end if;। साथ ही इसके लिए भी write_data। एक साथ, यह लगभग सभी त्रुटियों को पकड़ना चाहिए।
फ्रिट्ज़

यह एक तरीका है, लेकिन इस तरह से मेरे लिए भी क्रिया है। मैं VHDL भाषा के भीतर इस संभावना की कामना करता हूं।
कार्ल

1
ठीक है, VHDL थोड़ा वर्बोज़ है, लेकिन यह सिर्फ VHDL तरीका है। : दूसरी ओर डी भी बहुत स्पष्ट है, और मेरी पीठ के पीछे "काला जादू" नहीं करता है, जो मुझे काफी अच्छा लगता है (सीएफ। पायथन का ज़ेन "स्पष्ट है" निहित से बेहतर है)।
फ्रिट्ज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.