Ricerca…


Osservazioni

Verilog è un linguaggio di descrizione dell'hardware (HDL) che viene utilizzato per progettare, simulare e verificare i circuiti digitali a livello comportamentale o di trasferimento del registro. È degno di nota per una ragione che lo distingue dai linguaggi di programmazione "tradizionali":

  • Esistono due tipi di assegnamento, blocco e non blocco, ciascuno con i propri usi e semantica.
  • Le variabili devono essere dichiarate come a larghezza singola o con larghezza esplicita.
  • I disegni sono gerarchici, con la possibilità di istanziare i moduli che hanno un comportamento desiderato.
  • Nella simulazione (non tipicamente in sintesi), le variabili wire possono trovarsi in uno dei quattro stati: 0, 1, floating ( z ) e undefined ( x ).

Versioni

Versione Data di rilascio
Verilog IEEE-1364-1995 1995-01-01
Verilog IEEE-1364-2001 2001/09/28
Verilog IEEE-1364.1-2002 2002/12/18
Verilog IEEE-1364-2005 2006-04-07
SystemVerilog IEEE-1800-2009 2009-12-11
SystemVerilog IEEE-1800-2012 2013/02/21

Installazione o configurazione

Le istruzioni dettagliate su come installare o installare Verilog dipendono dallo strumento che si utilizza poiché ci sono molti strumenti Verilog.

introduzione

Verilog è un linguaggio di descrizione dell'hardware (HDL) utilizzato per modellare i sistemi elettronici. Descrive più comunemente un sistema elettronico al livello di trasferimento del registro (RTL) dell'astrazione. Viene anche utilizzato nella verifica di circuiti analogici e circuiti a segnali misti. La sua struttura e i principi fondamentali (come descritto di seguito) sono progettati per descrivere e implementare con successo un sistema elettronico.

  • Rigidità
    Un circuito elettronico è un'entità fisica che ha una struttura fissa e Verilog è adattato per questo. I moduli (modulo), le porte (input / output / inout), le connessioni (fili), i blocchi (@ways), i registri (reg) sono tutti corretti al momento della compilazione. Il numero di entità e interconnessioni non cambia in modo dinamico. C'è sempre un "modulo" al livello più alto che rappresenta la struttura del chip (per la sintesi), e uno a livello di sistema per la verifica.
  • Parallelismo
    Le operazioni simultanee inerenti nel chip fisico sono imitate nella lingua da blocchi sempre (più comuni), iniziali e fork / join.
  module top();
  reg r1,r2,r3,r4; // 1-bit registers
    initial
    begin
      r1 <= 0 ;
    end
    initial
    begin
      fork
         r2 <= 0 ;
         r3 <= 0 ;
      join
    end
     always @(r4)
        r4 <= 0 ;
 endmodule

Tutte le dichiarazioni di cui sopra sono eseguite in parallelo all'interno della stessa unità di tempo.

  • Tempi e sincronizzazione
    Verilog supporta vari costrutti per descrivere la natura temporale dei circuiti. Tempi e ritardi nei circuiti possono essere implementati in Verilog, ad esempio con costrutti #delay. Allo stesso modo, Verilog si adatta anche a circuiti e componenti sincroni e asincroni come flop, latch e logica combinatoria usando vari costrutti, ad esempio blocchi "sempre". Un insieme di blocchi può anche essere sincronizzato tramite un segnale di clock comune o un blocco può essere attivato in base a specifici set di input.

    #10   ;                 // delay for 10 time units
    always @(posedge clk )  // synchronous 
    always @(sig1 or sig2 ) // combinatorial logic  
    @(posedge event1)       // wait for post edge transition of event1
    wait (signal  == 1)     // wait for signal to be 1
    
  • Incertezza
    Verilog supporta parte dell'incertezza inerente ai circuiti elettronici. "X" è usato per rappresentare lo stato sconosciuto del circuito. "Z" è usato per rappresentare lo stato non trascurato del circuito.

    reg1 = 1'bx;
    reg2 = 1'bz;
    
  • Astrazione
    Verilog supporta la progettazione a diversi livelli di astrazione. Il livello più alto di astrazione per un progetto è il Livello di trasferimento di Resistenza (RTL), il successivo è il livello di gate e il più basso il livello di cella (User Define Primitives), l'astrazione RTL è il più comunemente usato. Verilog supporta anche il livello comportamentale di astrazione senza riguardo alla realizzazione strutturale del progetto, utilizzata principalmente per la verifica.

 // Example of a D flip flop at RTL abstraction
module dff (
 clk    , // Clock Input
 reset  , // Reset input
 d       , // Data Input
 q        // Q output
 );
 //-----------Input Ports---------------
 input d, clk, reset ;

 //-----------Output Ports---------------
 output q;

 reg q;

 always @ ( posedge clk)
 if (~reset) begin
   q <= 1'b0;
 end  else begin
   q <= d;
 end

endmodule


// And gate model based at Gate level abstraction 
module and(input x,input y,output o);

wire  w;
// Two instantiations of the module NAND
nand U1(w,x, y); 
nand U2(o, w, w); 

endmodule

// Gate modeled at Cell-level Abstraction
primitive udp_and(
a, // declare three ports
b,
c 
);
output a;   // Outputs
input b,c;  // Inputs 

// UDP function code here
// A = B & C;
table
 // B  C    : A 
    1  1    : 1;
    0  1    : 0;
    1  0    : 0;
    0  0    : 0;
endtable

endprimitive

Ci sono tre casi d'uso principali per Verilog. Determinano la struttura del codice e la sua interpretazione e determinano anche i set di strumenti utilizzati. Tutte e tre le applicazioni sono necessarie per l'implementazione di successo di qualsiasi progetto Verilog.

  1. Design fisico / back-end
    Qui Verilog viene utilizzato principalmente per visualizzare il design come una matrice di porte di interconnessione che implementano la progettazione logica. RTL / logic / Design passa attraverso vari passaggi da sintesi -> posizionamento -> costruzione di un albero di clock -> routing -> DRC -> LVS -> al tapeout. I passaggi e le sequenze precise variano in base alla natura esatta dell'implementazione.
  2. Simulazione
    In questo caso d'uso, l'obiettivo principale è generare vettori di test per convalidare il progetto secondo le specifiche. Il codice scritto in questo caso d'uso non deve essere sintetizzabile e rimane all'interno della sfera di verifica. Il codice qui ricorda più da vicino le strutture software generiche come per / while / do loops, ecc.
  3. Design
    La progettazione implica l'implementazione delle specifiche di un circuito generalmente a livello di astrazione RTL. Il codice Verilog viene quindi fornito per la verifica e viene fornito il codice completamente verificato per l'implementazione fisica. Il codice è scritto usando solo i costrutti sintetizzabili di Verilog. Alcuni stili di codifica RTL possono causare la mancata corrispondenza tra simulazione e sintesi e occorre prestare attenzione per evitarli.

Ci sono due principali flussi di implementazione. Influiranno anche sul modo in cui il codice Verilog viene scritto e implementato. Alcuni stili di codifica e certe strutture sono più adatti in un flusso rispetto all'altro.

  • ASIC Flow (circuito integrato specifico dell'applicazione)
  • FPGA Flow (Field-programmable gate array) - include FPGA e CPLD

Ciao mondo

Questo esempio usa il compilatore di verilog per icarus.

Passaggio 1: crea un file chiamato hello.v

module myModule();

initial
  begin
    $display("Hello World!");   // This will display a message
    $finish ; // This causes the simulation to end.  Without, it would go on..and on.
  end

endmodule

Passaggio 2. Compiliamo il file .v usando icarus:

>iverilog -o hello.vvp hello.v

L'opzione -o assegna un nome al file oggetto di output. Senza questo switch il file di output verrebbe chiamato a.out. Hello.v indica il file sorgente da compilare. Non dovrebbe esserci praticamente alcun output quando si compila questo codice sorgente, a meno che non ci siano errori.

Passaggio 3. Sei pronto per simulare questo programma Verilog di Hello World. Per fare ciò, invoca come tale:

>vvp hello.vvp 
Hello World!
>

Installazione di Icarus Verilog Compiler per Mac OSX Sierra

  1. Installa Xcode dall'App Store.
  2. Installa gli strumenti di sviluppo Xcode
> xcode-select --install

Questo fornirà strumenti da riga di comando di base come gcc e make

  1. Installa porte Mac https://www.macports.org/install.php

Il pacchetto di installazione di OSX Sierra fornirà un metodo open-source per l'installazione e l'aggiornamento di pacchetti software aggiuntivi sulla piattaforma Mac. Pensa yum o apt-get per il Mac.

  1. Installa icarus usando le porte Mac
> sudo port install iverilog
  1. Verifica l'installazione dalla riga di comando
$ iverilog
iverilog: no source files.

Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]
                [-g1995|-g2001|-g2005] [-g<feature>]
                [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]
                [-N file] [-o filename] [-p flag=value]
                [-s topmodule] [-t target] [-T min|typ|max]
                [-W class] [-y dir] [-Y suf] source_file(s)

See the man page for details.
$

Ora sei pronto per compilare e simulare il tuo primo file Verilog su Mac.

Installa GTKWave per la visualizzazione grafica dei dati di simulazione su Mac OSx Sierra

GTKWave è un pacchetto di visualizzazione grafica completamente funzionale che supporta diversi standard di archiviazione dei dati grafici, ma è anche in grado di supportare VCD, che è il formato che verrà prodotto da vvp . Quindi, per prendere GTKWave, hai un paio di opzioni

  1. Vai su http://gtkwave.sourceforge.net/gtkwave.zip e scaricalo. Questa versione è in genere l'ultima.
  2. Se hai installato MacPorts ( https://www.macports.org/ ), esegui semplicemente sudo port install gtkwave . Questo probabilmente vorrai installare sulle dipendenze di. Nota che questo metodo di solito ti offre una versione precedente. Se MacPorts non è installato, è disponibile un esempio di installazione per eseguire questa operazione su questa pagina. Sì! Avrai bisogno di tutti gli strumenti di sviluppo xcode, in quanto questi metodi ti "costruiranno" un GTKWave dal sorgente.

Al termine dell'installazione, ti potrebbe essere chiesto di selezionare una versione python. Avevo già installato 2.7.10, quindi non ne ho mai "selezionato" uno nuovo.

A questo punto puoi avviare gtkwave dalla riga di comando con gtkwave . Quando viene avviato, potrebbe essere richiesto di installare o aggiornare XQuarts. Fare così. Nel mio caso è installato XQuarts 2.7.11.

Nota: ho davvero bisogno di riavviare per ottenere XQuarts correttamente, quindi ho digitato di nuovo gtkwave e l'applicazione si presenta.

Nel prossimo esempio creerò due file indipendenti, un testbench e un modulo da testare e useremo gtkwave per visualizzare il progetto.

Utilizzando Icarus Verilog e GTKWaves per simulare e visualizzare graficamente un disegno

Questo esempio utilizza Icarus e GTKWave. Le istruzioni di installazione per questi strumenti su OSx sono fornite altrove in questa pagina.

Iniziamo con il design del modulo. Questo modulo è un display da BCD a 7 segmenti. Ho codificato il design in modo ottuso semplicemente per darci qualcosa che si rompe facilmente e possiamo passare a fissarlo a livello grafico. Quindi abbiamo un orologio, reset, un ingresso dati 4 che rappresenta un valore BCD e un'uscita a 7 bit che rappresenta il display a sette segmenti. Crea un file chiamato bcd_to_7seg.v e posiziona la sorgente sottostante.

module bcd_to_7seg (
   input clk,
   input reset,
   input [3:0] bcd,
   output [6:0] seven_seg_display

);
   parameter TP = 1;
   reg seg_a;
   reg seg_b;
   reg seg_c;
   reg seg_d;
   reg seg_e;
   reg seg_f;
   reg seg_g;

   
   always @ (posedge clk or posedge reset)
      begin
      if (reset)
         begin
            seg_a <= #TP 1'b0;
            seg_b <= #TP 1'b0;
            seg_c <= #TP 1'b0;
            seg_d <= #TP 1'b0;
            seg_e <= #TP 1'b0;
            seg_f <= #TP 1'b0;
            seg_g <= #TP 1'b0;
         end
      else
         begin
            seg_a <= #TP  ~(bcd == 4'h1 || bcd == 4'h4);
            seg_b <= #TP  bcd < 4'h5 || bcd > 6;
            seg_c <= #TP   bcd != 2;
            seg_d <= #TP   bcd == 0 || bcd[3:1] == 3'b001 || bcd == 5 || bcd == 6 || bcd == 8;
            seg_e <= #TP  bcd == 0 || bcd == 2 || bcd == 6 || bcd == 8;
            seg_f <= #TP  bcd == 0 || bcd == 4 || bcd == 5 || bcd == 6 || bcd > 7;
            seg_g <= #TP  (bcd > 1 && bcd < 7) || (bcd > 7);
         end
    end
 
    assign seven_seg_display = {seg_g,seg_f,seg_e,seg_d,seg_c,seg_b,seg_a};
endmodule

Successivamente, abbiamo bisogno di un test per verificare se questo modulo funziona correttamente. La dichiarazione del caso nel banco di prova è in realtà più facile da leggere a mio parere e più chiara su ciò che fa. Ma non volevo mettere la stessa indicazione del caso nel design E nel test. Questa è una cattiva pratica. Piuttosto due progetti indipendenti vengono utilizzati per convalidare l'un l'altro.

Con il codice qui sotto, noterai due righe $dumpfile("testbench.vcd"); e $dumpvars(0,testbench); . Queste linee sono ciò che crea il file di output VCD che verrà utilizzato per eseguire l'analisi grafica del progetto. Se li lasci fuori, non otterrai un file VCD generato. Creare un file chiamato testbench.v e posizionare la fonte sottostante in esso.

`timescale 1ns/100ps
module testbench;
reg clk;
reg reset;
reg [31:0] ii;
reg [31:0] error_count;
reg [3:0] bcd;
wire [6:0] seven_seg_display; 
parameter TP = 1;
parameter CLK_HALF_PERIOD = 5;
 
   // assign clk = #CLK_HALF_PERIOD ~clk;  // Create a clock with a period of ten ns
   initial
   begin
     clk = 0;
     #5;
     forever clk = #( CLK_HALF_PERIOD )  ~clk;
   end

   initial
     begin
       $dumpfile("testbench.vcd");
       $dumpvars(0,testbench);
       // clk  = #CLK_HALF_PERIOD ~clk; 
       $display("%0t, Reseting system", $time);
       error_count = 0;
       bcd  = 4'h0;
       reset = #TP 1'b1;
       repeat (30) @ (posedge clk);
       reset  = #TP 1'b0;
       repeat (30) @ (posedge clk);
       $display("%0t, Begin BCD test", $time); // This displays a message


       for (ii = 0; ii < 10; ii = ii + 1)
          begin
          repeat (1) @ (posedge clk);
          bcd  = ii[3:0];
          repeat (1) @ (posedge clk); 
          if (seven_seg_display !== seven_seg_prediction(bcd)) 
             begin
                $display("%0t, ERROR: For BCD %d, module output 0b%07b does not match prediction logic value of 0b%07b.",$time,bcd, seven_seg_display,seven_seg_prediction(bcd));
                error_count = error_count + 1;
             end
          end
       $display("%0t, Test Complete with %d errors", $time, error_count);
       $display("%0t, Test %s", $time, ~|error_count ? "pass." : "fail.");
       $finish ; // This causes the simulation to end.
     end


parameter SEG_A = 7'b0000001;
parameter SEG_B = 7'b0000010;
parameter SEG_C = 7'b0000100;
parameter SEG_D = 7'b0001000;
parameter SEG_E = 7'b0010000;
parameter SEG_F = 7'b0100000;
parameter SEG_G = 7'b1000000;

function [6:0] seven_seg_prediction;
   input [3:0] bcd_in;

   //    +--- A ---+
   //    |         |
   //    F         B
   //    |         |
   //    +--- G ---+
   //    |         |
   //    E         C
   //    |         |
   //    +--- D ---+

   begin
      case (bcd_in)
         4'h0: seven_seg_prediction = SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F;
         4'h1: seven_seg_prediction = SEG_B | SEG_C;
         4'h2: seven_seg_prediction = SEG_A | SEG_B | SEG_G | SEG_E | SEG_D;
         4'h3: seven_seg_prediction = SEG_A | SEG_B | SEG_G | SEG_C | SEG_D;
         4'h4: seven_seg_prediction = SEG_F | SEG_G | SEG_B | SEG_C;
         4'h5: seven_seg_prediction = SEG_A | SEG_F | SEG_G | SEG_C | SEG_D;
         4'h6: seven_seg_prediction = SEG_A | SEG_F | SEG_G | SEG_E | SEG_C | SEG_D;
         4'h7: seven_seg_prediction = SEG_A | SEG_B | SEG_C;
         4'h8: seven_seg_prediction = SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G;
         4'h9: seven_seg_prediction = SEG_A | SEG_F | SEG_G | SEG_B | SEG_C;
         default: seven_seg_prediction = 7'h0;
      endcase
   end
endfunction


bcd_to_7seg u0_bcd_to_7seg (
.clk               (clk),
.reset             (reset),
.bcd               (bcd),
.seven_seg_display (seven_seg_display)
);


endmodule

Ora che abbiamo due file, un testbench.v e bcd_to_7seg.v, abbiamo bisogno di compilare, elaborare usando Icarus. Per fare questo:

$ iverilog -o testbench.vvp testbench.v bcd_to_7seg.v

Quindi dobbiamo simulare

$ vvp testbench.vvp 
LXT2 info: dumpfile testbench.vcd opened for output.
0, Reseting system
6000, Begin BCD test
8000, Test Complete with          0 errors
8000, Test pass. 

A questo punto se si desidera validare il file è in fase di test, andare nel file bcd_2_7seg.v e spostare un po 'della logica intorno e ripetere quei primi due passaggi.

Come esempio cambio la riga seg_c <= #TP bcd != 2; a seg_c <= #TP bcd != 4; . Ricompila e simula come segue:

$ iverilog -o testbench.vvp testbench.v bcd_to_7seg.v
$ vvp testbench.vvp 
LXT2 info: dumpfile testbench.vcd opened for output.
0, Reseting system
6000, Begin BCD test
6600, ERROR: For BCD  2, module output 0b1011111 does not match prediction logic value of 0b1011011.
7000, ERROR: For BCD  4, module output 0b1100010 does not match prediction logic value of 0b1100110.
8000, Test Complete with          2 errors
8000, Test fail.
$

Così ora, consente di visualizzare la simulazione utilizzando GTKWave. Dalla riga di comando, emettere a

gtkwave testbench.vcd &

Quando appare la finestra GTKWave, nella casella in alto a sinistra vedrai il nome del modulo testbench. Cliccalo. Questo rivelerà i sottomoduli, le attività e le funzioni associate a quel file. Fili e registri appariranno anche nella scatola in basso a sinistra.

Ora trascina, clk, bcd, error_count e seven_seg_display nella casella del segnale accanto alla finestra della forma d'onda. I segnali verranno ora tracciati. Error_count ti mostrerà quale particolare input BCD ha generato l'output di sette_seg_display errato.

Ora sei pronto per risolvere graficamente un bug di Verilog.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow