0

I'm working on a project and I would like to implement variable module instantiation if that is possible. This is an example from my project where I am generating an array of multiplier modules that I've designed. To change data types(i.e. integer->floating point->fixed point) I need to change the module I'm calling, is there a way to do this easily by modifying my code? I've tried looking and it seems like I'm out of luck for answers.

I'm not sure how much this matters, but I am writing my code in Vivado 2019.2 for the Pynq-Z2.

My old code:

generate
    genvar m ;
    for(m=0;m<`inputPortCount;m=m+1)begin
        integercomputeBlockPynq m_computeBlock_in(i/o assign);
    end
endgenerate

3 Answers3

2

In my opinion, the following code would look a little concise and more readable, since it has only a single loop. However, it is up to you.

But one thing is that your if conditions are a bit overlapping, so I thought that the following will reflect them a bit better.

Now, it is better to use parameters instead of macros here. There are at least 2 reasons:

  1. parameters are scoped and belong you will avoid possible global space conflicts if you do it.

  2. you can instantiate this module with a different set of parameters easily enough, but you will have hard time to make all text macros working correctly in verilog.

So, here is my example:

parameter isInt=1; // i guess, if it is not int, it is float
parameter isFixed=0;
parameter inputPortCount = 4; // or whatever number.
 
generate
    genvar m ;
        for(m=0;m<inputPortCount;m=m+1) begin: loop
           if (isFixed)
               floatcomputeBlock m_computeBlock_in(i/o assign);
           else if (isInt)
               integercomputeBlockPynq m_computeBlock_in(i/o assign);
           else 
               floatcomputeBlockPynq m_computeBlock_in(i/o assign);
         end
endgenerate
Serge
  • 11,616
  • 3
  • 18
  • 28
0

My newly implemented code:

`define int     1
`define float   0
`define fixed   0
generate
    genvar m ;
    if(`int&&!(`float||`fixed))begin
        for(m=0;m<`inputPortCount;m=m+1)begin
            integercomputeBlockPynq m_computeBlock_in(i/o assign);
        end
    end
    if(`float&&!(`int||`fixed))begin
        for(m=0;m<`inputPortCount;m=m+1)begin
            floatcomputeBlockPynq m_computeBlock_in(i/o assign);
        end
    end
    if(`fixed&&!(`int||`float))begin
        for(m=0;m<`inputPortCount;m=m+1)begin
            floatcomputeBlock m_computeBlock_in(i/o assign);
        end
    end
endgenerate

Basically I just added some flags and used if statements that handle those flags to only enter if one of the three is set. Not sure if this is my final solution but lets my code work for now. Thank you again Christian B.

  • So what happens if your set both int and float? Why do you need all of this code when you will only instantiate one kind of submodule? – Moberg Jun 21 '20 at 08:40
  • in this case its better to use parameters than text macros. – Serge Jun 21 '20 at 11:37
0

Following the pattern of System Verilog Variable Module Name there should be a slightly more elegant version possible: `define MODE_INT

`ifdef MODE_INT
    `define module_name integercomputeBlockPynq 
`elsif MODE_FLOAT
    `define module_name floatcomputeBlockPynq 
`elsif MODE_FIXED
    `define module_name floatcomputeBlock 
`endif

generate
    genvar m ;
    for(m=0;m<`inputPortCount;m=m+1)begin
        `module_name m_computeBlock_in(1'b1);
    end
endgenerate

Sadly verilog seems to be incapable of "if defined(mode == 'int')"

Christian B.
  • 816
  • 6
  • 11