2013-06-01 12 views
7

Mi sto preparando per un esame passando attraverso alcuni vecchi. Una delle domande è:È possibile utilizzare i tipi personalizzati nella dichiarazione della porta?

Scrivere il codice VHDL comportamentale sintetizzabile che implementa l'FSM sincrono in fig ... L'FSM ha un input, chiamato request, cioè di tipo di enumerazione con valori (r1, r2, r3) ...

che fa venire voglia di scrivere questo codice:

entity fsm is 
    port (clk  : in std_logic; 
     request : in my_enum_type 
); 
end fsm; 

E da qualche parte un:

type my_enum_type is (r1, r2, r3); 

da qualche parte (ho provato giusto prima della dichiarazione della porta e subito dopo la dichiarazione dell'architettura).

Ma non riesco a farlo funzionare. Posso avere tipi personalizzati come input o output come quello?

risposta

7

Sì, è possibile, e lo considero una buona pratica: significa meno lavoro, migliore comprensione, manutenzione più semplice e design più pulito.

Il trucco è dichiarare i tipi comuni all'intero progetto in un pacchetto (io di solito lo chiamo "Comune" :-) e aggiungere use work.Common.all prima della dichiarazione dell'entità E in ogni cliente di tale entità. Componenti più specializzati possono avere nomi appropriati, ovviamente!

Ad esempio:

package Common is -- untested... 

    type my_enum_type is (r1, r2, r3); 

    -- (optional) useful tools 
    function to_slv (e : my_enum_type) return std_logic_vector; 
    function to_enum (s : std_logic_vector(my_enum'length downto 0)) 
        return my_enum_type; 

end Common; 

package body Common is 
    -- subprogram bodies here 
end Common; 

Ora, quando si aggiunge un valore al di enumerazione, è solo modificare "Comune" e ricostruire il disegno, mentre coloro che seguono le linee guida convenzionali stanno ancora cercando di identificare ogni porto e il segnale dove devono aumentare l'intervallo del loro "std_logic_vector" di 1.

Funziona davvero bene anche per le interfacce bus, dove un record in ogni direzione nasconde tutti i segnali individuali di bus e handshaking.

È necessario combattere strumenti "brain-dead" come Xilinx "generatore automatico di testbench" che tradurrà in modo utile TUTTI i tipi di porta, interi o booleani e personalizzati, in std_logic (_vector) e quindi non verranno compilati. Basta tradurli di nuovo.

È ancora possibile creare un caso che al livello più alto, tutti i pin FPGA esterni dovrebbero essere ancora basati su std_logic. E se hai mai bisogno di simulare una versione post-sintesi del tuo progetto, allora avrai bisogno di vivere con le porte std_logic_vector, o aggiungere un semplice wrapper per convertire da un modulo all'altro.

+0

Che funziona perfettamente! Domanda: Quel livello di punta e la roba del pin ... Come convertirei? Solo un se? if (request = r1) then pin1 <= '1' ... Questo non è un problema per me, ma sarebbe bello saperlo. – evading

+0

Seppellite il livello di dettaglio negli "strumenti utili" nel pacchetto Common ... il vostro wrapper contiene quindi un'entità (la netlist post_synth con porte SLV) e assegnazioni di segnale come 'slv_enum <= a_slv (mio_enum);' –

+0

Un'ulteriore nota - puoi scrivere quegli "strumenti utili" (per le enumerazioni) in termini di attributi '' pos'' e ''val'' e numeric_std.unsigned, quindi il corpo di' to_enum' potrebbe semplicemente essere 'return my_enum_type'val (unsigned (s)); ' –

Problemi correlati