Await_value utils functionality issue

Hi Marius,

I am trying to add self checking mechanism to another module I am currently verifying.

I currently have an issue when I use the following await_value ie awaiting between 262000 ns & 270000 ns for state_out value of “0110” (this is WRITE_SDA state) to reach :

await_value(state_out, “0110”, 262000 ns, 270000 ns, “Waiting for WRITE_SDA state to reach”);

& get the following error message:

UVVM: ==================================

UVVM: *** ERROR #1 ***

UVVM: 263100 ns TB seq.

UVVM: await_value(slv x"6", 262000 ns, 270000 ns) => Failed. Condition occurred too early, after 54900 ns. ‘Waiting for WRITE_SDA state to reach’

UVVM:

UVVM: Simulator has been paused as requested after 1 ERROR

UVVM: *** To find the root cause of this alert, step out the HDL calling stack in your simulator. ***

UVVM: *** For example, step out until you reach the call from the test sequencer. ***

UVVM: ================================

However, I am aware that there was another WRITE_SDA state_out “0110” that happened earlier @56300 ns and do not wanted to detect that one. Detected that one earlier but had to use also a bigger range band eg

await_value(state_out, “0110”, 54800 ns, 57000 ns, “Waiting for WRITE_SDA state to reach”);

WRITE_SDA state occurred here @56400 nS but had to use 54800 ns as start range and could not use eg 56300 ns ie 100 ns before it’s detection @56400 ns otherwise had a similar error that “Condition occurred too early, after 54900 ns”.

I performed already before hand a single WRITE_SDA followed by a single READ_SDA and at 263000 ns I was trying to perform another WRITE_SDA.

Part of the code in my testbench I am trying to perform is:

::

await_completion(I2CCONTROLLER_VVCT, 1, 2082*C_CLK_PERIOD, “Await completion”);

i2ccontroller_write_sda_multiple_bytes(I2CCONTROLLER_VVCT, 1, 26, “I2CController module: WRITE_SDA multi-byte transfer”);

log(ID_SEQUENCER, “Wait until the target signal ‘state_out’ equals the exp signal ‘0110’”, C_SCOPE); – @263000 nS

await_value(state_out, “0110”, 262000 ns, 270000 ns, “Waiting for WRITE_SDA state to reach”);

::

await_completion(I2CCONTROLLER_VVCT, 1, 26054*C_CLK_PERIOD, “Await completion”);

::

The C_CLK_PERIOD I use is 100 ns ie 2082*C_CLK_PERIOD stated above is 208200 ns

It should complete at 208200 ns from the await_completion procedure used above and then execute the rest. Isn’t this the case?

Your reply to this matter will be appreciated.

Regards,
Kevin

Hi Kevin,

Does your sequencer synchronize with all the commands, i.e. the sequencer has had an await_completion() of the previous I2C command? The time window in the sequencer should look something like:

|-----…
|-----i2c_command() – cmd 1
|-----await_completion() – waiting from “now” and to 2082C_CLK_PERIOD
|-----i2c_command() – cmd 2
|-----await_value() – waiting from “now” and to 2082
C_CLK_PERIOD
|-----i2c_command() – cmd 3
|-----await_completion() – waiting from “now” and to 2082*C_CLK_PERIOD

So, the i2c commands will be synchronized by:

  • await_completion() for cmd 1
  • await_value() for cmd 2
  • await_completion() for cmd 3

That is, if await_value() is waiting on something triggered by cmd 2.

You should for the await_value() have a waiting time window set from “now” and to the number of clock periods the DUT is required to set the output you are waiting on.

Could you please check if your sequencer is correctly synchronized?

Br,
Marius

Hi Marius,

Thanks for your reply. The await_completion() when executed then it assumes from “now”. I did not use any “now” as a parameter within the await_completion. Please confirm.

I replaced within the await_value() the start time to “now” wherever I try calling it.

My commands were still the same apart from adding the “now” as follows:

i2ccontroller_write_sda_one_byte() – cmd 1

await_value(state_out, “0110”, now, 57000 ns, “Waiting for WRITE_SDA state to reach”);
i2ccontroller_check()
i2ccontroller_check()
::
i2ccontroller_check()

await_completion(I2CCONTROLLER_VVCT, 1, 1055*C_CLK_PERIOD, “Await completion”);
– for cmd 1

i2ccontroller_read_sda_one_byte() – cmd 2

await_value(rx_buffer_rdy, ‘1’, now, 199700 ns, “Waiting until rx_buffer_rdy = ‘1’”);
i2ccontroller_check()

await_completion(I2CCONTROLLER_VVCT, 1, 2082*C_CLK_PERIOD, “Await completion”);
– for cmd2

cmd 1 was executed ok and completed @105500 ns as expected but cmd 2 reported the following error:

UVVM: *** ERROR #1 ***

UVVM: 199500 ns TB seq.

UVVM: await_value(std_logic 1, 105500 ns, 199700 ns) => Failed. Condition occurred too early, after 94000 ns. ‘Waiting until rx_buffer_rdy = ‘1’’

rx_buffer_rdy only gets asserted high in Simulation @199500 ns.
Why it displayed “Failed. Condition occurred too early, after 94000 ns. 'Waiting until rx_buffer_rdy = ‘1’” ?

You should for the await_value() have a waiting time window set from “now” and to the >>number of clock periods the DUT is required to set the output you are waiting on
My waiting window is set from “now” to just right after the pulse rx_buffer_rdy occured. ‘0’ → ‘1’ rx_buffer_rdy pulse occurred @199500-199600 (1 clk cycle long).

The await_value expects min_time and max_time parameters and not the number of clock cycles as you stated above. Please comment here.

await_value(target, exp, min_time, max_time, [alert_level], msg, […])

Regards,
Kevin

Hi Marius,

I think I see the issue now wrt the previous message sent. I removed the await_completion for cmd 1 and just left 1 await completion at the end as follows and this worked ok :slight_smile:

I will be checking the rest of my test code to fix the other issues seen. If any other problems will report back.

i2ccontroller_write_sda_one_byte() – cmd 1

await_value(state_out, “0110”, now, 57000 ns, “Waiting for WRITE_SDA state to reach”);
i2ccontroller_check()
i2ccontroller_check()
::
i2ccontroller_check()

i2ccontroller_read_sda_one_byte() – cmd 2

await_value(rx_buffer_rdy, ‘1’, now, 199700 ns, “Waiting until rx_buffer_rdy = ‘1’”);
i2ccontroller_check()

await_completion(I2CCONTROLLER_VVCT, 1, 2082*C_CLK_PERIOD, “Await completion”);
– for cmd2

Regards,
Kevin

Hi Marius,

The 1st 2 commands are working fine:

|-----…
|-----i2c_command() – cmd 1
|----- await_value() – waiting from “now” and to 57000 ns
|----- i2ccontroller_check() - executes then 8 of these checks
|----- :::
|----- i2ccontroller_check()
|-----i2c_command() – cmd 2
|----- await_value() – waiting from “now” and to 199700 ns
|----- i2ccontroller_check() - executes then 1 check
|-----await_completion() – waiting from “now” and to 208200 ns

Note: Just used 1 await_completion() for cmds 1 & 2 above. So here the sequencer had 1 await_completion() of the previous cmd1 & cmd2

The above i2c commands will be synchronized by:

  • await_value() for cmd 1
  • await_value() for cmd 2
  • await_completion() for cmd 2

I then execute within the same testbench:

|-----i2c_command() – cmd 3
|----- await_value() – waiting from “now” and to 270000 ns
|----- i2ccontroller_check() - executes then 8 of these checks
|----- :::
|----- i2ccontroller_check()
|-----i2c_command() – cmd 4
|-----await_completion() – waiting from “now” and to 5001300 ns

Note: Just used 1 await_completion() for cmds 3 & 4 above. So here the sequencer had 1 await_completion() of the previous cmd3 & cmd4

The above i2c commands will be synchronized by:

  • await_value() for cmd 3
  • await_completion() for cmd 4

but still see the following error wrt above cmd3 / cmd4 tests :

UVVM: *** ERROR #1 ***

UVVM: 263100 ns TB seq.

UVVM: await_value(slv x"6", 208200 ns, 270000 ns) => Failed. Condition occurred too early, after 54900 ns. ‘Waiting for WRITE_SDA state to reach’

Same issue reported at the beginning of this ticket…

Wrt my previous message, the await_value expects min_time and max_time parameters and not the number of clock cycles as you stated in your message. Please comment here.

Wrt your question:
“Does your sequencer synchronize with all the commands, i.e. the sequencer has had an await_completion() of the previous I2C command?”

Do we need to have an await_completion() for each separate I2C command? I think the answer here is no. Please comment if I am wrong. The above sequence of commands were executed in the order listed.

Regards,
Kevin

Hi Kevin,

You basically have two possible scenarios:

1A. issue a i2c VVC command
1B. wait for the VVC command to finish execution
1C. call the await_value() procedure to check that the output changes value as expected after the VVC command has finished, i.e. DUT has received the message command and should perform some work and set an output.

2A. issue a i2c VVC command
2B. call the await_value() procedure to check that the output changes value.

In scenario 1 you know that the VVC has transmitted the command to the DUT and you expect an output change any time from time now and some clock cycles (depends on the time the DUT will need to update the output).

In scenario 2 you do not wait for the VVC to finish sending the command, so you will wait for the output to change from the time of the i2c command transfer starts and to some clock cycles needed by the DUT.

Note that await_value() will return immediately if output = expected value when the procedure is called:

Waits until the target signal equals the exp signal, or times out after max_time.

Can you please check that your DUT output is not already set by any previous command?

Br.
Marius

Hi Marius,

Thanks for your reply.

I mainly use scenario2.

Had to add wait_num_rising_edge() + wait_until_given_time_after_rising_edge() UVVM utils procedures to perform self checking tests at allocated certain times after eg I2C i2ccontroller_write_sda_multiple_bytes() VVC command was issued

eg

wait_until_given_time_after_rising_edge(in_clk, xxx ns - now);

wait_num_rising_edge(in_clk,xx);

My self checking works fine now. Checks are performed at the right time. Had to review the simulation results and add the corresponding times as parameters to the eg above UVVM UTILS procedures.

ps
“now” is pretty useful parameter to use. Could not see anything within UVVM documentation wrt using the “now” parameter. Please correct me if I am wrong here. Thanks for suggesting that :slight_smile:

Best regards,

Kevin

Hi Kevin,
Glad to hear you fixed the simulations.
The “now” keyword is a VHDL function that returns the current simulation time. It is often handy to use in checkers etc.

Br,
Marius