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