1
\$\begingroup\$

I am currently encountering issues with my ring oscillator simulation in SystemVerilog, which I cannot explain.

Toolchain:

╰─○ iverilog -V
Icarus Verilog version 11.0 (stable) ()
╰─○ vvp -V
Icarus Verilog runtime version 11.0 (stable) ()

ring_oscillator.sv looks as follows:

module RING_OSCILLATOR #(
    parameter INVERTERS_PER_RING=3,
    parameter INVERTER_DELAY=1
) (
    input  logic en,
    output logic out
);

    initial begin
        assert( (INVERTERS_PER_RING >= 3) && (INVERTERS_PER_RING % 2 != 0) );
    end

    logic [INVERTERS_PER_RING-1:0] wires;
    assign out = wires[0];

    genvar i;
    generate
        for(i=0; i<INVERTERS_PER_RING; i=i+1) begin
            if (i == 0)
                not #(INVERTER_DELAY) (wires[i], en ? wires[INVERTERS_PER_RING-1] : 0);
            else
                not #(INVERTER_DELAY) (wires[i], wires[i-1]);
        end
    endgenerate
endmodule

/*
For INVERTERS_PER_RING = 3:

wires[0] = en ? ~wires[2] : 0;
wires[1] = ~wires[0];
wires[2] = ~wires[1];
*/

Testbench:

`timescale 1ns/1ps
`include "ring_oscillator.sv"

module RING_OSCILLATOR_TB();

    logic en1;
    wire out1;
    RING_OSCILLATOR ro1 (
        .en (en1),
        .out(out1)
    );
    defparam ro1.INVERTERS_PER_RING=3;
    defparam ro1.INVERTER_DELAY=1;

    initial begin

        $dumpfile("ring_oscillator_tb.vcd");
        $dumpvars(0, RING_OSCILLATOR_TB);

        #0;
        en1 = 0;

        #10;
        en1 = 1;
    
        #300;
        $finish();
    end
    
endmodule

This simulation results in somewhat expected output as follows: Simulation with 1ns input-to-output delay for inverters

But, when reaching a delay of 5ns per inverter, by setting:

defparam ro1.INVERTER_DELAY=5

the oscillator malfunctions, as follows: Simulation with 5ns input-to-output delay for inverters

The well-defined areas all have a width of 10ns, whereas the undefined areas have a width of 5ns. I'm new to SystemVerilog and hardware design in general. I would really like to understand what is actually happening here and how this may be fixed.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

To debug this issue, you should look at the waveforms of the wires signal inside the RING_OSCILLATOR module as well.

wires[0] is the output of the first not gate. At time=0, the input of that gate will be 0 since en=0, but it will take time for the 0 to propagate to the output. When INVERTER_DELAY=1, it takes 1ns for wires[0] to transition from x to 0. It takes 2ns for wires[1] to go from x to 0, and 3ns for wires[2] to go from x to 0. So, after 3ns, all wires signals will be 0. Since you wait until 10ns to enable the oscillator, all signals have had a chance to become known.

However, when INVERTER_DELAY=5, it takes each not gate 5ns to clear the x, for a total of 15ns. But, you enable the oscillator at 10ns, which means all gates have not had a chance to clear the x's.

To fix it, you need to wait a little more time, like 20ns. For example, change:

#10;

to:

#20;
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.