vhdl
Auflösungsfunktionen, nicht aufgelöste und aufgelöste Typen
Suche…
Einführung
VHDL-Typen können nicht aufgelöst oder aufgelöst sein . Der bit
- Typ , der vom deklarierten std.standard
Paket, zum Beispiel, ist ungelöst , während der std_logic
Typ des deklarierten ieee.std_logic_1164
Paket behoben ist.
Ein Signal, dessen Typ nicht aufgelöst ist, kann nicht von mehr als einem VHDL-Prozess angesteuert (zugewiesen) werden, während ein Signal, dessen Typ aufgelöst wird, kann.
Bemerkungen
Die Verwendung aufgelöster Typen sollte auf Situationen beschränkt bleiben, in denen wirklich beabsichtigt wird, einen Hardware-Draht (oder einen Kabelsatz) zu modellieren, der von mehr als einem Hardwareschaltkreis angetrieben wird. Ein typischer Fall, in dem dies erforderlich ist, ist der bidirektionale Datenbus eines Speichers: Wenn der Speicher geschrieben wird, steuert das Schreibgerät den Bus, während der Speicher beim Lesen des Speichers den Bus steuert.
Die Verwendung aufgelöster Typen in anderen Situationen ist zwar eine häufig anzutreffende Praxis, aber eine schlechte Idee, da dadurch sehr nützliche Kompilierungsfehler unterdrückt werden, wenn ungewollte Situationen mit mehreren Laufwerken versehentlich erstellt werden.
Das Paket ieee.numeric_std
deklariert die signed
und unsigned
Vektortypen und überlastet die arithmetischen Operatoren. Diese Typen werden häufig verwendet, wenn arithmetische und bitweise Operationen für dieselben Daten erforderlich sind. Die signed
und unsigned
Typen werden aufgelöst. Bei der Verwendung von ieee.numeric_std
und seinen Typen war es vor ieee.numeric_std
Fall, dass versehentliche Situationen mit mehreren Laufwerken keine Kompilierungsfehler verursachen würden. VHDL2008 fügt neue Typdeklarationen zu ieee.numeric_std
: unresolved_signed
und unresolved_unsigned
(Aliasnamen u_signed
und u_unsigned
). Diese neuen Typen sollten in allen Fällen bevorzugt werden, in denen mehrere Fahrsituationen nicht erwünscht sind.
Zwei Prozesse treiben dasselbe Signal vom Typ "Bit"
Die folgenden VHDL - Modell Laufwerke signalisieren s
von zwei verschiedenen Prozessen. Da der Typ von s
ein bit
, ein nicht aufgelöster Typ, ist dies nicht zulässig.
-- File md.vhd
entity md is
end entity md;
architecture arc of md is
signal s: bit;
begin
p1: process
begin
s <= '0';
wait;
end process p1;
p2: process
begin
s <= '0';
wait;
end process p2;
end architecture arc;
Kompilieren, Ausarbeiten und Simulieren, z. B. mit GHDL, führen zu einem Fehler:
ghdl -a md.vhd
ghdl -e md
./md
for signal: .md(arc).s
./md:error: several sources for unresolved signal
./md:error: error during elaboration
Beachten Sie, dass der Fehler auch dann ausgelöst wird, wenn sich, wie in unserem Beispiel, alle Fahrer auf den Fahrwert einigen.
Auflösungsfunktionen
Ein Signal, dessen Typ aufgelöst ist, hat eine zugehörige Auflösungsfunktion . Es kann von mehr als einem VHDL-Prozess gesteuert werden. Die Auflösungsfunktion wird aufgerufen, um den resultierenden Wert zu berechnen, wenn ein Fahrer einen neuen Wert zuweist.
Eine Auflösungsfunktion ist eine reine Funktion, die einen Parameter übernimmt und einen Wert des Typs zur Auflösung zurückgibt. Der Parameter ist ein eindimensionales, uneingeschränktes Array von Elementen des aufzulösenden Typs. Für den Typ bit
, zum Beispiel, kann der Parameter des Typs sein bit_vector
. Während der Simulation wird die Auflösungsfunktion aufgerufen, wenn der resultierende Wert für ein mehrfach angetriebenes Signal berechnet werden soll. Es wird ein Array aller Werte übergeben, die von allen Quellen gesteuert werden, und gibt den resultierenden Wert zurück.
Der folgende Code zeigt die Deklaration einer Auflösungsfunktion für bit
, der sich wie ein drahtgebundenes and
verhält. Außerdem wird gezeigt, wie ein aufgelöster Untertyp vom Typ bit
deklariert und verwendet werden kann.
-- File md.vhd
entity md is
end entity md;
architecture arc of md is
function and_resolve_bit(d: bit_vector) return bit is
variable r: bit := '1';
begin
for i in d'range loop
if d(i) = '0' then
r := '0';
end if;
end loop;
return r;
end function and_resolve_bit;
subtype res_bit is and_resolve_bit bit;
signal s: res_bit;
begin
p1: process
begin
s <= '0', '1' after 1 ns, '0' after 2 ns, '1' after 3 ns;
wait;
end process p1;
p2: process
begin
s <= '0', '1' after 2 ns;
wait;
end process p2;
p3: process(s)
begin
report bit'image(s); -- show value changes
end process p3;
end architecture arc;
Das Kompilieren, Ausarbeiten und Simulieren, z. B. mit GHDL, verursacht keinen Fehler:
ghdl -a md.vhd
ghdl -e md
./md
md.vhd:39:5:@0ms:(report note): '0'
md.vhd:39:5:@3ns:(report note): '1'
Ein Ein-Bit-Kommunikationsprotokoll
Einige sehr einfache und kostengünstige Hardwaregeräte wie Sensoren verwenden ein 1-Bit-Kommunikationsprotokoll. Eine einzige bidirektionale Datenleitung verbindet das Gerät mit einer Art Mikrocontroller. Sie wird häufig von einem Pullup-Widerstand hochgezogen. Die kommunizierenden Geräte fahren die Leitung für eine vordefinierte Dauer auf einen niedrigen Wert, um eine Information an die andere zu senden. Die folgende Abbildung veranschaulicht dies:
In diesem Beispiel wird ieee.std_logic_1164.std_logic
, wie dies mit dem aufgelösten Typ ieee.std_logic_1164.std_logic
.
-- File md.vhd
library ieee;
use ieee.std_logic_1164.all;
entity one_bit_protocol is
end entity one_bit_protocol;
architecture arc of one_bit_protocol is
component uc is
port(
data_in: in std_ulogic;
set_low: out std_ulogic
);
end component uc;
component sensor is
port(
data_in: in std_ulogic;
set_low: out std_ulogic
);
end component sensor;
signal data: std_logic; -- The bi-directional data line
signal set_low_uc: std_ulogic;
signal set_low_sensor: std_ulogic;
begin
-- Micro-controller
uc0: uc port map(
data_in => data,
set_low => set_low_uc
);
-- Sensor
sensor0: sensor port map(
data_in => data,
set_low => set_low_sensor
);
data <= 'H'; -- Pull-up resistor
-- Micro-controller 3-states buffer
data <= '0' when set_low_uc = '1' else 'Z';
-- Sensor 3-states buffer
data <= '0' when set_low_sensor = '1' else 'Z';
end architecture arc;