SPI BFM spi_slave_transmit exit time

Hi,
I’m using the SPI BFM function spi_slave_transmit in single-word mode with two BFM configured differently.
The first has CPOL=‘0’ and CPHA=‘0’
the second has CPOL=‘1’ and CPHA=‘1’

During the simulation, the first BFM (CPOL=‘0’ and CPHA=‘0’) completes the spi_slave_transmit function right after the SPI clock rising edge.

This means I can start a new spi_slave_transmit because the next MISO should change after the next SPI clock falling edge.

While the second BFM (CPOL=‘1’ and CPHA=‘1’) complete the spi_slave_transmit function right after the SPI clock falling edge.

This means I can NOT start a new spi_slave_transmit because the next MISO should have already been changed.

Is this behaviour correct?

Thanks for your feedback. We will check this.

Could you please elaborate a bit on this?

Hi,
I worked on this problem, maybe the previous post is not clear.
I will retry.

In my TB I use the spi_slave_receive/transmit in single-word mode.
I have:
loop

  1. spi_slave_receive( v_data, “Receiving from DUT”, spi_if, START_TRANSFER_ON_NEXT_SS, C_SCOPE, shared_msg_id_panel, config);
  2. my TB decode v_data
  3. spi_slave_transmit (…START_TRANSFER_IMMEDIATE)
    end loop

I have a breakpoint right after the function
spi_slave_receive( v_data, “Receiving from DUT”, spi_if, START_TRANSFER_ON_NEXT_SS, C_SCOPE, shared_msg_id_panel, config);

If I configure the SPI BFM in CPOL=‘0’ and CPHA=‘0’
The breakpoint is triggered after the falling SCLK edge

The problem is that in CPOL=‘0’ and CPHA=‘0’ I should update my MISO line at the SCLK falling edge, but when I call the spi_slave_transmit (3.) the miso is updated using the spi_slave_transmit_and_receive too late.

In fact, the first MISO update in the spi_slave_transmit_and_receive is when:

 if not config.CPHA then
    miso       <= bfm_tx_data(C_ACCESS_SIZE - v_tx_count - 1);
    v_tx_count := v_tx_count + 1;
  end if; 

so in my configuration when SCLK=‘1’ but at the SCLK rising edge the MISO should be valid.

Hi,

I have taken a look at this issue now. I think my testbench may not be configured identically to yours, because I can’t trigger the problem. I have two BFMs in my testbench. Both are configured to CPHA = ‘0’ and CPOL = ‘0’. One is a master and the other is a slave.

The following code is used to trigger the VVCs using the BFMs:

      -- Chip select shall not be deasserted between operations, and there shall be no pause on SCLK between operations.
      spi_master_transmit(data => 8x"55",  action_when_transfer_is_done => HOLD_LINE_AFTER_TRANSFER);
      spi_slave_check(data_exp => 8x"55",  when_to_start_transfer       => START_TRANSFER_ON_NEXT_SS);

      spi_slave_transmit(data => 8x"AA",   when_to_start_transfer       => START_TRANSFER_IMMEDIATE);
      spi_master_check(data_exp => 8x"AA", action_when_transfer_is_done => RELEASE_LINE_AFTER_TRANSFER);

      await_completion(SPI_VVCT, 0, 1 us);
      await_completion(SPI_VVCT, 1, 1 us);

As you can see from the code, I issue two commands to each of the two VVCs. First I command the master to transmit and slave to receive. Then, without any pause, I trigger the slave to transmit and master to receive.

In this example the BFM config is set so that bit time is 40 ns and the ss_n_to_sclk setting is 6 ns.

The following picture shows the moment where the master transmit/slave receive ends and the slave transmit/master receive begins.

The spi_slave_receive() procedure is finished at the final falling edge of SCLK + t_spi_bfm_config.ss_n_to_sclk . In my TB that is the time of the last falling edge of SCLK + 6 ns.

The spi_slave_transmit() procedure then sets the value of MISO, also at the last falling edge of SCLK + 6 ns. Because the BFM is set to SPI mode 0 the data shall be transmitted at the falling edge of SCLK and sampled at the rising edge of SCLK. Depending on the setting of spi_bit_time and ss_n_to_sclk the start of spi_slave_transmit() begins well within the required time before the rising edge of SCLK. The MISO updates 6 ns after the last falling edge of SCLK of the previous transaction, and 14 ns before the first rising edge of the spi_slave_transmit() procedure.

Have I configured anything differently with respect to your testbench?

Best regards,

Daniel Blomkvist
EmLogic

Edit:

Here’s the BFM config I am using:

  constant C_SPI_BFM_CONFIG_DEFAULT : t_spi_bfm_config := (CPOL             => '0',
                                                           CPHA             => '0',
                                                           spi_bit_time     => 40 ns,
                                                           ss_n_to_sclk     => 6 ns,
                                                           sclk_to_ss_n     => 5 ns,
                                                           inter_word_delay => 0 ns,
                                                           match_strictness => MATCH_EXACT,
                                                           id_for_bfm       => ID_BFM);

Dear Daniel,
to reproduce the error in your configuration I changed the spi_bit_time, ss_n_to_sclk and sclk_to_ss_n to match the real SPI timing I want to simulate.

My BFM config is:

  constant C_SPI_BFM_CONFIG_DEFAULT : t_spi_bfm_config := (CPOL             => '0',
                                                           CPHA             => '0',
                                                           spi_bit_time     => (1000.0/96.0)*5.0 *1 ns,
                                                           ss_n_to_sclk     => 40 ns,
                                                           sclk_to_ss_n     => 40 ns,
                                                           inter_word_delay => 0 ns,
                                                           match_strictness => MATCH_EXACT,
                                                           id_for_bfm       => ID_BFM);

in this configuration, I have:

The miso is updated after the sclk rising edge.

I think that the problem comes from the time ss_n_to_sclk which is bigger than the spi_bit_time.

The SPI spi_slave_check function exit time is after the sclk rising edge.

If you want I can share with you my tb.

Best regards,
Emanuele

Hi Emanuele,

I changed my TB to use your BFM and now my TB also fails in the same way as yours. I will investigate some more and discuss this with the other developers and I will get back to you. Thank you for reporting this issue.

Best regards,

Daniel Blomkvist

Dear Daniel,
do you have any news about this issue?

Best regards,
Emanuele Zaccaro

Hi Emanuele,

We have found the issue. The issue was as you suspected with the relation between ss_n_to_sclk and spi_bit_time. A fix has been implemented and will be part of the next release of UVVM.

Here is the fix:

Best regards,

The UVVM Team