1

In a system verilog design, I have a top-module, sub-module and a sub-sub module. sub-sub module instantiated in sub-module instantiated in top module.Top module also has an instance of sub-sub module.The hierarchy tree is shown below

enter image description here

The sub-sub module definition has some code written in a 'ifndef block like this

module sub_sub()
{
...........
`ifndef OFF
<code to avoid>
`endif
...........
}

How can I disable the code to avoid only in sub-sub module instance1 during compilation? I used `define OFF in sub-module instance but it disables code to avoid from all instances.

vishnu varkala
  • 121
  • 2
  • 2
  • 7

3 Answers3

2

The cleaner solution is to pass a parameter and use a generate-if/case statement. Example:

module sub_sub #(parameter OFF=0) ( ... );
  generate
    if (OFF) begin
      <code to avoid>
    end
  endgenerate
endmodule

module sub ( ... );
  ...
  sub_sub #( .OFF(1'b1) ) inst ( ... );
endmodule

module top ( ... );
  ...
  sub inst0 ( ... );
  sub_sub #( .OFF(1'b0) ) inst1 ( ... );
endmodule

Technically the the if (OFF) does not need to be in an explicit generate-endgenerate; it is inferred otherwise. It is recommended for human readability.

For full detail on generate blocks, refer to IEEE Std 1800-2012 ยง 27. Generate constructs

Greg
  • 18,111
  • 5
  • 46
  • 68
1

The scope of `define macros, and most other compiler directives is a compilation unit. A compilation unit is a stream of source text that a compiler parses. A macro gets defined at the point it appears in the compilation unit and is visible from that point onward.

The scopes defined by modules and other namespaces are irrelevant because macros are pre-processed before any Verilog or SystemVerilog syntax gets recognized. This means you can never have instance specific control over macro definitions.

If you want instance specific control over your code, you need to define parameters with instance specific overrides. Then you can use generate-if/case constructs to control the code you want to execute. If the generate construct is too restrictive for you, you can use procedural-if/case statements and optimization will remove branches not taken as a result of constant parameters.

dave_59
  • 39,096
  • 3
  • 24
  • 63
0

The best way is to modify your sub_sub module using parameter as suggested in other answers. However, this may not be practical if you can't edit/modify the sub_sub module, for example, it may be an encrypted IP.

In this case, one solution is to create wrapper nested module for each sub_sub module. You can do as follows:

// Wrapper for sub_sub with OFF defined
module sub_sub_wrapper1;
  `define OFF
    `include "sub_sub.v"
  `undef OFF
endmodule

// Wrapper for sub_sub without OFF defined
module sub_sub_wrapper2;
  `include "sub_sub.v"
endmodule

////////////////

module sub;
  sub_sub_wrapper1 subsub1();
endmodule

module top;
  sub sub1();
  sub_sub_wrapper2 subsub2();
endmodule

Quick sample

In this case of course I am assuming you are able to edit your top and sub module. And just note that nested module is only supported in system-verilog.

AldoT
  • 913
  • 1
  • 8
  • 34