08-25-2017 05:39 AM
I encountered a strange behavior during simulation in Vivado 2016.4 / 2017.1
To describe my setup:
I have a SV testbench where I have 2 instances of the same BFM designed as SystemVerilog interface.
Each interface/BFM instance is connected to different signals of the DUT.
BFMs are controlled with tasks that set the values to the interface signals.
What I encountered:
2nd BFM instance behaves as it is connected to the clock signal of the 1st BFM instance even though it is not.
In the attached picture you can see that BFM drives araddr and arvalid signals at the rising edge of the BFM's clock signal aclk. The 2nd BFM instance should drive its araddr and arvalid signals at the rising edge of its own aclk signal, but signals are aligned to the rising edge of the 1st BFMs aclk signal.
I detect events of the aclk clock signals through @(posedge aclk). I have seen the same behavior with other input signals (from the BFM's point of view) when I tried to wait for some value/event, e.g. with wait().
I tried various modifications with interface definition:
- aclk defined in input/output region
- aclk defined as signal in interface's body
- automatic/static tasks for driving of the interface's signals
I ran the same test bench in ModelSim and it worked as expected, without any issues.
I wonder, is it a known bug in Vivado Simulator? Is there any "work around" for getting it to behave as expected?
08-28-2017 01:58 AM
thank you for the reply.
I cannot post the original source files, but I prepared simplified version of the test bench which results in the same behavior.
Test bench has two instances of the same BFM definition. I use task send to drive the data on the bus.
First BFM runs on 50 MHz clock and the second one on 80 MHz clock.
In the picture below (taken from simulation in Vivado 2016.4) you can see that 2nd BFM's data should be aligned to rising edge of 80 MHz clock and in the end is aligned to 50 MHz clock which is connected to 1st BFM instance.
After further debugging I came to conclusion that the bug resides in combination: task + event handling (e.g. @() or wait() ).
You can see in the picture that second BFM even ignores the assertion of the ready signal to 1 and BFM consideres that condition wait(valid == 1 and ready == 1); is not fulfilled.
When I detected these events (rising edge of clk, etc.) within initial block in BFM every event was detected correctly.