kiranbhaskar Posted September 16, 2011 Report Share Posted September 16, 2011 Is there a mechanism for communicating between two sequences. I have a virtual sequence body task body() { uvm_do_on ( spi_seq, spi_sequencer) uvm_do_on ( cpu_seq, cpu_sequencer) } Is there a mechanism to stop SPI sequencer after one frame is sent and execute the CPU sequencer to read the register and then again continue SPI sequencer and then again read the register. Regards, Kiran Bhaskar Quote Link to comment Share on other sites More sharing options...
uwes Posted September 16, 2011 Report Share Posted September 16, 2011 hi, a sequencer stops automatically if there are no items in the queue (no uvm_do* active). so there is no need to explicitly stop it. btw: your body is serial (there is no fork in the code you wrote) body() { repeat(2) begin uvm_do_on ( spi_seq, spi_sequencer) uvm_do_on ( cpu_seq, cpu_sequencer) end } /uwe Quote Link to comment Share on other sites More sharing options...
kiranbhaskar Posted September 16, 2011 Author Report Share Posted September 16, 2011 Hi Uwes, Can i stop a seq when there are still items in the queue for instance , In my spi_seq i have body () { uvm_do_with(); //Can i stop the sequence here and continue my CPU seq uvm_do_with(); uvm_do_with(); } can i stop the sequence at the comment above and continue my CPU_seq My CPU_seq has body () { uvm_do_with(); //Can i stop the CPU sequence here and continue my SPI seq uvm_do_with(); uvm_do_with(); } can i stop the CPU sequence at the comment above and continue my SPI_seq hi, a sequencer stops automatically if there are no items in the queue (no uvm_do* active). so there is no need to explicitly stop it. btw: your body is serial (there is no fork in the code you wrote) body() { repeat(2) begin uvm_do_on ( spi_seq, spi_sequencer) uvm_do_on ( cpu_seq, cpu_sequencer) end } /uwe Quote Link to comment Share on other sites More sharing options...
SeanChou Posted September 18, 2011 Report Share Posted September 18, 2011 if the 2 sequence are irrelevent to each other, you could use different thread and run parallel. for example: fork repeat (n) begin // prepare or check frame buffers end forever begin wait (vsync); // read/write some registers end join Quote Link to comment Share on other sites More sharing options...
verifs Posted September 21, 2011 Report Share Posted September 21, 2011 Hi Kiran, You may try using a semaphore with a single key between the two sequences. So when one seq has the key, it can carry on execution, while the other seq waits for the key and blocks its execution till the first one returns the key back to the semaphore. Refer to the example below and you'll get a better idea.. http://www.dvteclipse.com/uvm-1.1-HTML_API/uvm_pkg-uvm_transaction.html#constructor NOTE - 1. the lock.get() and lock.put() in the example are for the semaphore "lock" which you will have to create first. (not shown in example) 2. When two threads are started in parallel (in your case - the 2 sequences, if started in parallel) and both request the key at the same time, i am not sure about the outcome (who gets the key). So you might want to research a little more on that. If you want a particular sequence out of the two of your sequences to execute before the other to do a part of its sequence and then relesase the key for the 2nd one, you will need to find a way to make sure that the sequence of your interest indeed gets the key first. Regards, verifs Hi Uwes, Can i stop a seq when there are still items in the queue for instance , In my spi_seq i have body () { uvm_do_with(); //Can i stop the sequence here and continue my CPU seq uvm_do_with(); uvm_do_with(); } can i stop the sequence at the comment above and continue my CPU_seq My CPU_seq has body () { uvm_do_with(); //Can i stop the CPU sequence here and continue my SPI seq uvm_do_with(); uvm_do_with(); } can i stop the CPU sequence at the comment above and continue my SPI_seq Quote Link to comment Share on other sites More sharing options...
uwes Posted September 22, 2011 Report Share Posted September 22, 2011 hi, i think so far we only talked about howto accomplish things from the technical side - what I didnt hear so far is the use case or use model. depending upon this there might be other solutions other than fork/join, serialization etc. /uwe Quote Link to comment Share on other sites More sharing options...
hillelmiller@ymail.com Posted January 17, 2012 Report Share Posted January 17, 2012 Uwe, As to the need to have a mechanism to enable sequences to communicate with each other. My use case is as follows, I have 2 interfaces, one for my RESET block and another for my CONFIGURATION block. The components and sequences for each of the blocks were developed independently. We have sequences for the RESET block and we have sequences for the CONFIGURATION block. This has been working for us quite some time and till we hit a corner case. The corner case requires that a certain signal does not assert on the RESET block until the CONFIGURATION sequence completes a certain set of transactions (the CONFIGURATION sequence continues doing other things after it reaches this point). I am looking for an elegant communication mechasim to provide this hand shake. I do not want to have to do the following: - Use a semaphore. - Use different phases for each of the sequences. - Use an objection mechanism - Significantly change the current structure and topology. I do want to have some kind of communication mechanism that I set up before I "start" the sequences. Thanks Hillel Quote Link to comment Share on other sites More sharing options...
uwes Posted January 17, 2012 Report Share Posted January 17, 2012 hi, you could use a uvm_event to do that: 1. make an instance of the uvm_event somewhere , store it in the config-db under a known key 2. make the CONFIG sequence trigger the event (pull it from the config db via the known key and trigger it once you pass your now-we-can-have-reset point) 3. in the reset block also retrieve the event and simply wait upon the trigger (if you dont want to change your reset-block-sequences you may want to create a wrapper sequence waiting upon the event and then starting the real sequences. at the same time if you are able to identify the now-we-can-have-reset point in the monitor there would also be no need to change the config sequences.) regards /uwe Quote Link to comment Share on other sites More sharing options...
Roman Posted January 30, 2012 Report Share Posted January 30, 2012 Hi, This is the inter-working stuffs when usecase verification. You could also reserve one or more inter-banks in the shared physical memory(such as DDR3,Internal RAM ,etc.) . All sequences could see the inter-banks. then, You may use these inter-banks to make communication between sequences(for example: trans message via write/read API...., trigger/wait(just like uvm_event do.)) Quote Link to comment Share on other sites More sharing options...
whiteriver Posted August 3, 2012 Report Share Posted August 3, 2012 Hi, I ran into a similar situation Hillel described. I had to communicate a trigger from monitor_1 to sequence_2 which are in separate environments. Here is what I did: @ monitor_1: uvm_event specific_ev; // no new() for it task run_phase ... specific_ev.trigger(); endtask @ top environment: uvm_event mon_1_seq_2_ev = new("mon_1_seq_2_ev"); function connect_phase(); ... env_1.agent_1.monitor_1.specific_event = mon_1_seq_2_ev; env_2.agent_2.assign_event(mon_1_seq_2_ev); endfunction @agent_2: function assign_event(uvm_event mon_1_seq_2_ev); if (is_active == UVM_ACTIVE) begin sequencer.specific_ev = mon_1_seq_2_ev; end endfunction @sequencer_2: uvm_event specific_ev; // just a declaration @sequence_2: `uvm_declare_p_sequencer(sequencer_2) task body(); begin ... // `uvm_do_.. p_sequencer.specific_ev.wait_trigger(); ... // `uvm_do_.. end endtask Comments of a better or more elegant implementation (perhaps using uvm_event_pool) are welcomed! Quote Link to comment Share on other sites More sharing options...
whiteriver Posted January 17, 2013 Report Share Posted January 17, 2013 I've figured a simpler way to trigger events between verification blocks. Instead of creating all the structure like on my previous post, I used the default pool (global) from uvm_event_pool to send a trigger to synchronize two sequences on different environments. Here it is: on the triggering sequence: uvm_event event_a; uvm_event_pool event_pool; function new(...); ... event_a = new("event_a"); event_pool = uvm_event_pool::get_global_pool(); event_pool.add("event_a",event_a); endfunction virtual task body(); ... event_a.trigger(); ... endtask on the sequence receiving the trigger: uvm_event event_a; uvm_event_pool event_pool; virtual task body(); event_pool = uvm_event_pool::get_global_pool(); if (!event_pool.exists("event_a")) begin // error message end event_a = event_pool.get("event_a"); ... event_a.wait_trigger(); ... endtask Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.