Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpinalSim: onSamplings can't work properly with clock from a blackbox #1334

Open
zyn810039594 opened this issue Mar 3, 2024 · 8 comments
Open

Comments

@zyn810039594
Copy link

Spinal version: v1.10.1
Simulation tool: Synopsys VCS 2018

Here's the simulation code:

        SimTimeout(500 ms)
        val perpPort = dut.socInst.logicMainInst.coreInst.io.d_perp
        val coreCd = ClockDomain(dut.socInst.logicMainInst.smuInst.io.coreClkRst.clk)
        InitBase.doInit(dut, 10 MHz, "00".asBin)
        infoMonitor(perpPort, coreCd)
        var numCnt = 0
        coreCd.onSamplings{
            if(perpPort.aw.valid.toBoolean && perpPort.aw.addr.toBigInt == 0x30006040L){
                val data = (perpPort.w.data.toBigInt & 0x000000FF).toChar
                println("state of ready: " + perpPort.aw.ready.toBoolean + " , count = " + numCnt + " , char is " + data)
                numCnt = 0
            }else{
                numCnt += 1
            }
        }
        sleep(100 ms)
        simSuccess()

All the signals here are set with "simPublic".

I want to record the cycles between two transport, but it gives me such a callback:

state of ready: true , count = 3125 , char is S
state of ready: true , count = 8 , char is M
state of ready: false , count = 6 , char is U
state of ready: false , count = 6 , char is  
state of ready: true , count = 14 , char is n
state of ready: false , count = 6 , char is i
state of ready: false , count = 6 , char is t
state of ready: true , count = 14 , char is S
state of ready: false , count = 6 , char is u
state of ready: false , count = 6 , char is c
state of ready: true , count = 14 , char is e
state of ready: false , count = 6 , char is s
state of ready: false , count = 6 , char is s

And the wave is:

image

Well, it's extremely unexpected... The number of count is obviously wrong, and the char "I" is missing.

The only special is the clock is from a simulation model of an RC osc.

So is there anything wrong about this? Maybe I need to offer a simplified model?

@andreasWallner
Copy link
Collaborator

Pinging @wswslzp as they have access to VCS

@zyn810039594 please provide a small, self contained example that reproduces the issue so that we have something to run.
Some general stuff: I see you are constructing the CD in your testcase, have you tried to use the appropriate CD from your design instead of making a new one? You do mention the model of your RC oscillator, did you check with a clock driven from the testbench? Is the oscillator model a blackbox in the design?

@zyn810039594
Copy link
Author

zyn810039594 commented Mar 14, 2024

Sorry for the late reply

Here's the code. And this time I simulate on IVerilog,

import spinal.core._
import spinal.lib._
import spinal.core.sim._
import spinal.lib.sim.StreamDriver

import scala.util.Random

object MyOnSamplingTest extends App {
    case class ClkSource0() extends BlackBox {
        val io = new Bundle {
            val clk = out Bool ()
        }
        addRTLPath("./hw/verilog/ClkSource.v")
        noIoPrefix()
    }
    case class ClkSource1() extends BlackBox {
        val io = new Bundle {
            val clk = out Bool ()
        }
        noIoPrefix()
    }
    case class OnSamplingModule() extends Component {
        val io = new Bundle {
            val rstn = in Bool ()
            val sIn  = slave(Stream(Bits(16 bits)))
            val sOut = master(Stream(Bits(16 bits)))
        }
        val insideClk0 = ClkSource0()
        val insideClk1 = ClkSource1()
        insideClk0.io.clk.simPublic()
        insideClk1.io.clk.simPublic()
        val cd0 = ClockDomain(insideClk0.io.clk, io.rstn)
        val cd1 = ClockDomain(insideClk1.io.clk, io.rstn)
        val c0Area = new ClockingArea(cd0) {
            val streamA = io.sIn.m2sPipe().s2mPipe()
        }
        val c1Area = new ClockingArea(cd1) {
            val streamATemp = cloneOf(io.sIn)
            val streamB     = streamATemp.halfPipe()
            io.sOut << streamB
        }
        val c0toC1 = StreamFifoCC(c0Area.streamA, c1Area.streamATemp, 2, cd0, cd1)
    }
    // Low Reset
    Config.sim
        .compile(OnSamplingModule())
        .doSimUntilVoid(dut => {
            SimTimeout(10 ms)
            dut.io.rstn #= false
            sleep(10 us)
            dut.io.rstn #= true
            val pIn   = dut.io.sIn
            val pOut  = dut.io.sOut
            val cd0   = ClockDomain(dut.insideClk0.io.clk, dut.io.rstn)
            val cd1   = ClockDomain(dut.insideClk1.io.clk, dut.io.rstn)
            val rand  = new Random()
            var times = 0
            pIn.valid #= false
            pIn.payload.randomize()
            pOut.ready #= false
            cd0.onSamplings {
                println("pIn valid State = " + pIn.valid.toBoolean)
                if (!pIn.valid.toBoolean) {
                    val randomValue = rand.nextInt()
                    pIn.valid #= true
                    pIn.payload #= randomValue
                    println("In value : " + randomValue)
                } else if (pIn.valid.toBoolean && pIn.ready.toBoolean) {
                    pIn.valid #= false
                }
            }
            cd1.onSamplings {
                if (pOut.valid.toBoolean) {
                    println("Out value : " + pOut.payload.toInt)
                    pOut.ready.set()
                    times += 1
                    if (times == 40) {
                        simSuccess()
                    }
                } else {
                    pOut.ready.clear()
                }
            }
        })
}

And here's the clock blackbox in Verilog:

module ClkSource0(
    output wire clk
);
    reg clk_r = 0;
    always #5.525 clk_r = ~clk_r;
    assign clk = clk_r;
endmodule

module ClkSource1(
    output wire clk
);
    reg clk_r = 0;
    always #2.775 clk_r = ~clk_r;
    assign clk = clk_r;
endmodule

The wave is correct, but nothing print in console.

@wswslzp
Copy link
Contributor

wswslzp commented Mar 20, 2024

What do you mean "missing cycle"?

What's the expected behavior? The issue makes no sense to me.

@zyn810039594 zyn810039594 changed the title SpinalSim: onSamplings missing cycle SpinalSim: onSamplings can't work properly with clock from blackbox Mar 20, 2024
@zyn810039594 zyn810039594 changed the title SpinalSim: onSamplings can't work properly with clock from blackbox SpinalSim: onSamplings can't work properly with clock from a blackbox Mar 20, 2024
@zyn810039594
Copy link
Author

What do you mean "missing cycle"?

What's the expected behavior? The issue makes no sense to me.

Sorry for my inaccurate discription, I've change the title of this issue. The problem is, when I simulate with a logic which is driven by a blackbox, the onSamplings function can not work properly. In my example above, cd0.onSamplings can not print anything.

@wswslzp
Copy link
Contributor

wswslzp commented Mar 20, 2024

Two examples you provide are still compilcated and not small enough I think. I have only noticed that you used some time literal in Verilog source codes without specifing timescale and also using time literal in Spinal testbench. I don't know how VCS or other simulators handle these time literal. These behaviors are somewhat unknown to me.

If you think this may relate to simulator API, please help provide the comparison of waveforms coming from VCS and other simulators.

@zyn810039594
Copy link
Author

Two examples you provide are still compilcated and not small enough I think. I have only noticed that you used some time literal in Verilog source codes without specifing timescale and also using time literal in Spinal testbench. I don't know how VCS or other simulators handle these time literal. These behaviors are somewhat unknown to me.

Okay I'll provide a smaller example later

If you think this may relate to simulator API, please help provide the comparison of waveforms coming from VCS and other simulators.

I think the problem may come from the implementation of onSamplings. In my test, the problem is happened in both VCS and iverilog. I'll have a try in both simulators later.

@zyn810039594
Copy link
Author

zyn810039594 commented Mar 20, 2024

New example:

object onSamplingsTest extends App {
    case class ClkSource() extends BlackBox {
        val io = new Bundle {
            val clk = out Bool ()
        }
        addRTLPath("./hw/verilog/ClkSource.v")
        noIoPrefix()
    }
    case class TestModule() extends Component {
        val io = new Bundle {
            val rstn     = in Bool ()
            val testOut = out UInt (8 bits)
        }
        val clkInst   = ClkSource()
        clkInst.io.clk.simPublic()
        val inCd = ClockDomain(clkInst.io.clk, io.rstn)
        val testArea = new ClockingArea(inCd) {
            val test = RegInit(U(0, 8 bits))
            test       := test + 1
            io.testOut := test
        }
    }
    Config.sim
        .compile(TestModule())
        .doSim(dut => {
            //Reset
            dut.io.rstn #= false
            sleep(1 us)
            dut.io.rstn #= true
            //
            ClockDomain(dut.clkInst.io.clk).onSamplings {
                println("CountNum: " + dut.io.testOut.toBigInt)
            }
            sleep(10 us)
            simSuccess()
        })
}

Clock blackbox written in Verilog (The ClkSource.v):

module ClkSource(
    output wire clk
);
    reg clk_r = 0;
    always #5 clk_r = ~clk_r;
    assign clk = clk_r;
endmodule

For IVerilog: nothing print in console, right wave.
image

[Progress] IVerilog compilation started
[Progress] IVerilog compilation done in 66.986 ms
[Progress] Start TestModule test simulation with seed 18677148
Shared memory key : SpinalHDL_0_1_1404932042_1309212340_1710946376677_6984934007765800324
Start of simulation
VCD info: dumpfile test.vcd opened for output.
End of simulation
[Done] Simulation done in 13.844 ms

For VCS: nothing print in console, right wave.
image

*Verdi* : Create FSDB file 'TestModule.fsdb'
*Verdi* : Begin traversing the scope (TestModule), layer (0).
*Verdi* : End of traversing.
*Verdi* : Flush all FSDB Files at 0 ps.
[Progress] Start TestModule test simulation with seed 1951478238
Unexpected termination of the simulation
           V C S   S i m u l a t i o n   R e p o r t 
Time: 11000000 ps

Verilator: can not load simulation model.
XSim: I don't have it.

@wswslzp
Copy link
Contributor

wswslzp commented Apr 7, 2024

Looks like none of the simulator works properly for your issue.

Try using SystemVerilog TB. SpinalHDL simulation kits may not cover your requirement. Complicated behavior model written in Verilog/SV may not be able to interact with SpinalHDL simulation kits perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants