modportで定義した信号にclockingを適用する

interfaceではmodportを使うことで信号の向きを定義できるが、このmodportにclockingを適用したい場合は、下記のように書けばよい。

interface bus_if(input clk);
  〜
    // clockingブロックで信号の向きと遅延を設定
    default clocking cb @(posedge clk);
        default input #1ns output #1ns;
        
        output   cs, rw, addr, wdata;
        input    rdata;
    endclocking

    modport master(clocking cb); // ここではclockingだけ定義
endinterface

ここまではよいのだけど、このmodportで定義した信号を下記のような別モジュール内(test)でドライブしようとしたら、またはまってしまった。

bus_if bus(clk); // interfaceのインスタンス
test test(.bus_m(bus.master), .clk(clk));

testモジュール内ではどのように信号に値を入力すればよいか?下記のように書けば行けそうなんだけど、これだと信号が見つからないと怒られた。

module test(bus_if bus_m, input clk);
    task write(input [31:0] ad, dt);
        @(posedge clk);
        bus_m.cs    <= 1'b1;
        bus_m.rw    <= 1'b1;
  〜

正解はというと、"bus_m.cb.○○"のようにclockingブロックのブロック名を付ければよいだけ。こんなんで結構悩んだような気が・・・

module test(bus_if bus_m, input clk);
    task write(input [31:0] ad, dt);
        @(posedge clk);
        bus_m.cb.cs    <= 1'b1;
        bus_m.cb.rw    <= 1'b1;
  〜

以下、参考までに。

interface bus_if(input clk);
    logic        cs;
    logic        rw;
    logic [31:0] addr;
    logic [31:0] wdata;
    logic [31:0] rdata;

    // clockingブロックで信号の向きと遅延を設定
    default clocking cb @(posedge clk);
        default input #1ns output #1ns;
        
        output   cs, rw, addr, wdata;
        input    rdata;
    endclocking

    modport master(clocking cb);
endinterface
`timescale 1ns/1ns
// テストベンチトップ
module tb_top;
    logic clk;

    bus_if bus(clk); // interfaceのインスタンス
    test test(.bus_l(bus.master), .clk(clk)); // ここではclockingだけ定義
  
    initial begin // クロック
        clk <= 1'b0;
        forever #5 clk = ~clk;
    end

    initial begin
        bus.cs    <= 1'b0;
        bus.rw    <= 1'b0;
        bus.addr  <= 32'h0;
        bus.wdata <= 32'h0;
        bus.rdata <= 32'h0;
        
        #100;
        test.write(32'h1234, 32'h5678);
        #100;
        $finish;
    end
endmodule
module test(bus_if bus_l, input clk);
    // "cb."付けないとエラー
    task write(input [31:0] ad, dt);
        @(posedge clk);
        bus_l.cb.cs    <= 1'b1;
        bus_l.cb.rw    <= 1'b1;
        bus_l.cb.addr  <= ad;
        bus_l.cb.wdata <= dt;
        @(posedge clk);        
        bus_l.cb.cs    <= 1'b0;
        bus_l.cb.rw    <= 1'b0;
        bus_l.cb.addr  <= 32'h0;
        bus_l.cb.wdata <= 32'h0;
    endtask
endmodule