Read bus signal problem. Compare with my Modelsim DE 10.2c and 10.4. EDAplayground Modelsim 10.1d has a different result
Hello to all SystemVerilog experts with the Mentor Graphic Modelsim tool.
I am writing a monitor task to handle a simple PCI bus write / read once event. Somehow EDAplayground Altera Modelsim 10.1d requires an extra clock cycle for some unknown reason, while my Modelsim DE 10.2c / 10.4 doesn't. I want to understand if this is correct.
Here is an example of the code for a post-entry class:
@(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
Below is a sample code for a reader class:
@(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 The example shows the correct result if I have this extra clock cycle. I get the data = c to read or write correctly. http://www.edaplayground.com/x/TSE The example shows the wrong result if I remove this extra clock cycle. I get data = 516 (address) to write and data = z to read. But, my Modelsim 10.2c and 10.4 will show the correct result (data = c).
Could you please help me understand this problem? Thank.
Michael
source to share
I cannot find an explanation for the race condition, but I did find two workarounds that will work with all versions.
One approach is to use a while loop with a clock as the blocking event and the net as the comparison condition.
-
while(bus.MONCLK.FRAMEn!=1'b0) @(bus.MONCLK);
Another approach is to use a tiny delay before or after @
. #1
should be safe if your time period is longer than 1 time unit. I don't recommend using both lead and end latency, pick one.
-
@(negedge bus.MONCLK.FRAMEn) #1;
-
#1 @(bus.MONCLK);
source to share