3

I am porting a System Verilog model to SystemC and I am not sure of the best way to model this phase locked loop clock driving scheme. It seems to me in SV driving the clock is a bit of a manual process where SystemC provides a way for the kernel to do it for you. But I don't know how SystemC supports the kind of clock dividing that is done manually in the SV model I am looking at.

Consider this simplified System Verilog model.

module device(
    input REFCLKP, // Reference clock, Positive.
    input REFCLKN, // Reference Clock, Negative.
    ...
);
...
    reg  ck;
    reg  ck_x2;
    reg  ck_x3;
    wire refclk = REFCLKP & ~REFCLKN;
    int unsigned ck_ratio = 10; // divide the reference clock by 10
...
    always @(posedge refclk) begin
        tm_refclk_period = $time - tm_refclk;
        tm_refclk <= $time;
        if (tm_refclk_period) begin
            for (int i=0; i<ck_ratio; i++) begin
                ck <= #(i*tm_refclk_period/ck_ratio) refclk;
                ck <= #((i+0.5)*tm_refclk_period/ck_ratio) !refclk;
            end
            for (int i=0; i<ck_ratio/2; i++) begin
                ck_x2 <= #(i*tm_refclk_period/(ck_ratio/2)) refclk;
                ck_x2 <= #((i+0.5)*tm_refclk_period/(ck_ratio/2)) !refclk;
            end
            for (int i=0; i<ck_ratio/3; i++) begin
                ck_x3 <= #(i*tm_refclk_period/(ck_ratio/3)) refclk;
                ck_x3 <= #((i+0.5)*tm_refclk_period/(ck_ratio/3)) !refclk;
            end
        end
    end
...
endmodule

Then, in the testbench:

initial begin
    ...
    // start the clock
    refclk <= #(1e6/rl_ck_mhz) 1'b1;
    forever begin
        @(posedge refclk) begin
            refclk <= #(0.5e6/rl_ck_mhz) 1'b0;
            refclk <= #(1e6/rl_ck_mhz) 1'b1;
        end
    end
end

device dut(
    .REFCLKP(refclk),
    .REFCLKN(!refclk),
    ...);

So my SystemC equivalent of the testbench basically looks like

int sc_main(int argc, char* argv[])
{
    sc_clock refclk;
    ...
    device dut;
    dut.refclk(refclk);
    ...
}

But now I am a bit stuck on how to properly model the internal clock driving from the reference clock. I suppose I could try to do a manual approach like the SV code but that doesn't seem like the SystemC way. Another idea I had is try to have all the clocks directly driven from sc_main, instead of in the PLL style of the example, but I don't have the experience to say for sure if it will work. Is there any convention for doing something like this in SystemC?

Rich
  • 1,165
  • 1
  • 15
  • 29

0 Answers0