Interface design for an unidirectional bus

Hi, I have developed a BFM for a unidirectional bus in a package. Lines are pulled high at top module. BFM has the virtual interface to access the lines.

I wanted the BFM to be reusable but it depends on bus interface signals roughly. Since the lines are needed to be pulled up, it has to be a wire. But BFM might drives it to Z and strong0 using procedural assignments. So it can’t be the actual wires, it should be logic type. By using logic types for driving and assigning them to wires at interface level, it was impossible the read back the wire’s into the BFM via logic type variables while DUT is driving the lines. So I had to use the actual wires inside the bfm classes when reading the lines. I feel like this make the BFM and interface so dependent, and they always must be ship together. Also, I wanted to make interface signals input/output port in order to avoid the assignments in the dut interface.

I am wondering that, is it the most convenient way to structure the components? Please let me know if there is something that I am missing.

See the example code below,


module top
  bit clk;
  DUT_IF my_if(clk);
  DUT my_dut(my_if.bus_sig1, my_if.bus_sig2, some_signal);

  pullup(my_if.bus_sig1);
  pullup(my_if.bus_sig2);

endmodule;

interface DUT_IF(bit clk);
 // some signal
 wire bus_sig1, bus_sig2;
 
 BUS_IF bus_if(bus_sig1, bus_sig2);
 bfm my_bfm(bus_if);

endinterface;

interface BUS_IF(inout sig1_io, sig2_io);
 logic sig1, sig2;

 assign sig1_io = sig1;
 assign sig2_io = sig2;

endinterface;

package bfm_pkg;
  class bfm;
    virtual BUS_IF bus_vif;
    logic a;

    task drive();
      bus_vif.sig1 = 1'bZ;
      bus_vif.sig2 = 1'b0;
    endtask

    task read();
     if(bus_vif.sig1_io == 1'b1)
       a = buf_vif.sig2_io;
    endtask;

  endclass
endpackage;


Hey forum! Any ideas?