Jump to content

Router Sequence (also known as your doing it wrong)


Recommended Posts

I'm developing an AXI agent. Given that AXI's read and write channels are basically completely separate interfaces that are just bundled together, I created separate master agents for the read and write channels. However, they share a common sequence item class.

You can use the two masters separately. This implies that a sequences feeding the write master and only do write, and a sequence feeding the read master can only do reads. You'd do this when you want to explicit control over when transactions are running concurrently on the two interfaces.

However, when you don't care about that concurrency, the separation is just a pain. So I created another higher level agent which instantiates both the read and the write master. This allows me to write a sequence that does both reads and writes, but I lose some ability to make concurrent transactions this way. Ease of use vs. power.

This agent has a virtual sequence called RouterSequence that routes the sequence items from the higher level sequencer to the appropriate lower level master, based on the transaction type (read or write). This works, however I'm not sure that what I'm doing is a good idea.

*Why don't the BB codes work?*

class RouterSequence extends uvm_sequence;
      uvm_sequencer#(AxiBurst) up_sqr;
      uvm_sequencer#(AxiBurst) read_sqr;
      uvm_sequencer#(AxiBurst) write_sqr;
      
      `uvm_object_utils(RouterSequence)
      
      virtual task body();
         AxiBurst itm;
         forever begin
            int saved_seq_id;
            uvm_sequence_base saved_parent_seq;
            up_sqr.get_next_item(itm);
            saved_seq_id = itm.get_sequence_id(); // this get's stomped when the item is forwared
            if (itm.kind == AxiBurst::READ)
              begin
                 // trying to make this router sequence transparent, by using itm.get_parent_sequence() 
                 // in the request to the next sequencer
                 read_sqr.wait_for_grant(itm.get_parent_sequence(),itm.get_parent_sequence().get_priority()); 
                 read_sqr.send_request(itm.get_parent_sequence(),itm);
                 read_sqr.wait_for_item_done(itm.get_parent_sequence(),itm.get_transaction_id());
              end
            else
              begin
                 write_sqr.wait_for_grant(itm.get_parent_sequence(),itm.get_parent_sequence().get_priority()); 
                 write_sqr.send_request(itm.get_parent_sequence(),itm);
                 write_sqr.wait_for_item_done(itm.get_parent_sequence(),itm.get_transaction_id());
              end // else: !if(itm.kind == AxiBurst::READ)
            itm.set_sequence_id(saved_seq_id);  // restore the stomped sequence_id, so up stream wait_for_dones work
            up_sqr.item_done();
         end
      endtask // body
   endclass // AxiRouterSequence

-Ryan

Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...