Home
Accesso / Registrazione
 di 

VHDL

11 risposte [Ultimo post]
ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12

Ciao a tutti.Sto cercando di risolvere un esercizio su una macchina a stati,ma mi fermo a degli errori che non riesco a risolvere:
[code]process(SC)
begin
case SC is
when s0 => (lattina<='0',resto<='000');
when s10 => (lattina<='0',resto<='000');
when s20 => (lattina<='0',resto<='000');
when s30 => (lattina<='0',resto<='000');
when s40 => (lattina<='0',resto<='000');
when s50 => (lattina<='1',resto<='000');
when s60 => (lattina<='1',resto<='001');
when s70 => (lattina<='1',resto<='010');
when s80 => (lattina<='1',resto<='011');
when s90 => (lattina<='1',resto<='100');
when others => null;
end case;
end process;[/code]
gli errori che riscontra ghdl sono solo in questo pezzo:
[code]resto.vhdl:31:49: unexpected token ''' in a primary
resto.vhdl:31:49: '=>' is expected instead of '''
[/code]
Riuscite a capire se c'è un errore di sintassi o cos'altro?

ritratto di Mino_73
Online
Titolo: User++
Utente++
Ultima visita:
5 min 24 sec fa
Utente dal: 27/06/2008
Messaggi: 69
A occhio e al volo direi che

A occhio e al volo direi che tra le varie assegnazione ci va il ";" e non la ","
io scriverei così

when s0 => lattina<='0'; resto<='000';
ecc
ecc

Le tonde non sono obbligatorie ci sono i ";" che delimitano le istruzioni.
Poi la scritta [code]process(SC)
questo tipo di dichiarazione di processo non la conosco io in genere uso scrivere

code:process(SC)

dove non "code" indichi un nome al processo, utile durante la simulazione per identificare il processostesso.

ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12
Il [code] l'ho usato per

Il [code] l'ho usato per distinguere la parte di codice dal resto(in altri forum si usa così).
Comunque ho provato a metterci i ;,ma non vanno bene lo stesso.
tra l'altro non ho capito una cosa in generale:che differenza c'è tra scrivere
x <= '01' e x <= "01" ?

ritratto di Mino_73
Online
Titolo: User++
Utente++
Ultima visita:
5 min 24 sec fa
Utente dal: 27/06/2008
Messaggi: 69
Non ho visto le

Non ho visto le virgolette!!
In effetti anche quello è un errore.
Facciamo ordine allora!! Gli apici si utilizzano quando vuoi esplicitare il valore di un segnale o di unsingolo bit di un registro le doppie si utilizzano quando vuoi espicitare il valore di più bit.
In pratica le righe che hai scritto le devi riscrivere così:

when s0 => lattina<='0'; resto<="000";

questo è valido se "lattina" è di tipo std_logic e "resto" è di tipo
std_logic_vector(2 downto 0)

Scusami per l'errore, utilizzo sia il verilog che il vhdl e spesso scrivo un misto dei due :-) alle volte ci metto anche un pò di C a dire il vero.
Con una compilata si risolve tutto però.
L'utilizzo delle parentesi e della virgola per accorpare le istruzioni non lo conoscevo e dire che sono quasi 10 anni che scrivo in vhdl, non si finisce mai di imparare.

Per finire sostituisci anche il when others => null con una assegnazione esplicita ad un valore nullo dei due segnali.
Questo perchè altrimenti in sintesi ti ritrovi un multiplexer con un latch in uscita invece di un semplice multiplexer. Nei processi combinatori (tutti quelli dove non usi il rising_edge o 'event) è necessario eseguire un'assegnazione per ogni ramo del processo altrimenti in sintesi avrai come risultato un lacth, che in logica programmabile sono da evitare.
Nel processo che hai scritto nel caso il valore di SC non corrisponde a nessuno dei vaolori del case non viene eseguita nessuna assegnazione ma questo significa che i due segnali devono essere memorizzati e non essendoci un clok il sintetizzatore mette dei latch.

Come trucco per evitare delle assegnazioni non fatte puoi fare un'assegnazione di tutti i segnali da pilotare nel processo subito dopo il begin, e poi prosegui con tutte le istruzioni che vuoi.
tipo:

process(SC)
begin
lattina <= '0';
resto <= "000";

case SC is
when s0 => lattina <= '0'; resto <= "000";
when s10 => lattina <= '0'; resto <= "000";
when s20 => lattina <= '0'; resto <= "000";
when s30 => lattina <= '0'; resto <= "000";
when s40 => lattina <= '0'; resto <= "000";
when s50 => lattina <= '1'; resto <= "000";
when s60 => lattina <= '1'; resto <= "001";
when s70 => lattina <= '1'; resto <= "010";
when s80 => lattina <= '1'; resto <= "011";
when s90 => lattina <= '1'; resto <= "100";
when others => null;
end case;

end process;

il segnale risulta assegnato al valore dell'ultima assegnazione eseguita prima dell'uscita dal processo.
Quindi se SC non corrisponde a nessun ramo del case rimangono valide le assegnazioni in testa al processo, altrimenti varranno le assegnazioni fatte nel ramo del case corrispondente a SC.

ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12
Perfetto,grazie mille per i

Perfetto,grazie mille per i chiarimenti

ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12
Già che ci siamo,questa

Già che ci siamo,questa tecnica di "mettere le mani avanti" e assegnare un valore prestabilito a tutti gli altri casi oltre quelli previsti,si può utilizzare anche in questo caso:
ho un decoder 4-16 one-hot,in cui se le entrate vanno da 1 a 16(in decimale) si deve accendere solo il bit corrispondente,mentre negli altri casi(alta impedenza,don't care eccetera l'uscita deve andare a 0).Seguendo il tuo consiglio ho scritto questo:

process(binary_in)
begin
decoder_out<=x"0000";
case binary_in is
when x"0" => decoder_out<= x"0001";
when x"1" => decoder_out<= x"0002";
when x"2"=> decoder_out<=x"0004";
when x"3"=> decoder_out<=x"0008";
when x"4"=> decoder_out<=x"0010";
when x"5"=> decoder_out<=x"0020";
when x"6"=> decoder_out<=x"0040";
when x"7"=> decoder_out<=x"0080" ;
when x"8"=> decoder_out<=x"0100";
when x"9"=> decoder_out<=x"0200";
when x"A"=> decoder_out<=x"0400";
when x"B"=> decoder_out<=x"0800";
when x"C"=> decoder_out<=x"1000";
when x"D"=> decoder_out<=x"2000";
when x"E"=> decoder_out<=x"4000";
when x"F"=> decoder_out<=x"8000";
when others => null;
end case;
end process;
end ESEMPIO1;

ma mi sa proprio che non è corretto

ritratto di Mino_73
Online
Titolo: User++
Utente++
Ultima visita:
5 min 24 sec fa
Utente dal: 27/06/2008
Messaggi: 69
Corretto

Questa tecnica la puoi usare sempre in qualsiasi tipo di processo combinatorio o sequenziale. Anzi nei processi combinatori è anche consigliato specialmente se nel processo metti dei costrutti di tipo " if then " annidati. Se dimentichi un else, ad esempio, ottieni il solito e indesiderato latch.
Quello che hai scritto è corretto a me compila correttamente.
imposti i due sagnali come:

signal binary_in:std_logic_vector(3 downto 0);
signal decoder_out:std_logic_vector(15 downto 0);

e tutto gira correttamente.

Per i valori numerici puoi usare anche la forma 16#0000# dove con 16 indichi la base numerica in cui esprimi il numero tra i simboli #.

ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12
a me invece dà questo errore:

a me invece dà questo errore: " 'begin' is expected instead of 'process' "

ritratto di Mino_73
Online
Titolo: User++
Utente++
Ultima visita:
5 min 24 sec fa
Utente dal: 27/06/2008
Messaggi: 69
Di seguito il codice completo

Di seguito il codice completo che ho compilato controlla se non hai sbagliato qualcosa.
Dall'errore che ti da sembra che si aspetti il begin e invece trova la parola Process.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity dec is
port(
x: in std_logic_vector ( 3 downto 0);
y: out std_logic_vector ( 15 downto 0)
);
end entity dec;

architecture behavior of dec is

signal binary_in:std_logic_vector(3 downto 0);
signal decoder_out:std_logic_vector(15 downto 0);

begin

process(binary_in)
begin
decoder_out<=x"0000";
case binary_in is
when x"0" => decoder_out<= x"0001";
when x"1" => decoder_out<= x"0002";
when x"2"=> decoder_out<=x"0004";
when x"3"=> decoder_out<=x"0008";
when x"4"=> decoder_out<=x"0010";
when x"5"=> decoder_out<=x"0020";
when x"6"=> decoder_out<=x"0040";
when x"7"=> decoder_out<=x"0080" ;
when x"8"=> decoder_out<=x"0100";
when x"9"=> decoder_out<=x"0200";
when x"A"=> decoder_out<=x"0400";
when x"B"=> decoder_out<=x"0800";
when x"C"=> decoder_out<=x"1000";
when x"D"=> decoder_out<=x"2000";
when x"E"=> decoder_out<=x"4000";
when x"F"=> decoder_out<=x"8000";
when others => null;
end case;
end process;

end architecture behavior;

ritratto di Mifert4
Offline
Titolo: User+
Utente+
Ultima visita:
2 anni 30 settimane fa
Utente dal: 28/11/2011
Messaggi: 12
Ok,ora va bene(bastava

Ok,ora va bene(bastava aggiungere il begin prima di process,anche se non capisco perchè).Ma va bene anche senza specificare i due signal subito dopo architecture

ritratto di divivoma
Offline
Titolo: PowerUser
Utente Power
Ultima visita:
17 ore 17 min fa
Utente dal: 02/03/2011
Messaggi: 212
ci va prima perché specifica

ci va prima perché specifica l'inizio dell'architecture se nn sbaglio...infatti guarda anche gli end alla fine come chiudono le diverse strutture inizializzate sopra..

ritratto di Mino_73
Online
Titolo: User++
Utente++
Ultima visita:
5 min 24 sec fa
Utente dal: 27/06/2008
Messaggi: 69
Devi rispettare le specifiche

Devi rispettare le specifiche del vhdl!! La struttura dell'entity e dell'achitettura è ben specificata basta fare una ricerca su internet e prendere un tutorial qualsiasi!! :-)
Nella specifica è riportata tutto ciò che riguarda la posizione e i tipi di dichiarazioni che puoi utilizzare. Strano il fatto che ti compila anche senza la dichiarazione dei due segnali. Non mi risulta che il vhdl ha, come il verilog, la dichiarazione implicita dei segnali. Dai uno sguardo al tuo compilatore e a quale specifica del vhdl fa riferimento a seconda dell'anno della specifica, tipo vhdl 1987, vhdl 1993 o vhdl 2008.

 

 

Login   
 Twitter Facebook LinkedIn Youtube Google RSS

Chi è online

Ultimi Commenti