Strumenti Utente

Strumenti Sito


informatica:ae:reti_combinatorie

Reti Combinatorie in Verilog

Per realizzare una rete combinatoria in Verilog abbiamo due modi:

  • utilizzare una tabella di verità
  • utilizzare un'espressione dell'algebra booleana

Definizione mediante tabella di verità

Intestazione del modulo

Si definisce un modulo di tipo “primitive”, ovvero un modulo racchiuso fra le due righe

   primitive nomedelmodulodadefinire(listadeiparametriinuscitaeiningresso);
   endprimitive

Il nome del modulo è una stringa qualunque. La lista dei parametri dichiara un parametro come

   [input|output] nomeparametro

Un modulo primitive può definire un tabella di verità che produce un solo bit in uscita. Per ogni bit di una funzione che produce un'uscita a più bit va definito un modulo primitive diverso. Il modulo deve avere tante variabili in ingresso quanti sono gli ingressi del modulo.

Esempio di definizione di un modulo commutatore a due vie con ingressi da 1 bit:

primitive commutatoreADueVie32(output z, input x, input y, input alpha); 
   ...
endprimitive

Per prassi, i parametri di output si indicano prima di quelli di input.

Corpo del modulo

Si definisce una tabella di verità di n variabili di ingresso e una variabile di uscita elencando righe di n valori delle variabili separate da spazi seguite dai due punti, dal valore corrispondente della variabile di uscita e dal punto e virgola fra le parole chiave “table” e “endtable”. Ad esempio:

table
  0 0 : 0 ; 
  0 1 : 1 ; 
  1 0 : 1 ; 
  1 1 : 1 ;
endtable

definisce l'OR di due variabili da un bit.

Valori “don't care” nella tabella di verità possono essere indicati con il punto interrogativo.

Ad esempio:

primitive k(output z, input alpha, input x, input y); 
  table
    0 1 ? : 1;
    0 0 ? : 0;
    1 ? 1 : 1; 
    1 ? 0 : 0; 
  endtable
endprimitive

definisce il commutatore a due vie da un bit.

Definizione mediante espressione dell'algebra booleana

Intestazione del modulo

Si definisce un modulo di tipo “module”, ovvero un modulo racchiuso fra le due righe

   module nomedelmodulodadefinire(listadeiparametriinuscitaeiningresso);
   endmodule

Il nome del modulo è una stringa qualunque. La lista dei parametri dichiara un parametro come

   [input|output] ["["dimensioniInBit"]"]nomeparametro

dove le dimensioni in bit vengono date con un'espressione che comprende l'indice del bit più significativo, seguito dai due punti, seguito dall'indice del bit meno significativo. Ad esempio

   input [1:0]alpha

indica una variabile in ingresso da due bit, il cui bit più significativo è

   alpha[1]

e quello meno significativo è

   alpha[0]

Esempio di definizione di un modulo commutatore a due vie con ingressi da 2 bit:

module commutatoreADueVie2bit(output [1:0]z, input [1:0]x, input [1:0]y, input alpha); 
   ...
endmodule

Il corpo del modulo può contenere una o più istruzioni di “assign”

assign nomeVar = espressioneBooleana; 

dove il nome della variabile da assegnare denota un valore di un bit e l'espressione booleana usa i simboli “&” per l'and “+” per l'or e “~” per il not.

Dunque il commutatore di cui abbiamo dato l'intestazione può essere completato come segue:

module commutatoreADueVie2bit(output [1:0]z, input [1:0]x, input [1:0]y, input alpha); 
   
   assign z[1] = ((~alpha) & x[1]) + (alpha & y[1]);
   assign z[0] = ((~alpha) & x[0]) + (alpha & y[0]);
   
endmodule

Lo statement “assign” è detto assegnamento continuo e il significato è (informalmente) fai in modo che la variabile assegnata valga in continuazione quanto vale l'espressione. Se le variabili dell'espressione cambiano, il valore della variabile deve cambiare di conseguenza immediatamente.

Utilizzo di un modulo rete combinatoria

Un modulo, definito come “primitive” o “module” può essere utilizzato dichiarandone un'istanza, ovvero nominandone il nome utilizzato per la definizione, dando un nome all'istanza del modulo e passando una lista di parametri attuali:

   commutatoreADueVie2bit   K1(z1,xx,yy, a); 

definisce un'istanza del modulo “commutatoreADueVie2bit” che si chiama “K1” e che associa al parametro formale in uscita “z” il parametro attuale “z1”, al formale “x” l'attuale “xx”, etc.

Test di una rete combinatoria

Definizione del programma di test

Definiamo un modulo senza parametri, che costituirà il “main” della nostra simulazione. All'interno del modulo

  • dichiariamo tante variabili di tipo “wire” quante sono le uscite del modulo che si vuole testare. Una variabile di questo tipo rappresenta un “filo” del nostro circuito. Se ne può vedere il valore ma non gli si può assegare il valore. Il valore sarà asseganto indicando il wire in corrispondenza di una delle variabili di uscita del modulo. Le variabili wire possono avere una dimensione in bit, indicata con la solita notazione [indiceBitPiàSignificativo:indiceBitMenoSignificativo] (Parte I nel listato che segue)
  • dichiariamo tanti variabili di tipo “reg” (registro) quanti sono gli input del modulo da testare. Queste serviranno ad istanziare i parametri di ingresso del modulo. Una variabile di tipo registro può essere assegnata con un valore anche più volte, come una normale variabile dei linguaggi di programmazione (Parte II nel listato che segue)
  • dichiariamo un'istanza del modulo da testare, utilizzando i wire per i parametri attuali in uscita e i reg per i parametri attuali in ingresso al modulo (Parte III del listato che segue
  • dichiariamo il corpo del programma che testerà il nostro modulo, indicandolo fre le parole chiave “begin” ed “end” immediatemente dopo la parola chiave “initial” (Parte IV del listato che segue). All'interno del corpo del nostro programma di prova:
    • diamo delle direttive che indicano dove deve essere salvato il risultato della simulazione del nostro modulo (cioè l'output del nostro modulo “main”). Questo avviene utilizzando le direttive
      $dumpfile("nomeFile.vcd"); $dumpvars;

      (Parte V del listato che segue)

    • assegnamo valori alle variabili di ingresso (reg) utilizzando statement tipo
       in = 1; alpha=0;

      (Parte VI nel listato che segue)

    • eventualmente assegnamo altri valori alle varibili con uno statement
       #10 in=0

      il cui significato è attendi 10 unità del tempo di simulazione e poi assegna a in il valore 0 (Parte VII nel listato che segue)

    • dichiariamo la fine della simulazione con la direttiva
      $finish

      (Parte VIII nel listato che segue)

Listato del programma di prova

module prova_commutatoreDueVie2bit(); 


  wire [1:0]zz;                             // Parte I
  
  reg a;			            // Parte II
  reg [1:0]x1;
  reg [1:0]x2;
  
  commutatoreADueVie2bit K1(zz,x1,x2,a);    // Parte III
  
  initial                                   // Parte IV
     begin
     
       $dumpfile("prova_comm.vcd");         // Parte V
       $dumpvars;
     
     
       x1 = 2'b00;                          // Parte VI
       x2 = 2'b11;                          // 2'bxx indica un numero binario (per via del b) di due cifre 
                                            // per via del 2' con valore xx 
                                            // 2'hff denoterebbe 255 in decimale (due cifre esadecimali (h))
                                            
       a = 0;                               // 0 è inteso come decimale
       
       #5 a = 1;                            // PArte VII
       
       #10 x2 = 2'b10; 
       
       #10 $finish;                         // Parte VIII
     end
    
endmodule

Compilazione

Si compila il programma di test insieme a tutti i file che contengono i moduli instanziati nel test con il comando

 iverilog main.vl modulo1.vl ... modulon.vl -o testmain

Run del test

Si fa girare la simulazione del test eseguendo il programma compilato al passo precedente

 ./testmain

Visualizzazione dei risultati

Si visualizzano i risultati invocando gtkwave sul file indicato nella dumpfile

gtkwave prova_comm.vcd

In particolare, dopo l'apertura dell'iterfaccia grafica di gtkwave occorre cliccare sul nome del modulo nel box in alto a sinistra (prova_commutatoreDueVie2bit nel nostro caso) dopo di che nel box sotto a sinistra appariranno i nomi delle variabili che possiamo selezionare e con il bottone “append” inserire nel box di destra dove ne verrà visualizzato il valore col passare del tempo di simulazione.

informatica/ae/reti_combinatorie.txt · Ultima modifica: 18/10/2013 alle 08:26 (6 anni fa) da Marco Danelutto