Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

SystemVerilog - module ports including interfaces with parameters

Quartus 9.0

I am new to SystemVerilog. I want to package certain common interfaces using 'interface'. For example:

 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// An interface for communication of parallel data with flow control where the source and destination share a clock //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   interface IParallel# (parameter DataWidth = 1);
   //////////////
   // The data //
   //////////////
      logic  Data;
   ////////////////////////////////////////////////
   // An indication that the source has new data //
   ////////////////////////////////////////////////
      logic ReadyFromSource;
   //////////////////////////////////////////////////////////////
   // An indication that the destination is ready for new data //
   //////////////////////////////////////////////////////////////
      logic ReadyToSource;
   /////////////////////////////
   // Forms of this interface //
   /////////////////////////////
      modport Source     (output Data, output ReadyFromSource, input ReadyToSource);
      modport Destination( input Data, input ReadyFromSource, output ReadyToSource);
endinterface

If I define a module and include this interface in its ports, I can use the default data width:

 
   module MyModule
   (
      IParallel.Destination ParallelInterface
   );

but, if I try to override that parameter:

 
   module MyModule
   (
      IParallel# (.DataWidth(2)).Destination ParallelInterface
   );

this gives

--- Quote Start ---

Error (10170): Verilog HDL syntax error...near text "#"; expecting ")", or ","

--- Quote End ---

What am I doing wrong?

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Unfortunately, even avoiding parameters, Quartus II 9.0 often crashes when trying to handle SystemVerilog interfaces.

    I have real work to do, so I'll revert to pure Verilog until the tool improves.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Man, I use interfaces *extensively* in Quartus.. I've been using them since 6.x, and I use them *a lot*. Quartus does not crash.. now, from time to time I make some construction that causes a red box.. and I just back that out, and try something else, but let me say that interfaces are not the issue.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Okay,, now to address the real issue.

    In order to use parameterized interfaces, you must use generic interfaces in the module using the parameterized interface.. I do that now, and it works great.

    module top(..);

    IParallel# (.DataWidth(16)) ipar();

    Useit inst(.if_par(ipar.Destination));

    SrcIt sinst(.if_par(ipar.Source));

    endmodule

    module UseIt(

    interface if_par

    );

    endmodule

    Things to note:

    In the module(s) using he interface, source or destination, do not specify the interface by name, use the "generic" name "interface". Since you are not specifying the modport, you must specify the modport where you instantiate the module. This is allowable SV syntax, you can specify the modport in the module defintion, OR in the instantiation. Since you are using a "generic" interface, you must specify at the instantiation. (It might be possible to do "interface.Destinaion", but I'm not sure of that)

    So, now you have defined your modules that use the IParallel interface to be generic, so they will work with any size of IParallel. Now, inside of the module, you will undoubtedly refer to if_par.<interface item>, so, whatever interface you pass to you modules has to support THOSE. This wuuld allow you to pass another interface, NOT IParallel, that also included any items addressed... this other interface would need the same items and directions, etc. but hopefully you get the idea.

    The next question you will have is.. "How can I make the using/sourcing module adapt to the size of the interface?"

    Well.. you can use the $size or $left or $right items.

    module UseIt

    # (parameter size=1)

    (

    interface if_par,

    );

    logic intData;

    assign intData = if_par.Data;

    ..

    endmodule

    When you instantiate the UseIt module, you can do this:

    UseIt# (.size($size(ipar.Data)) useinst (.if_par(ipar.Destination);

    This seems to do the trick as expected.

    I hope that helps..

    Good luck, and happy interfacing..

    Ed
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you. I see now that generic interfaces simply use 'interface' (like some object-oriented languages which derive all classes from 'Object') and that type-compatibility is checked at instantiation (rather than constructing a 'full' type hierachy and deriving from the most appropriate, so that type-compatibility can be checked when the subsidiary module is compiled).

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Thank you. I see now that generic interfaces simply use 'interface' (like some object-oriented languages which derive all classes from 'Object') and that type-compatibility is checked at instantiation (rather than constructing a 'full' type hierachy and deriving from the most appropriate, so that type-compatibility can be checked when the subsidiary module is compiled).

    --- Quote End ---

    Exactly..

    one thing to remember, be sure that all of you interfaces are first in the compile list. Quartus must see the interface before it sees the instantiation. This applies to packages as well.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    P.S.

    Since I mentioned it, I tried using the modport name in the generic..

    Module MyMod

    (

    interface.Destination if_par

    );

    endmodule

    This actually works.. It would require that at elaboration time any interface supplied to "if_par" would have to have a modort named "Destination", with any items referenced by if_par.. This is pretty cool, and very powerful.