===== Esempi Verilog =====
 
Questi sono i piccoli esempi Verilog presentati nella lezione del 16 maggio. 

==== Commutatore ====
Commutatore da due ingressi di un bit ciascuno. 
=== Versione behavioral===
<code verilog commutatore.vl>
module commutatore(output z, input x, input y, input alpha);

   assign z = ((~alpha) ? x : y);

endmodule
</code>
=== Versione tabella di verità ===
<code verilog komm.vl>
primitive commutatore(output z, input x, input y, input alpha);

   table
      0 ? 0 : 0;
      1 ? 0 : 1;

      ? 0 1 : 0;
      ? 1 1 : 1;

   endtable
endprimitive
</code>

=== Versione rete di porte logiche ===
<code verilog kp.vl>
module commutatore(output z, input x, input y, input alpha); 

   wire notalpha;
   wire t1;
   wire t2;
   wire res;
   
   
   not(notalpha,alpha);
   and(t1,notalpha,x);
   and(t2,alpha,y);

   or(res,t1,t2);

   assign #2 z = res;
   
endmodule
</code>

=== Programma di prova ===
<code verilog prova_commutatore.vl>
// 
// definizione di comodo per stabilire il range temporale 
// 
`timescale 1ns / 1ps

// nome del modulo; senza parametri perchè è quello di test
module prova_commutatore();

  //
  // registri che conterranno i valori di input alla rete da testare
  //
  reg x; 
  reg y; 
  reg alpha;

  // 
  // filo per l'output della rete da testare (potrebbe anche essere reg)
  //
  wire z;

  // 
  // istanziazione della rete (non è una chiamata di procedura!)
  // i parametri attuali vengono collegati come specificato mediante 
  // i parametri formali nella definizione del modulo esIII4
  // prima delle parentesi tonde dei parametri troviamo il nome del modulo
  // istanziato (serve per distinguere fra istanziazioni diverse)
  // 
  commutatore k1(z,x,y,alpha);

  // 
  // statement da eseguire all'inizio della simulazione 
  // 
  initial
  begin
    
    // file di ouput per la visualizzazione del comportamento
    $dumpfile("prova_commutatore.vcd");
    // esegui il dump dei cambiamenti di tutte le variabili in gioco
    $dumpvars; 

    // assegnamento iniziale dei registri di input alla rete
    x = 0; 
    y = 1; 
    alpha = 0; 

    #10 alpha = 1; 
    #10 x = 1;
    #10 y = 0; 
    #10 alpha = 0; 
    #10 alpha = 1; 

    // attendi altri 10 nsec e termina la simulazione
    // (producendo il .vcd con il dump dei cambiamenti delle variabili)
    #10 $finish;

  // fine del (blocco di) comando da eseguire all'inizio della simulazione
  end

// fine del modulo di test
endmodule
</code>

=== Makefile ===
<code script makefile>
SRC = 	commutatore.vl prova_commutatore.vl
OBJ =   prova_commutatore

compile:	$(SRC)
	iverilog $(SRC) -o $(OBJ)

run:	compile
	./$(OBJ)

view:	run
	gtkwave $(OBJ).vcd

clean:	
	rm -f $(OBJ) $(OBJ).vcd
</code>

==== Clock ====

=== Modulo generatore clock ===
<code verilog clock.vl>
module gen_clock(clock); 

  output reg clock; 

  initial
  begin
    clock = 0; 
  end

  always 
  begin
    if(clock==0) 
      #17 clock = 1; 
    else 
      #1 clock = 0; 
  end

endmodule
</code>

=== Test bench ===
<code verilog prova_clock.vl>
module prova_clock();

  wire clock;

  gen_clock my_clock(clock);

  initial 
  begin
    $dumpfile("prova_clock.vcd");
    $dumpvars;

    #50 $finish; 

  end
endmodule
</code>

==== Memoria ====

=== Modulo memoria ===
<code verilog mem.vl>
module memoria # (parameter N=6, M=32) ( 
  output reg [M-1:0] data_out,
  input clock, 
  input beta,
  input [N-1:0] address, 
  input [M-1:0] data_in
); 

  reg [M-1:0]mem_bank[2**N-1:0];
  reg [N:0]i; 

  initial
    begin
       for(i=0; i<2**N; i=i+1) 
	 mem_bank[i]=0;
    end
   
   always @ (posedge clock) 
     begin
	if(beta)
	  mem_bank[address] = data_in; 
     end
   
   always @ (negedge clock)
     begin
	data_out = mem_bank[address]; 
     end
endmodule
</code>

=== Test bench ===
<code verilog prova_mem.vl>
`timescale 1ns / 1ps

module prova_mem();

`define IN  4
`define N  32

  wire [`N-1:0]out0;
  reg beta; 
  reg clock; 
  reg [`IN-1:0]addr;
  reg [`N-1:0]in0;

  memoria #(`IN,`N) memoria(out0,clock,beta,addr,in0);

   always
   begin
     if(clock) 
	 #5 clock = ~clock;
     else
	 #10 clock = ~clock; 
   end

  initial
  begin
    $dumpfile("prova_mem.vcd");
    $dumpvars(1,prova_mem);

    clock = 0; 
    beta = 0; 
    addr = 0; 

    #10 in0 = 127;
    #10 beta = 1; 
    #12 beta = 0; 
    #10 addr = addr+1;
    #10 in0 = 255; 
    #10 beta = 1; 
    #10 beta = 0; 
  
    #20 $finish;
  
  end

endmodule
</code>