0

I know that SystemVerilog allows you to save a reference to an interface in a SystemVerilog class by declaring it as "virtual". Bus, is it also possible to declare a module as "virtual" in order to save a reference to a module in a SystemVerilog class? Example:

    `timescale 1 ns / 10 ps

    // Verilog-95 style BFM (with verilog 2001 style ports)
    module BFM1(
        input  wire        clk,
        output reg [15:0]  data
    );

        task write(input [15:0] data1);
            data = data1;
            @(posedge clk); 
            #1;
        endtask;

    endmodule
    class MyClass

        //"Virtual module" (instead of a "virtual interface")
        virtual BFM1 vBFM1;

        function new(virtual BFM1 vvBFM1);
            // save virtual module reference
            vBFM1 = vvBFM1;
        endfunction

        function write(input [15:0] data);
            vBFM.write(data);
        endfunction
    endclass
    // Testbench top-level
    module top;
        reg        clk;
        reg [15:0] data;

        initial begin
            clk = 0;
            forever #5 !clk = clk; 
        end

        BFM1 BFM1(
            .clk  (clk),
            .data (data)
        );

        DUT DUT(
            .clk  (clk), 
            .data (data)
        );

        initial begin

            //Verilog-95 Style BFM call
            BFM1.write(16'h12340);

            // SystemVerilog Class style
            MyClass MyClass1 = new(BFM1);

            MyClass.write(16'hDEAD);
            MyClass.write(16'hBEEF);

            $finish;
        end
    endmodule
    // Design under Test
    module DUT(
        input wire        clk,
        input wire [15:0] data
    );
        //insert design under test logic
    endmodule

I was just curious, if I could dispense with the formality of using a SystemVerilog interfaces, and just use an old verilog-95 Style BFM's from a SystemVerilog Class?

I just think the old style BFM's would work better in a SystemVerilog testbench if your DUT is in VHDL, since VHDL doesn't have SystemVerilog interfaces. Its kind of redundant to create unnecessary interfaces and packages just to plug a SystemVerilog testbench into a VHDL DUT that doesn't use them.

2 Answers 2

2

The direct answer to your question is no, SystemVerilog has limited constructs that you can get handles to (interfaces, classes, and events). The biggest problem is that modules are not like data types that have to be defined before being referenced. It's very difficult and non-optimal creating a reference to an identifier when you don't know its type.

The original SystemVerilog interface specification was much simpler than it is today. Its features have grown to look more like a module, but still more restrictive.

However, alternatives to virtual interfaces, especially when communicating with legacy Verilog BFMs is a frequently discussed topic. link1 link2 link3

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

2 Comments

Not to restate the obvious, but the reason why its a frequently asked question is because the SystemVerilog standard is missing a feature to save a reference to a module type into a variable... interfaces are just crippled modules with some extra modport syntax...you instantiate interfaces in the same way as a module...because they are really the same static structure... standards people should just treat modules the same as interfaces when saving a handle, in my opinion...
Also, in my opinion older style Verilog-BFM is not legacy... its the SystemVerilog Standard that is breaking backward compatibility by trying to force all testbenchs to use interfaces for everything even when the design doesn't need them... the result is that people need to maintain two versions of the exact same code... with identical BFM tasks... many interfaces are simple, and the designers prefer to maintain them as individual signals... either way...its eactly the same and not legacy code... just a missing feature.
-1
    `timescale 1 ns / 10 ps

    // The best why to solve this problem since the SystemVerilog
    //  language standard people did't give us a handle to a module
    //  is to create a define that points to full hierarchical path to
    //  the verilog module. Example:

    `define   DEF_BFM1   $root.top.BFM1

    // Verilog-95 style BFM (with verilog 2001 style ports)
    module BFM1(
        input  wire        clk,
        output reg [15:0]  data
    );

        task write(input [15:0] data1);
            data = data1;
            @(posedge clk); 
            #1;
        endtask;

    endmodule
    class MyClass

        function write(input [15:0] data);
            `DEF_BFM1.write(data);
        endfunction
    endclass
    // Testbench top-level
    module top;
        reg        clk;
        reg [15:0] data;

        initial begin
            clk = 0;
            forever #5 !clk = clk; 
        end

        BFM1 BFM1(
            .clk  (clk),
            .data (data)
        );

        DUT DUT(
            .clk  (clk), 
            .data (data)
        );

        initial begin

            //Verilog-95 Style BFM call
            `DEF_BFM1.write(16'h12340);

            // SystemVerilog Class style
            MyClass MyClass1 = new();

            MyClass.write(16'hDEAD);
            MyClass.write(16'hBEEF);

            $finish;
        end
    endmodule
    // Design under Test
    module DUT(
        input wire        clk,
        input wire [15:0] data
    );
        //insert design under test logic
    endmodule

4 Comments

This answer doesn’t scale when your design has multiple data ports and want to reuse the same class for each port. It also prevents you from putting your classes in a package since you can’t put hierarchical references in a package. And using packages allows you to do things like separate compilation of your testbench and DUT.
There is no need to use the instance path to access functions/tasks in a module. BFM1.write() would be sufficient , no macros, nor module instantiation is needed in this case. And it still will not work if the class is defined withing a package.
include file works almost the same as a package file... ifndef MY_INCLUDE define MY_INCLUDE define DEF_BFM1 $root.top.BFM1 endif
thats because the systemVerlog standards people are jerks that wanted to break verilog-95 without asking people what they really wanted at the time...a handle only work with "interfaces" instead of "module BFM's".. (they also gave a handle a terrible keyword name called "virtual")... so thus, i needed to hack it with hierarchy references... which still works because SystemVerlog also needs to cheat the same way... personally i think threy messed up interfaces...dumb way to implement them in my opinion...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.