Module, Interface, Clocking

Hello,

Recently I’ve been trying to learn system verilog. I believe it’s almost impossible, since forums and online tutorials are at least ambiguous, if not full of contradictions. I’m trying to find a solid and complete source of information about System Verilog, but I haven’t succeeded so far. I’ve been using duolos, testbench[.in], chipverify, asic-world, sunburst and many other sites. None of those sites is comprehensive, thus I need to jump between them. While doing so I have the feeling that system verilog is well defined… (or widely understood)

I am currently trying to understand how to correctly define port directions between modules, testbenches, interfaces and clocking blocks.
Let’s assume I’m trying to verify my module modExample (it’s role is to set acknowledge if data was received):


module modExample
(
    input clk,
    input din,
    input den,
    output ack
)
//...
endmodule

I also would like to connect the testbench to it via the interface ifExample:


interface ifExample(input clk);
    logic din;
    logic den;
    logic ack;

    modport DUT(input din, input den, output ack);
    modport TB(output din, output den, input ack); 
endinterface

The testbench could look like:


module tb;
    // ...
    // signal declaration, etc.
    // ...

    ifExample IF(clk);

    initial begin
        @(posedge IF.clk) begin 
            IF.TB.din = 1;
            IF.TB.den = 1;
        end
    end

    modExample DUT
    (
        .clk(IF.clk),
        .din(IF.DUT.din),
        .den(IF.DUT.den),
        .ack(IF.DUT.ack)
    );
endmodule

I believe that so far everything (or at least if it comes to port directions) is correct

But what if we add clocking block inside the interface? Is the following implementation correct? Or should I create a separate clocking block for modport DUT and TB? Because - to my mind - I want my inputs to be driven #1[time] (skew) before the (posedge clk), thus din and den should be “inputs” of clocking block. But it also looks like it changes the direction of modports…


interface ifExample_withClockingBlock(input clk);
    logic din;
    logic den;
    logic ack;

    clocking cb @(posedge clk);
    // skews
    input din;
    input den;
    output ack;
    endclocking

    modport DUT(clocking cb);
    modport TB(clocking cb); 
endinterface

So please help me understand it. Is the definition of ifExample_withClockingBlock correct? Or have I messed it up?

In reply to bakiej:

interface ifExample_withClockingBlock(input clk);
logic din;
logic den;
logic ack;

clocking dut_cb @(posedge clk);
// skews
input din;
input den;
output ack;
endclocking

// for tb, the direction of signals reverses,
// so have another clocking block with changed directions
clocking tb_cb @(posedge clk);
// skews
output din;
output den;
input ack;
endclocking

modport DUT(clocking dut_cb);
modport TB(clocking tb_cb); 

endinterface