systemverilog -> Passing parameters from an interf

2019-07-19 04:37发布

问题:

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

回答1:

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.



回答2:

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