UVM driver does not drive a component of the interface

Hello,

In my system,

I have a port (which is not connected to the DUT) named LA_EN in the interface of my agent, the related code part in the interface is as follows:


interface example_if();
   bit LA_EN;
endinterface: example_if

I use LA_EN as a control bit to drive an inout signal, whenever the agent wants to drive a value into the DUT, I set this bit high, then drive the data and set the bit low again. At the top module of my testbench, I check the LA_EN, if the LA_EN is high, I connect the internally generated data_bus to the DUT, otherwise I drive HZ.

The related code part in the top module is as follows:


wire [16:0] data_bus_buffer;

DUT DUT_0(
            .data_bus (data_bus_buffer)
          );

assign data_bus_buffer = (top.example_if.LA_EN === 1'b1) ? example_if.data_bus : 16'hZZZZ;

The problem is that when I drive the LA_EN high or low in the driver, it does not really change its value in the waveform.

The related code part in the driver is as follows:


task exmaple_driver::run_phase(uvm_phase phase)
   example_seq_item req;
   exmaple_vif.LA_EN = 1'b0;

   forever begin
      seq_item_port.get_nex_item(req);
      case(req.example_op)
         3'b000: begin ****** end
         3'b001: begin ****** end
         3'b010: begin ****** end
         3'b011: begin ****** end
         3'b100: begin ****** end
         3'b101: begin ****** end
         3'b110: begin ****** end
         3'b111: begin 
                    example_vif.LA_EN <= 1'b1;
                    example_vif.data_bus <= req.data_bus;
                    example_vif.LA_EN <= 1'b0;
                 end
      endcase
      seq_item_port.item_done();
   end
endtask

Here I drive the LA_EN port, however the port always stays at low. I if drive the port before the “forever begin end” block, the port perfectly works.
Any idea on the problem?

Thank you…

In reply to ramazankaan:

Two things:
(1) your driver does not progress in time,
(2) Do you really reach the case item 3’b111?

In reply to chr_sue:

Hi chr_sue, thank you for your answer,

1 - I can assure the timing from the waveform by seeing the data receiving state of the DUT is active when I try to send data, also the inout port data_bus is driven HZ by the DUT at this time.
2 - I place an info macro following line after the “example_vif.LA_EN <= 1’b1;”. According to the info prompt in the transcript, the case item is reached and the LA_EN has taken its value (HIGH). The odd part is here. I can see from the info prompt that the LA_EN has taken its value high, however it is still low at that time in the waveform as appears.

As I am sure that the case item is reached, knowing that it works if I drive the port outside the case statement, what would be wrong?

I would like to add that I drive other ports in the other case items like resetting the DUT and these ports working precisely.

In reply to ramazankaan:

It is confusing what you are writing. Look to this piece of code:

 3'b111: begin 
                    example_vif.LA_EN <= 1'b1;
                    example_vif.data_bus <= req.data_bus;
                    example_vif.LA_EN <= 1'b0;
                 end

You are setting LA_EN to 1#b1 and afterwards in the same time step to 1’b0.
What you see seems to be correct.

In reply to chr_sue:

I thought that as a begin-end block is sequential, data_bus will transmit a value right after the LA_EN port is set to high and the LA_EN will be set to low again after the value is sent. But what you are saying seems logic, so do you suggest to put a little time delay between the statements or anything else?

In reply to ramazankaan:

2 things:
(1) you are using non-blocking assignments. They will imediately continue afetr executed.
(1) A little delay would resolve your issue. But you should use a clocked design, i.e. adding a clock edge in between the 2 assigments.