vhdl
Funzioni di risoluzione, tipi non risolti e risolti
Ricerca…
introduzione
I tipi di VHDL possono essere irrisolti o risolti . Il tipo di bit
dichiarato dal pacchetto std.standard
, ad esempio, non è risolto mentre il tipo std_logic
dichiarato dal pacchetto ieee.std_logic_1164
è stato risolto.
Un segnale di tipo irrisolto non può essere pilotato (assegnato) da più di un processo VHDL mentre un segnale di quale tipo è risolto può.
Osservazioni
L'uso di tipi risolti dovrebbe essere riservato a situazioni in cui l'intenzione è realmente quella di modellare un filo hardware (o una serie di fili) pilotato da più di un circuito hardware. Un caso tipico in cui è necessario è il bus dati bidirezionale di una memoria: quando la memoria è scritta, è il dispositivo di scrittura che guida il bus mentre durante la lettura della memoria è la memoria che guida il bus.
L'utilizzo di tipi risolti in altre situazioni, mentre una pratica frequentemente riscontrata, è una cattiva idea perché sopprime errori di compilazione molto utili quando si creano accidentalmente situazioni di azionamento multiple indesiderate.
Il ieee.numeric_std
pacchetto dichiara le signed
e unsigned
tipi vettoriali e sovraccarica gli operatori aritmetici su di loro. Questi tipi vengono spesso utilizzati quando sono necessarie operazioni aritmetiche e bit-bit sugli stessi dati. Il signed
e unsigned
tipi sono risolti. Il precedente VHDL2008, utilizzando ieee.numeric_std
e i suoi tipi, implicava che situazioni accidentali di azionamento multiplo non avrebbero sollevato errori di compilazione. VHDL2008 aggiunge nuove dichiarazioni di tipo a ieee.numeric_std
: unresolved_signed
e ieee.numeric_std
e unresolved_unsigned
(alias u_signed
e u_unsigned
). Questi nuovi tipi dovrebbero essere preferiti in tutti i casi in cui non si desiderano più situazioni di guida.
Due processi guidano lo stesso segnale di tipo `bit`
Le seguenti unità modello VHDL segnale s
da due diversi processi. Poiché il tipo di s
è un bit
, un tipo non risolto, questo non è permesso.
-- 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;
Compilare, elaborare e provare a simulare, ad es. Con GHDL, genera un errore:
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
Si noti che l'errore viene generato anche se, come nel nostro esempio, tutti i driver concordano sul valore guida.
Funzioni di risoluzione
Un segnale di quale tipo è risolto ha una funzione di risoluzione associata. Può essere guidato da più di un processo VHDL. La funzione di risoluzione viene chiamata per calcolare il valore risultante ogni volta che un driver assegna un nuovo valore.
Una funzione di risoluzione è una funzione pura che accetta un parametro e restituisce un valore del tipo da risolvere. Il parametro è una matrice unidimensionale e non vincolata di elementi del tipo da risolvere. Per il bit
tipo, ad esempio, il parametro può essere di tipo bit_vector
. Durante la simulazione, la funzione di risoluzione viene chiamata quando necessario per calcolare il valore risultante da applicare a un segnale guidato da più fattori. Viene passato un array di tutti i valori guidati da tutte le fonti e restituisce il valore risultante.
Il seguente codice mostra la dichiarazione di una funzione di risoluzione per il bit
tipo che si comporta come un cavo and
. Mostra anche come dichiarare un sottotipo risolto di bit
di tipo e come può essere utilizzato.
-- 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;
Compilare, elaborare e simulare, ad esempio con GHDL, non genera un errore:
ghdl -a md.vhd
ghdl -e md
./md
md.vhd:39:5:@0ms:(report note): '0'
md.vhd:39:5:@3ns:(report note): '1'
Un protocollo di comunicazione a un bit
Alcuni dispositivi hardware molto semplici ea basso costo, come i sensori, utilizzano un protocollo di comunicazione a un bit. Una singola linea dati bidirezionale collega il dispositivo a un tipo di microcontrollore. Viene frequentemente tirato su da un resistore di pull-up. I dispositivi di comunicazione guidano la linea in basso per una durata predefinita per inviare un'informazione all'altro. La figura seguente illustra questo:
Questo esempio mostra come modellarlo usando il tipo risolto 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;