在一個程序中,我需要根據其中一個埠是否具有特定值來做一些事情。此值在單獨的包檔案中的型別 def 中定義。
比較應該在“if-statement”中完成,以獲得簡短易讀的代碼。
因為我需要確保沒有我不能使用的混淆use work.pkg.all,所以我使用pkg_name.enum_name
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
use work.SAWTOOTH_INNER_pkg.all; -- other pkg which is needed.
entity SAWTOOTH_entity is
PORT(
p_clk : in std_logic;
p_event_enum_next : in SAWTOOTH_pkg.in_event_enum
);
end entity;
architecture arch of SAWTOOTH_entity is
begin
process(p_clk)
begin
if rising_edge(p_clk) then
-- Throws error. Modelsim says 'no feasable entry for /='
if (p_event_enum_next /= SAWTOOTH_pkg.event_enum_empty) then
-- do something
end if;
-- Does the same but compiles without errors. But it is much longer.
case p_event_enum_next is
when SAWTOOTH_pkg.event_enum_empty =>
-- do nothing
when others =>
-- do something
end case;
end if;
end process;
end architecture;
編輯:更多資訊:
確切的錯誤:
** Error: C:\Users\4DIAC\Desktop\ModelSimWS\Bug.vhd(25): (vcom-1581) No feasible entries for infix operator '/='.
** Error: C:\Users\4DIAC\Desktop\ModelSimWS\Bug.vhd(25): Type error resolving infix expression "/=" as type std.STANDARD.BOOLEAN.
包:SAWTOOTH_INNER_PKG:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
package SAWTOOTH_INNER_pkg is
TYPE in_event_enum is (event_enum_empty, event_enum_START, event_enum_STOP, event_enum_REQ, event_enum_CONFIG);
TYPE buffer_event_type is array (0 to 3) of in_event_enum;
end SAWTOOTH_INNER_pkg;
SAWTOOTH_PKG:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
package SAWTOOTH_pkg is
TYPE in_event_enum is (event_enum_empty, event_enum_CONFIG, event_enum_START, event_enum_STOP);
TYPE buffer_event_type is array (0 to 3) of in_event_enum;
end SAWTOOTH_pkg;
uj5u.com熱心網友回復:
問題中聲稱的包 SAWTOOTH_pkg 宣告存在缺陷,雖然問題文本顯示 SAWTOOTH_pkg,但宣告顯示為 SAWTOOTH_INNER_pkg:
SAWTOOTH_PKG:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.all;
package SAWTOOTH_INNER_pkg is
TYPE in_event_enum is (event_enum_empty, event_enum_START, event_enum_STOP, event_enum_REQ, event_enum_CONFIG);
TYPE buffer_event_type is array (0 to 3) of in_event_enum;
end SAWTOOTH_INNER_pkg;
出于最小、完整和可驗證的示例的目的,這兩個包除了包名之外可以相同,因此包 SAWTOOTH_pkg 的包名應為 SAWTOOTH_pkg(在兩個地方)代替 SAWTOOTH_INNER_pkg。
預定義運算子在型別宣告之后立即隱式宣告。這意味著通過所選名稱使型別宣告可見并不會使運算子宣告可見。
IEEE Std 1076-2008
9.2 運算子
9.2.3 關系運算子
為檔案型別和受保護型別以外的所有型別定義了相等和不等運算子(= 和 /=)。如果兩個運算元相等,相等運算子回傳值 TRUE,否則回傳值 FALSE。如果兩個運算元相等,則不等式運算子回傳值 FALSE,否則回傳值 TRUE。
該標準在 4.5 子程式多載、4.5.1 通用、4.5.2 運算子多載小節中包含了一種提供多載子程式和運算子的機制(“其指示符為運算子符號的函式的宣告用于多載運算子。運算子符號的字符應是 9.2.") 和 4.5.3 簽名中定義的運算子類別中的運算子之一。這些可用于為新型別多載運算子,例如列舉型別(5.2 標量型別 5.2.1 通用)in_event_enum。
12.5 多載決議的背景關系
12.5 多載決議的背景關系
多載是為名稱、子程式和列舉字面量定義的。
對于多載的物體,只要可見性規則確定在出現的位置可以接受多個含義,多載決策就會確定識別符號或字符文字的出現所具有的實際含義;多載決議同樣決定了一個運算子或基本操作出現的實際意義(見 5.1)。
這里的物體是指命名物體,而不是由物體宣告宣告的外部塊。
所有這一切都基于 12.3 可見性:
對于文本中的每個識別符號和每個位置,可見性規則確定了一組宣告(使用此識別符號),這些宣告定義了識別符號出現的可能含義。當根據可見性規則,宣告定義了此事件的可能含義時,則稱宣告在文本中的給定位置可見。在確定這種宣告的含義時,會出現以下兩種情況:
— 可見性規則最多確定一種可能的含義。在這種情況下,可見性規則足以確定定義識別符號出現的含義的宣告,或者在沒有這樣的宣告的情況下,確定該出現在給定點是不合法的。
— 可見性規則決定了不止一種可能的含義。在這種情況下,當且僅當恰好一個可見宣告對于給定背景關系中的多載規則是可接受的,或者所有可見宣告都表示相同的命名物體時,此時識別符號的出現是合法的。
vcom-1581 錯誤告訴我們第一種情況不滿足沒有可見的運算子多載宣告(由“/=”指定)回傳一個布林值并具有 in_event_enum 的引數基型別。
根據您的問題,我們可以通過 use 子句禁止您直接看到包的宣告,沒有提供推理,或者我們可以通過選擇使宣告可見(這與問題要求“比較應該在' if-statement' 具有簡短易讀的代碼。” 選定的名稱可以用作函式呼叫的前綴,但不能用作運算子,并且將指示符用作函式呼叫可能滿足要求,也可能不滿足要求。(它只是更長前綴,括號括起來的引數和雙引號來指定運算子符號。)我們已經可以看到您嘗試使用 use 子句“縮短” if 陳述句條件use work.all;使作業庫中的包宣告直接可見。通常,高級 VHDL 用戶會認為使用這樣的 use 子句是粗俗的,它實際上需要您回溯到 use 子句以了解可見性是如何產生的。
那么有沒有辦法讓預定義的不等式運算子的隱式宣告直接可見(避免函式呼叫的前綴)?
VHDL 支持使用別名(6.6 別名宣告),其中非物件別名在其宣告中使用簽名來提供資訊以滿足上述 12.3 的第一種情況(在包 SAWTOOTH_pkg 中找到的每個型別宣告,對的參考SAWTOOTH_pkg."/="將是模棱兩可的與第二種情況發生沖突)。
所以我們的別名宣告看起來像
architecture arch of SAWTOOTH_entity is
alias "/=" is work.sawtooth_pkg."/="
[work.sawtooth_pkg.in_event_enum,
work.sawtooth_pkg.in_event_enum return boolean];
begin
process(p_clk)
begin
if rising_edge(p_clk) then
-- Throws error. Modelsim says 'no feasable entry for /='
if (p_event_enum_next /= SAWTOOTH_pkg.event_enum_empty) then
-- do something
end if;
并且可以作為架構宣告項制作,或者因為不等式運算子僅在流程宣告中使用,在流程宣告部分中。
在運算子指示符直接可見的情況下,二級設計物體(架構)進行分析(當問題提供最小、完整且可驗證的示例時,提供兩個包宣告)。
還有宣告范圍的概念(12.2 宣告范圍)。如果禁止使用使包 SAWTOOTH_pkg 中的所有宣告直接可見的 use 子句是由于包 SAWTOOTH_INNER_pkg 中出現相同的宣告,您可以利用內部宣告區域,其中不依賴包 SAWTOOTH_INNER_pkg 中的宣告來使用用于使包 SAWTOOTH_pkg 中的宣告直接可見的 use 子句:
begin
process (p_clk)
use work.SAWTOOTH_pkg.all;
begin
if rising_edge(p_clk) then
-- Throws error. Modelsim says 'no feasable entry for /='
if p_event_enum_next /= event_enum_empty then
-- do something
end if;
這也適用于此處,這可能是也可能不是示例過于最小的結果。流程陳述句是一個內部宣告區域,它允許任何出現的宣告也被所有 use 子句可見,其范圍包括這個地方被內部宣告區域中的 use 子句可見的宣告隱藏(參見 12.4 Use 子句)。
問題示例代碼不排除通過在外部宣告區域中隱藏宣告來使用內部宣告區域來劃分可見性。
不依賴于這些使不等式運算子多載的宣告直接可見的方法將依賴于選定的名稱,并且不符合 if 陳述句的最短可讀代碼主觀標準:
architecture arch of SAWTOOTH_entity is
-- alias "/=" is work.sawtooth_pkg."/="
-- [work.sawtooth_pkg.in_event_enum,
-- work.sawtooth_pkg.in_event_enum return boolean];
begin
process (p_clk)
-- use work.sawtooth_pkg.all;
begin
if rising_edge(p_clk) then
-- Throws error. Modelsim says 'no feasable entry for /='
-- if p_event_enum_next /= sawtooth_pkg.event_enum_empty then
-- -- do something
-- end if;
if sawtooth_pkg."/="(p_event_enum_next,
sawtooth_pkg.event_enum_empty) then
-- do something
end if;
-- Does the same but compiles without errors. But it is much longer.
case p_event_enum_next is
when SAWTOOTH_pkg.event_enum_empty =>
-- do nothing
when others =>
-- do something
end case;
end if;
end process;
end architecture;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/471123.html
