2

I'm trying to pass an interface to a module which is an array of interfaces.

interface front_port #(parameter DATA_WIDTH = 4);
        logic   [DATA_WIDTH - 1 : 0]   data;
        logic                          acknowledge;

        modport f_interface(input data, output acknowledge);
endinterface

interface front_interface #(parameter NO_OF_IN_PORTS = 3);
        front_port    front_ports[NO_OF_IN_PORTS]();
endinterface

module A #(parameter NO_OF_IN_PORTS = 3)
(
    interface front_port;
);

module testbench;
    font_interface #(.NO_OF_IN_PORTS(3))  my_front_interface();

    A #(.NO_OF_IN_PORTS(3)) (.front_port(my_front_interface));
endmodule

So, my question is, can the array elements of my_front_interface have different values of DATA_WIDTH. If so, how? In the code defined above all the array elements of my_front_interface have the default DATA_WIDTH of 4.

Thanks

3
  • You are sure about using nested modules? While instantiating module A, the input argument is my_front_interface of type front_interface, but the instance my_front_interface is of type front_interface. The module declaration might be like module A...(front_interface fr_if). Commented Apr 6, 2016 at 7:28
  • Regarding variable DATA_WIDTH, rather than simply creating array of instances, you need a generate block for making multiple instances with varying data width parameter. Refer this link and this question for generate block example. Commented Apr 6, 2016 at 7:43
  • Ok. Thank you. If that's the case how do I assign the generated instances with varying data width parameter to front_interface? Commented Apr 6, 2016 at 8:32

2 Answers 2

3

Following from my comments, there seems many compilation errors in the given code. Yet, I have tried to resolve them as per my understanding.

In order to create varying DATA_WIDTH instances, the interface front_interface must get information about DATA_WIDTH in various instances. So, adding an array of parameters to front_interface entity. The size of that array is determined by NO_OF_IN_PORTS parameter.

Further, you must use generate block for creating multiple instances of front_port. Each instance picks up an element from parameter array of front_interface entity.

I have created following code which overrides the default values of DATA_WIDTH and creates instances with unique data widths.

interface front_port #(parameter DATA_WIDTH = 4);
    logic   [DATA_WIDTH - 1 : 0]   data;
    logic                          acknowledge;

    modport f_interface(input data, output acknowledge);

  initial
    begin : DEBUG_DISPLAY
      $display("DATA_WIDTH for %m is %0d",DATA_WIDTH);
    end
endinterface

// Use array DATA_WIDTH here, for varying data widths.
interface front_interface #(parameter NO_OF_IN_PORTS = 3, int DATA_WIDTH[NO_OF_IN_PORTS] = '{1,2,3});
  genvar i;
  generate // generate block for multiple instances
    begin : MULTIPLE_INSTANCES
      for(i=0;i<NO_OF_IN_PORTS;i++)
        begin : UNIQUE_DATA_WIDTH
          // Pick up each element from array to create varying DATA_WIDTH instances
          front_port #(.DATA_WIDTH(DATA_WIDTH[i])) front_ports();
        end
     end
  endgenerate
endinterface

module A #(parameter NO_OF_IN_PORTS = 3)
          (front_interface fi_if);
endmodule

module testbench;

  // Override DATA_WIDTH here for different instances
  front_interface #(.NO_OF_IN_PORTS(3), .DATA_WIDTH('{4,5,6}))  my_front_interface();

  A #(.NO_OF_IN_PORTS(3)) a1(my_front_interface);

endmodule

Output:

DATA_WIDTH for testbench.my_front_interface.MULTIPLE_INSTANCES.UNIQUE_DATA_WIDTH[0].front_ports.DEBUG_DISPLAY is 4
DATA_WIDTH for testbench.my_front_interface.MULTIPLE_INSTANCES.UNIQUE_DATA_WIDTH[1].front_ports.DEBUG_DISPLAY is 5
DATA_WIDTH for testbench.my_front_interface.MULTIPLE_INSTANCES.UNIQUE_DATA_WIDTH[2].front_ports.DEBUG_DISPLAY is 6

Refer this page for passing array of parameters in an entity. Also, SystemVerilog IEEE 1800-2012 Section 27 is helpful for generate blocks.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm struggling to access the front_interface (fi_if) in module A. What is the syntax? Shouldn't it be fi_if.MULTIPLE_INSTANCES.UNIQUE_DATA_WIDTH[0].front_ports.data?
Oh yes. There seems to be a gotcha for unnamed generate block scope discussed in Section 2.5 Sutherland Paper. Remove begin : MULTIPLE_INSTANCES ..end, and use my_front_interface.UNIQUE_DATA_WIDTH[i].front_ports.DATA_WIDTH from testbench. For accessing from module A, fi_if.UNIQUE_DATA_WIDTH[i].front_ports.DATA_WIDTH should work, but I am confused as to why it is not working.
So, for module A, use $root.testbench.my_front_interface.UNIQUE_DATA_WIDTH[i].front_ports.DATA_WIDTH. When I get a solution for module A, fi_if hierarchy, I'll post it as soon as possible.
Alright. Thank you. I'll post if I find a solution too.
0

Yes, it will create data as per DATA_WIDTH only, by default 4 bit.

Check the below code, with it's output. (In the code, 2 Interface Arrays with different parameter values, f & f5 are instantiated in the front_interface, to make things more clear.

interface front_port #(parameter DATA_WIDTH = 4);
  logic [DATA_WIDTH - 1 : 0] data;
  logic acknowledge;

  modport f_interface(input data, output acknowledge);
endinterface

interface front_interface #(parameter NO_OF_IN_PORTS = 3);
  // To create array of front_port
  front_port f[NO_OF_IN_PORTS - 1 : 0](); // data should be 4 bits wide
  front_port #(5) f5[NO_OF_IN_PORTS - 1 : 0](); // data should be 5 bits wide
endinterface

module A #(parameter NO_OF_IN_PORTS = 3) (front_interface x); 
  initial
    begin
      $display ("Size of x.f[%0d].data = %0d", 0, $size(x.f[0].data));
      $display ("Size of x.f[%0d].data = %0d", 1, $size(x.f[1].data));
      $display ("Size of x.f[%0d].data = %0d", 2, $size(x.f[2].data));

      $display ("Size of x.f5[%0d].data = %0d", 0, $size(x.f5[0].data));
      $display ("Size of x.f5[%0d].data = %0d", 1, $size(x.f5[1].data));
      $display ("Size of x.f5[%0d].data = %0d", 2, $size(x.f5[2].data));
    end
endmodule


module testbench ();
  front_interface #(3)  my_front_interface();

  A #(3) (my_front_interface);
endmodule

And Output of the Code :

Size of x.f[0].data = 4
Size of x.f[1].data = 4
Size of x.f[2].data = 4
Size of x.f5[0].data = 5
Size of x.f5[1].data = 5
Size of x.f5[2].data = 5

4 Comments

The number of instances of front_port is to be controlled by parameter, NUM_OF_IN_PORTS.
Yes, exactly that is what I have done. front_port #(5) f5[NO_OF_IN_PORTS - 1 : 0]() will create instances of front_port, depending upon parameter NO_OF_IN_PORTS
Will the array elements of my_front_interface have different values of DATA_WIDTH?? As per OPs question? I think this willwill create an array of instances with same value of DAAT_WIDTH (4). Then you have created again a different array of instances with DATA_WIDTH (5). The intent of OP is to have a single array of instances with different data width.
I have explained, how to generate array if DATA_WIDTH is same. Now, if you want to change DATA_WIDTH in each instance, then it can't be called an array, as each elements are not same. To make different insatnces with different DATA_WIDTH values, you can use generate ... endgenerate block.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.