How to get virtual interface in sequence

In reply to cgales:

If it is not 1:1 req-resp sync mechanism, ie interface requests 10 resposes back to back without waiting for one to arrive. Where should the storage be implemented - in driver?

In reply to harshbandil:

I’d like to underline what cgales is saying. You are running into big trouble if you deal with pinlevel signals in the sequence, because it has a completely different synchronisation mechanism
Do you have a pipelined processing of sequences, i.e. a second sequence can be processed before the first on has been completed. Thi is the most simple case. You could haave even more sequences in your pipeline.

In reply to chr_sue:

I am not advocating the use of I/f level signals in sequence. I am trying to understand if there is any mechanism where we don’t need to generate dummy transaction in sequence. .

Yes, All the sequences(a group of responses - 1 req, multiple responses) need to be processed in pipeline and their trigger (req from if) can come any time regardless of the completion.

As mentioned by cgales, a null/dummy transaction can be generated in sequence. Once driver sees this transaction, it can wait for request from interface. If driver sees more than one request before the transaction is fetched from sequencer, in this case driver does not need to wait as it has already received the request, so somewhere it needs to save those requests. Is it recommended to create a separate storage/tlm fifo in driver?

There are several different approaches that you can take, depending on your slave requirements:

  • For a simple memory slave, you can store the memory data in the driver. When a write/read request is received, the slave can try to get a response from the sequencer. If there isn’t a sequence_item available, the slave can respond with a default response.
  • If the slave can have multiple outstanding requests, then it can maintain a queue of outstanding requests, responding to each one as it gets the sequence_items from the sequencer.

Remember that there should be no delay in receiving the response sequence_item from the sequencer since the testbench is untimed.

In reply to praneethmspd:

Hi,

Get the virtual interface into your sequencer. Using p_sequencer, You can access the virtual interface in sequences.

In reply to sri205:

You NEVER want to drive any signal outside of your driver. This will result in multiple components driving signals which is a very bad idea. Only drive signals from your driver.

You can encapsulate your entire AXI transaction into a sequence item. When you do this, your driver will conduct all phases of the AXI transaction per the sequence item. Don’t have part of the transaction performed by the sequence and part by the driver.

In reply to sri205:

If you do not have a piplined approach implemented your sequencer is always waiting until you are calling item_done() ot put() in the driver, independently whether you are sending bac a response.
cgales doesn’t want you to modify your VIP, but using OOP inheritence you can extend your VIP transaction, thus defining a new sequence item which is VIP transaaction.

In reply to sri205:

It’s not really clear from your post what you are trying to accomplish.

Is the CPU being replaced by a UVM VIP? Is the CPU or IP protocol compliant by not waiting for a response or not supporting non-posted transactions.

If an IP block or verification component isn’t protocol compliant, then you have bigger issues that you need to address. If there are parts of the protocol that are optional and not supported, then your verification IP should allow for this.

Why is modifying the driver/monitor not an option? As a verification engineer, your job is to create the VIP necessary for your job. If it is third party VIP, then you need to work with your provider to determine how to handle any non-compliance issues.

In reply to sri205:

You have to differentiate between the sequence item/transaction data fields and the virtual interface. These are two completely different things. The signals of the AXI interface are defined. I guess you do not want to add more signals to this interface. Right?

In reply to sri205:

In reply to chr_sue:
Yes, I’ve not yet worked out the differentiation yet. actually the interface doesn’t have axi signals at all. it has open core protocol interface. Nevertheless, the scenario is the same i suppose. Can you point me to the example under cookbook examples which gives me the scenario i’m looking for under this link?

An Open Core Protocol Interface does not exist. I guess you are using an Open Core AXI interface, right? And I’m not sure if you want to replace the AXI RTL by the AXI VIP, because you have to drive the AXI RTL from an AXI VIP.
I believe you need a pipelined driver implementation. One of the cosing examples you can find here:
https://verificationacademy.com/cookbook/cookbook-code-examples#UVM_Examples:#UVM_Examples:#UVM_Examples:

Uvm_use_models_pipelined_get_put.tgz

In reply to sri205:

This was my mistake. I was assuming you were using an example from the Open Core Download page (http://opencores.org/)

In reply to sri205:
See below.
interface bus_if;
logic clk;
logic resetn;
logic[31:0] addr;
logic[31:0] write_data;
logic rnw;
logic valid;
logic ready;
logic[31:0] read_data;
logic error;
endinterface: bus_if

class bus_seq_item extends uvm_sequence_item;
// Request fields
rand logic[31:0] addr;
rand logic[31:0] write_data;
rand bit read_not_write;
rand int delay;

// Response fields
bit error;
logic[31:0] read_data;

endclass

In reply to sri205:

In the sequence item you do not have any control signals.
The intention for the interface and the sequence item is different. The interface has to drive the ports of your design. It is a pin-level interface.
The seq_item is provoding data necesary to drive the pin interface. In your case the seq_item has to have data members for addr, wrdata and rddata.

Hi,

I completely understand the part that sequence should not drive any signal.
But I am not very clear about the mistake in sampling a signal in a sequence instead of getting a response transaction from driver.

Although I get the difference that data item and component types of classes and so it is kind of “grammatically wrong” to access component variables inside data items.
Also being not of component type sequence will not have access to phasing.
But I thought p_sequencer is used for this purpose only.

So we can get interface handle in sequencer and from there to sequence perhaps.

I would like to have your further kind suggestions regarding this.

Regards,
Chandan

In reply to chandanc9:

One of the big benefits UVM is providing is the usage of TLM (transaction-level-modelling). It increases the performance of a UVM testbench dramatically and makes the processing of data very simple because it does not know clock and control signals. Processing is focused only on valuable data. All other aspects are removed on this level. If you deal with interface signals in sequnces you are loosing all these benfits and make the execution of sequences very complicated.
You should think about whether ist’s worth to do this.

In reply to chr_sue:

Thanks @chr_sue… I understand about abstraction level now…

In reply to chr_sue:


class vseq_sandbox extends uvm_sequence #(uvm_sequence_item);
  `uvm_object_utils(vseq_sandbox);

  virtual interface cool_if my_if; // assigned by test

  function new(string name="");
    super.new(name);
  endfunction

  virtual task body();
    my_if.wait_clks(10);
  endtask

endclass

This is very straight-forward, but violates the principles of TLM. thoughts?

Guyz, instead of using virtual interface in a sequence , why cant we create a polling sequence which eventually will grab the interface bus status(in driver) .

This polling sequence can be called whenever you want the status of any pin in DUT.

Any issue in this?

Thanks,
Suyog

In reply to bmorris:

In reply to chr_sue:


class vseq_sandbox extends uvm_sequence #(uvm_sequence_item);
`uvm_object_utils(vseq_sandbox);
virtual interface cool_if my_if; // assigned by test
function new(string name="");
super.new(name);
endfunction
virtual task body();
my_if.wait_clks(10);
endtask
endclass

This is very straight-forward, but violates the principles of TLM. thoughts?

This is not a question of violating rules. You are loosing the benfits of TLM. TLM is an untimed modelling style. TLM does not know about clock cycles it knows only the right order of commands. Finally it behaves like a piece of software.

In reply to chr_sue:

Personally, I’ve tried using TLM for these kinds of operations, and it’s always clunky and bloated.

Lets say I’ve got a sequence, and the very first thing it has to do is wait for the DUT to initialize. This happens at 7ms.

I could…

  1. Just have the seq wait 7.5 ms, then start.
  2. Use a virtual interface to detect a DUT signal going high (assuming it exists)
  3. Go make a new transaction, agent, the previous interface, detect that init is done, broadcast the transaction, somehow connect this to the sequence? All in the name of TLM?

I think a better approach would be to use TLM for things it is good at, and VI for what it’s good at.