-1
\$\begingroup\$

I want to handle 2 scenarios in a module. The difference is very minimal, few lines at worst. The scenario depends on the instantiation and I would like to avoid having to have 2 separate files for it.

I can't use V/SV parameter because it would change the scope of the variables (scenarios using different types).

// Following breaks the scope
if (SCENARIO=1) begin
  mystruct_scenario1 myvar; // Scenario 1
end else begin
  mystruct_scenario2 myvar; // Scenario 2
end

Using different values for case depending on a SV parameter is impossible.

case (select_type)
if (SCENARIO=1) begin
  sc1_A: begin end
end else begin
  sc2_B: begin end
end
endcase

Using a macro here would solve all my problems but I don't know how to properly do it.

I'd be fine generating 2 different modules from the same file but I don't know how to tell Vivado to build 2 different modules with 2 different macros.

For Questa/Modelsim, I believe I'd just need to compile twice with 2 different +define+.

\$\endgroup\$
1
  • \$\begingroup\$ This seems like an xyproblem.info. You need to explain the behavioral differences needed for each scenario. Would also help to see what the difference is in declarations are supposed to be. This might be handled by a completely different approach. \$\endgroup\$ Commented Apr 24 at 20:42

1 Answer 1

2
\$\begingroup\$

Disclaimer, this doesn't answer how to use a macro as a parameter, but rather how to use a parameter to do what you want.

For the first situation it is possible to use a generate block to change the type of a variable like you show, and still use the variable outside the generate block itself.

Basically you give the generate block a name, and then access the variable defined inside by using its full structural name:

generate 
if (SCENARIO == 1) begin : myblock
  mystruct_scenario1 myvar; // Scenario 1
end else begin : myblock
  mystruct_scenario2 myvar; // Scenario 2
end
endgenerate

// Do something with myvar.
// Outside the generate block it's called "myblock.myvar".
assign something = myblock.myvar;

For case statements, more info on what you are trying to do would be needed to advise fully, but you could:

  • Use an if-elseif-else tree if possible

  • Have two copies of the case statement inside an if-else generate block.

  • Perform the if-else bit outside of the case statement into local variables or parameters:

    localparam sc1or2_case = (SCENARIO == 1) ? sc1_A : sc2_B;
    // -or-
    wire [...] sc1or2_case; // Or whatever type
    assign sc1or2_case = (SCENARIO == 1) ? sc1_A : sc2_B
    
\$\endgroup\$
2
  • \$\begingroup\$ Vivado doesn't support very well hierarchical variables like that. I had too many issues in the past. The case contains around 10 different values. I can change all my code to achieve that. Too bad I can't use macro for my use case. Thanks! \$\endgroup\$ Commented Apr 24 at 12:52
  • 1
    \$\begingroup\$ @None you could potentially use macros, but I don't know enough about Vivado to tell you whether it can compile like that. In Quartus you can define libraries in the project file and have duplicate copies of the same verilog file in different libraries, with each library having its own macro definitions. No idea if Vivado can. I'd give the heirarchical variable a go again in Vivado, it should work in this simple case where the names are within the same module (so can't be affected by modules being optimised away). \$\endgroup\$ Commented Apr 24 at 13:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.