3

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

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44
Michael Li
  • 53
  • 2
  • 1
    You might have a race condition on the `data` signal. The signal operations might get scheduled slightly differently on the two simulators Without the showing us the code that is driving that signal it's impossible to say for sure. – Tudor Timi Dec 16 '14 at 07:16
  • It is definitely a scheduling differences. Putting `$display` statements after each `@` show `@(negedge bus.MONCLK.FRAMEn);` and `@(bus.MONCLK);` happen in the same time-stamp in ModelSim 10.1d. I haven't determent if it is a bug in 10.1d or an inherent race condition from the LRM. @Tudor, the full code is available on the the edaplayground links. – Greg Dec 16 '14 at 19:01
  • Thank you so much. I believed that Atlera Modelsim is based the core engine of Modelsim DE. I would not think that there is a difference. I did this example with UVM library. I have the same problem with uvm_info and the wrong data stored in the transaction class packet (not just $display issue). Could not be scheduling be that much different? It is able to break my UVM testbench. I can provide link to UVM testbench if interested. – Michael Li Dec 16 '14 at 19:29
  • Sorry, UVM is complex and can confuse the issue. SV example here is simple. Maybe I can put comparison of data to show the mismatch problem. That may be simple way to see if it is related to $display. In UVM, I have a mismatch issue that the data is wrong. So, I know that there is an issue. – Michael Li Dec 16 '14 at 19:52
  • I added comparison (==) to check actual address/data in both examples. Thank you for any additional comments. – Michael Li Dec 16 '14 at 20:40
  • I appreciate Greg and Tudor. I like to check LRM too for any insight on signal race and internal delta event scheduling. – Michael Li Dec 16 '14 at 21:29

1 Answers1

1

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);
Greg
  • 18,111
  • 5
  • 46
  • 68
  • Greg. Thank you so much for the example code. The first example will sample the state of FRAMEn and use only @(bus.MONCLK) to advance. The second example is to put #1 unit delay to avoid two statement to occurs at the same time. I think I understand your ideas here. I will try them out. – Michael Li Dec 20 '14 at 02:39
  • FYI: on this site, thank yous are given via up votes and accepting the best answers (check mark next to an answer). This also helps other users with similar issues find solutions. – Greg Dec 23 '14 at 03:41