Questo argomento contiene 11 risposte, ha 3 partecipanti, ed è stato aggiornato da  divivoma 2 anni, 10 mesi fa.

Stai vedendo 12 articoli - dal 1 a 12 (di 12 totali)
  • Autore
    Articoli
  • #58496

    Mifert4
    Membro

    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?

    #70624

    Mino_73
    Membro

    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.

    #70629

    Mifert4
    Membro

    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" ?

    #70630

    Mino_73
    Membro

    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.

    #70631

    Mifert4
    Membro

    Perfetto,grazie mille per i chiarimenti

    #70635

    Mifert4
    Membro

    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

    #70637

    Mino_73
    Membro

    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 #.

    #70641

    Mifert4
    Membro

    a me invece dà questo errore: ” ‘begin’ is expected instead of ‘process’ “

    #70680

    Mino_73
    Membro

    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;

    #70681

    Mifert4
    Membro

    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

    #70684

    divivoma
    Membro

    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..

    #70683

    Mino_73
    Membro

    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.

Stai vedendo 12 articoli - dal 1 a 12 (di 12 totali)

Devi aver eseguito l’accesso per poter rispondere a questa discussione.