Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Verilog

Verilog menghasilkan blok

Sebuah generate block memungkinkan untuk menggandakan instance modul atau melakukan instantiasi bersyarat dari modul apa pun. Ini memberikan kemampuan untuk desain yang akan dibangun berdasarkan parameter Verilog. Pernyataan ini sangat cocok ketika operasi yang sama atau contoh modul perlu diulang beberapa kali atau jika kode tertentu harus dimasukkan secara kondisional berdasarkan parameter Verilog yang diberikan.

Sebuah generate blok tidak boleh berisi port, parameter, specparam deklarasi atau specify blok. Namun, item modul lain dan blok pembangkit lainnya diperbolehkan. Semua instantiasi yang dihasilkan dikodekan dalam module dan di antara kata kunci generate dan endgenerate .

Instansiasi yang dihasilkan dapat memiliki salah satu modul, penugasan berkelanjutan, always atau initial blok dan primitif yang ditentukan pengguna. Ada dua jenis konstruk generate - loop dan conditional.

Hasilkan untuk loop

Setengah penambah akan dipakai N kali dalam modul desain tingkat atas lain yang disebut my_design menggunakan generate untuk konstruksi loop. Variabel loop harus dideklarasikan menggunakan kata kunci genvar yang memberi tahu alat bahwa variabel ini akan digunakan secara khusus selama elaborasi blok generate.

  
  
// Design for a half-adder
module ha ( input   a, b,
            output  sum, cout);
 
  assign sum  = a ^ b;
  assign cout = a & b;
endmodule

// A top level design that contains N instances of half adder
module my_design 
	#(parameter N=4) 
		(	input [N-1:0] a, b,
			output [N-1:0] sum, cout);
			
	// Declare a temporary loop variable to be used during
	// generation and won't be available during simulation
	genvar i;
	
	// Generate for loop to instantiate N times
	generate 
		for (i = 0; i < N; i = i + 1) begin
          ha u0 (a[i], b[i], sum[i], cout[i]);
		end
	endgenerate
endmodule

  

Testbench

Parameter testbench digunakan untuk mengontrol jumlah instance half adder dalam desain. Ketika N adalah 2, my_design akan memiliki dua instance setengah penambah.

  
  
module tb;
	parameter N = 2;
  reg  [N-1:0] a, b;
  wire [N-1:0] sum, cout;
  
  // Instantiate top level design with N=2 so that it will have 2
  // separate instances of half adders and both are given two separate
  // inputs
  my_design #(.N(N)) md( .a(a), .b(b), .sum(sum), .cout(cout));
  
  initial begin
    a <= 0;
    b <= 0;
    
    $monitor ("a=0x%0h b=0x%0h sum=0x%0h cout=0x%0h", a, b, sum, cout);
    
    #10 a <= 'h2;
    		b <= 'h3;
    #20 b <= 'h4;
    #10 a <= 'h5;
  end
endmodule

  

a[0] dan b[0] memberikan output jumlah[0] dan cout[0] sedangkan a[1] dan b[1] memberikan output jumlah[1] dan cout[1].

Log Simulasi
ncsim> run
a=0x0 b=0x0 sum=0x0 cout=0x0
a=0x2 b=0x3 sum=0x1 cout=0x2
a=0x2 b=0x0 sum=0x2 cout=0x0
a=0x1 b=0x0 sum=0x1 cout=0x0
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit

Lihat bahwa RTL yang diuraikan memang memiliki dua instance setengah penambah yang dihasilkan oleh generate blokir.

Hasilkan jika

Di bawah ini adalah contoh menggunakan if else di dalam generate konstruksi untuk memilih antara dua implementasi multiplexer yang berbeda. Desain pertama menggunakan assign pernyataan untuk mengimplementasikan mux sedangkan desain kedua menggunakan case penyataan. Parameter yang disebut USE_CASE didefinisikan dalam modul desain tingkat atas untuk memilih di antara dua pilihan.

  
  
// Design #1: Multiplexer design uses an "assign" statement to assign 
// out signal 
module mux_assign ( input a, b, sel,
                   output out);
  assign out = sel ? a : b;
  
  // The initial display statement is used so that 
  // we know which design got instantiated from simulation
  // logs  
  initial
  	$display ("mux_assign is instantiated");
endmodule

// Design #2: Multiplexer design uses a "case" statement to drive
// out signal
module mux_case (input a, b, sel,
                 output reg out);
  always @ (a or b or sel) begin
  	case (sel)
    	0 : out = a;
   	 	1 : out = b;
  	endcase
  end
  
  // The initial display statement is used so that 
  // we know which design got instantiated from simulation
  // logs
  initial 
    $display ("mux_case is instantiated");
endmodule

// Top Level Design: Use a parameter to choose either one
module my_design (	input a, b, sel,
         			output out);
  parameter USE_CASE = 0;
  
  // Use a "generate" block to instantiate either mux_case
  // or mux_assign using an if else construct with generate
  generate
  	if (USE_CASE) 
      mux_case mc (.a(a), .b(b), .sel(sel), .out(out));
    else
      mux_assign ma (.a(a), .b(b), .sel(sel), .out(out));
  endgenerate
    
endmodule

  

Testbench

Testbench membuat instance modul tingkat atas my_design dan menyetel parameter USE_CASE ke 1 sehingga membuat instance desain menggunakan case pernyataan.

  
  
module tb;
	// Declare testbench variables
  reg a, b, sel;
  wire out;
  integer i;
  
  // Instantiate top level design and set USE_CASE parameter to 1 so that
  // the design using case statement is instantiated
  my_design #(.USE_CASE(1)) u0 ( .a(a), .b(b), .sel(sel), .out(out));
  
  initial begin
  	// Initialize testbench variables
  	a <= 0;
    b <= 0;
    sel <= 0;
    
    // Assign random values to DUT inputs with some delay
    for (i = 0; i < 5; i = i + 1) begin
      #10 a <= $random;
      	  b <= $random;
          sel <= $random;
      $display ("i=%0d a=0x%0h b=0x%0h sel=0x%0h out=0x%0h", i, a, b, sel, out);
    end
  end
endmodule

  

Ketika parameter USE_CASE adalah 1, dapat dilihat dari log simulasi bahwa desain multiplexer menggunakan case pernyataan diinstansiasi. Dan ketika USE_CASE adalah nol, desain multiplexer menggunakan assign pernyataan diinstansiasi. Ini terlihat dari pernyataan tampilan yang dicetak di log simulasi.

Log Simulasi
// When USE_CASE = 1
ncsim> run
mux_case is instantiated
i=0 a=0x0 b=0x0 sel=0x0 out=0x0
i=1 a=0x0 b=0x1 sel=0x1 out=0x1
i=2 a=0x1 b=0x1 sel=0x1 out=0x1
i=3 a=0x1 b=0x0 sel=0x1 out=0x0
i=4 a=0x1 b=0x0 sel=0x1 out=0x0
ncsim: *W,RNQUIE: Simulation is complete.

// When USE_CASE = 0
ncsim> run
mux_assign is instantiated
i=0 a=0x0 b=0x0 sel=0x0 out=0x0
i=1 a=0x0 b=0x1 sel=0x1 out=0x0
i=2 a=0x1 b=0x1 sel=0x1 out=0x1
i=3 a=0x1 b=0x0 sel=0x1 out=0x1
i=4 a=0x1 b=0x0 sel=0x1 out=0x1
ncsim: *W,RNQUIE: Simulation is complete.

Buat Kasus

Kasus hasilkan memungkinkan modul, blok awal dan blok selalu dipakai dalam modul lain berdasarkan case ekspresi untuk memilih salah satu dari banyak pilihan.

  
  
// Design #1: Half adder
module ha (input a, b,
           output reg sum, cout);
  always @ (a or b)
  {cout, sum} = a + b;
  
  initial
    $display ("Half adder instantiation");
endmodule

// Design #2: Full adder
module fa (input a, b, cin,
           output reg sum, cout);
  always @ (a or b or cin)
  {cout, sum} = a + b + cin;
  
    initial
      $display ("Full adder instantiation");
endmodule

// Top level design: Choose between half adder and full adder
module my_adder (input a, b, cin,
                 output sum, cout);
  parameter ADDER_TYPE = 1;
  
  generate
    case(ADDER_TYPE)
      0 : ha u0 (.a(a), .b(b), .sum(sum), .cout(cout));
      1 : fa u1 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
    endcase
  endgenerate
endmodule

  

Testbench

  
  
module tb;
  reg a, b, cin;
  wire sum, cout;
  
  my_adder #(.ADDER_TYPE(0)) u0 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
  
  initial begin
    a <= 0;
    b <= 0;
    cin <= 0;
    
    $monitor("a=0x%0h b=0x%0h cin=0x%0h cout=0%0h sum=0x%0h",
             a, b, cin, cout, sum);
    
    for (int i = 0; i < 5; i = i + 1) begin
      #10 a <= $random;
      b <= $random;
      cin <= $random;
    end
  end
endmodule

  

Perhatikan bahwa karena setengah penambah dipakai, cin tidak memiliki efek apa pun pada jumlah dan cout keluaran.

Log Simulasi
ncsim> run
Half adder instantiation
a=0x0 b=0x0 cin=0x0 cout=00 sum=0x0
a=0x0 b=0x1 cin=0x1 cout=00 sum=0x1
a=0x1 b=0x1 cin=0x1 cout=01 sum=0x0
a=0x1 b=0x0 cin=0x1 cout=00 sum=0x1
ncsim: *W,RNQUIE: Simulation is complete.


Verilog

  1. Tutorial Verilog
  2. Rangkaian Verilog
  3. Verilog - Dalam kulit kacang
  4. Tugas Verilog
  5. Pemblokiran &Non-Pemblokiran Verilog
  6. Fungsi Verilog
  7. Tugas Verilog
  8. Generator Jam Verilog
  9. Fungsi Matematika Verilog
  10. Format Waktu Verilog