Wednesday, April 13, 2022

Configurable RTL Design Using Verilog Generate Constructs


Configurable RTL Design Using Verilog Generate Constructs

- Generate statement is a powerful construct to write configurable, synthesizable RTL

- Useful to create multiple instantiations of modules and code or conditionally instantiate blocks of code

- The generate statement simplifies the description of regular design structures.

Three usage forms of Generate Construct -

1) generate loop - to iteratively create multiple instances of a piece of code

2) if-generate and - Conditional include blocks of code

3) case-generate




1) Generate Loop Syntax and Example :

Syntax :

// Declare the loop variable

genvar <name>

// Code for the generate block

generate

for (<initial_condition>; <stop_condition>; <increment>)

begin

// Code to Execute

end

endgenerate




Example:

// Gray2Binary Code Converter Using Generate Construct

module Gary2Binary #( parameter SIZE = 8) (

input [SIZE-1 : 0] gray,

output [SIZE-1:0] binary

);

genvar gen;

generate

for (gen = 0; gen < SIZE; gen =gen+1)

begin : Gen Num

assign binary [gen] = ^gray[SIZE-1 : gen];

end

endgenerate

endmodule




Note:

- generate , endgenerate keywords are actually optional but good for readability

- Generate block in a Verilog generate loop can be named or unnamed. If it is named, then an array of generate block instances is created. Some tools warn you about unnamed generate loops, so it is good practice to always name them.

- Temporary loop variable (genvar) is only available during code generation and would not be available during simulation




2) if-generate (Conditional Generate Construct) Syntax and Example :

Syntax:

generate

if(<condition1>) begin

// Code to Execute

end

else if (<condition2>) begin

// Code to Execute

end

else begin

// Code to Execute

end

endgenerate




Example :

module mux1_assign (

input a, b , sel;

output out

);




assign out = sel ? a : b ;

endmodule



module mux2_case (

input a, b, sel;

output reg out

);

always @ (*)

begin

case(sel)

0 : out = a;

1 : out = b;

endcase

endmodule




module top_design (

input a, b, sel;

output out

);

parameter MUX_SELECT = 0;




generate

if(MUX_SELECT)

mux1_assign ma(.a(a), .b(b), .sel(sel), .out(out));

else

mux2_case mc(.a(a), .b(b), .sel(sel), .out(out));

endgenerate

endmodule



3) case-generate (Conditional Generate Construct) Syntax and Example :

Syntax:

generate

case(<variable >)

<value1> : begin

//This branch executes when <variable> = <value1>

end

<value2> : begin

//This branch executes when <variable> = <value2>

end

default : begin

// This branch executes in all other cases

end

endcase

endgenerate




Example:




module HA(

input a, b;

output reg sum, cout

);

always @(*)

begin

{sum, cout} = a + b;

end

endmodule



module FA(

input a, b, cin;

output reg sum, cout

);

always @(*)

begin

{sum, cout} = a + b + cin;

end

endmodule




module top_adder(

input a, b, cin;

output sum, cout

);



parameter SELECT_ADDER = 0;

generate

case (SELECT_ADDER)

0 : HA HA_ADDER(.a(a), .b(b), .sum(sum), .cout(cout));

else

1 : FA FA_ADDER(.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));

endgenerate

endmodule




--------------------------------------Happy Learning-----------------------------------------------------------

















0 Comments:

Post a Comment