Search code examples
system-verilogmodelsimedaplayground

Issue with reading bus signal. Compare to my Modelsim DE 10.2c and 10.4. EDAplayground Modelsim 10.1d has different result


Hi any SystemVerilog experts with Mentor Graphic Modelsim Tool.

I am writing a monitor task to process a simple PCI single word write/read bus event. Somehow EDAplayground Altera Modelsim 10.1d requires extra clock cycle for unknown reason while my Modelsim DE 10.2c / 10.4 does not. I want to understand if this is correct.

Here is an example on write monitor class code :

     @(negedge bus.MONCLK.FRAMEn);
     @(bus.MONCLK);    // EDA playground Modelsim 10.1d requires this extra clock cycle for getting data right.   It is also required for read as well. 
     address = bus.MONCLK.AD;
     if (bus.MONCLK.CBEn == IO_Write_CMD) begin
        //tran_type = PCI_WRITE;
        write = 1;      // true
        @(bus.MONCLK);
        data = bus.MONCLK.AD;
        status = 1'b1; // success
     end else begin              
        status = 1'b0; // not success
     end  

Here is an example on read monitor class code :

    @(negedge bus.MONCLK.FRAMEn);
     @(bus.MONCLK);     // EDA playground Modelsim 10.1d requires this extra clock cycle for getting data right.   It is also required for read as well. 
     address = bus.MONCLK.AD;
     if (bus.MONCLK.CBEn == IO_Read_CMD) begin
        write = 0;      // false
        @(bus.MONCLK);
        @(bus.MONCLK);
        data = bus.MONCLK.AD;
        status = 1'b1; // success
     end else begin              
        status = 1'b0; // not success
     end          

http://www.edaplayground.com/x/7kG An example shows the correct result if I have this extra clock cycle. I will get data = c correctly for read or write. http://www.edaplayground.com/x/TSE An example shows the wrong result if I removes this extra clock cycle. I get data = 516 (address) for write and data = z for read. But, my Modelsim 10.2c and 10.4 will show the correct result (data = c).

Could you help me understand this issue? Thank you.

Michael


Solution

  • I cannot find an explication for the race condition, but I have found two workarounds that will work with all versions.

    One approach is to use a while-loop with the clock as the blocking event and the net as the compare condition.

    • while(bus.MONCLK.FRAMEn!=1'b0) @(bus.MONCLK);

    The other approach is to use tiny delay before or after the @. #1 should be safe so long as your clock is period is greater than a 1 time unit. I do not recommend using both leading and trailing delay, pick one.

    • @(negedge bus.MONCLK.FRAMEn) #1;
    • #1 @(bus.MONCLK);