SeanChou Posted August 5, 2011 Report Posted August 5, 2011 Hi, The user guide defines the root sequence is the one which has no parent and be assigned to a defualt sequence of a phase of sequencer. And only the root sequence's starting_phase is set automatically. Other sequences created by `uvm_do macro do not have handle of the starting_phase. so the question is how to raise the objection not entering next phase in the sequences which are not root? Thanks! Quote
uwes Posted August 8, 2011 Report Posted August 8, 2011 hi, in general you only need a single/last objection per phase to stop the phasing system from progressing. so you dont need every sequence to object - only the usually (single) root sequence objects the phase progression. this at least is the standard case - you could have your sequences also more "phase aware" such as - starting a sequence in one phase BUT objecting the end of another phase - waking up a sequence at sometime BUT wanting all traffic to complete in the current phase there are more cases but here you have to be explicit in coding which phase end you want to object and uvm doesnt provide a framework for that yet. you have to communicate/derive your starting/ending phase via standard mechanisms (uvm_config_db, event_pool, tlm_ports).. /uwe Quote
vishal.jain Posted August 24, 2011 Report Posted August 24, 2011 Hi, One way to get around this is to create a base sequence where flow is defined in separate tasks. build calling pre_main -> main -> post_main tasks. Base sequence can add objections to pre_main and post_main. main is now left for users to implement. -Vishal Quote
calvapete Posted November 23, 2011 Report Posted November 23, 2011 Hi Guys, I'm having problems with objections in my sequences... I am starting a number of sequences in parallel(in my testcase), to do this I use fork/join blocks to ensure that each sequence can run independently. The issue is that the sequences themselves are reactive and have forever loops within them. This being the case I want to start them with a fork/join_none statement. However I can't see a way to raise an objection in each sequence, so that it can wait and run at least once after its trigger event, then drop its objection. This is because the body task does not take phase as an argument. I've tried using starting_phase.raise_objection(). But starting phase is only set for the default sequence, and I'm running multiple sequences on a single sequencer. Also I've tried uvm_test_done.raise_objection(), but this doesn't seem to do anything. So my current method of resolving this is to have at least one of the sequences have an exit from it's loop, then I can call a fork/join_any. But doing this seems to negate any need for objections at all, also I do want the sequences to all reach a suitable exit point before the simulation ends. Quote
Erling Posted November 23, 2011 Report Posted November 23, 2011 But doing this seems to negate any need for objections at all, also I do want the sequences to all reach a suitable exit point before the simulation ends. It seems to be just one case where objections are actually needed, and that is to prevent immediate kill of the toplevel test. This can be hidden in a common base class for tests, and start of any test will then be secured. This will not solve the end of test/phase problem, but it may be easier to think about this when the objections are out of sight. FWIW, one method to consider in the situation you describe could be equipping your parallel running sequences (and/or environment) with some sort of indicators for use by the test to check the current state of the individual sequences. It can be a simple done or triggered flag, an iteration count, a state enumeration, an event, a run level, a coverage percentage, whatever. With this in place, simply fork all sequences in parallel and join_none, and then fork a process for each sequence to wait for whatever indicator you want to use to consider the sequence completed, and join, after which all sequences will have reached a suitable exit point according to the indicators, and you can now drain if necessary, and then return to caller to end the test/phase. Erling Quote
uwes Posted November 24, 2011 Report Posted November 24, 2011 hi, the bottom line issue is that only phase aware objects can clearly identify the "current" phase exactly. other objects can only be told what the exact current phase is (there is a set of concurrent active phases, eg. run + pre_configure (+ eventually user defined phases)). you cannot query the phasing and determine to which phase you belong to. the "default_sequence" capability in the sequencer uses the phase info provided to set the current_phase for started root sequences. i see the following way to address your issue: 1. you know in which phase you start/end your sequences: then you can get the phase object and object the phase termination (and drop once finished) uvm_domain uvm= uvm_domain::get_uvm_domain(); uvm_phase p =uvm.find(uvm_shutdown_phase::get()); p.raise_objection(...); 2.your sequences do NOT span multiple phases and you dont know the starting phase: the wrap it in a meta sequence which in in its body forks all your sequences. when the meta sequence is started via the default sequence hook then starting_phase is set and you can propagate it to your child sequences 3. your sequences span multiple phases: start your sequences in the phase_started hook - then you know the current phase. simply propagate it to your sequences. /uwe Quote
Erling Posted November 24, 2011 Report Posted November 24, 2011 ...simply propagate it to your sequences. This will distribute the objection, but my understanding was that the sequences should run to a suitable exit point. But how does a reusable sequence know what is a suitable exit point for a given test? Also, dropping the phase objection in a sequence to signal that it has reached its suitable exit point, is not the same as dropping the objection to signal that the phase may end. Consider a phase with a drain time. That should delay phase end, but what is delayed is the signal that the sequence has reached a suitable exit point. If this is a loop sequence, it will continue to run and if it triggers components with objection raise/drop pairs, the objection will stay raised forever, because the drop will be canceled periodically, and the test/phase will never run to completion. Erling Quote
uwes Posted November 25, 2011 Report Posted November 25, 2011 hi, raise and drop of objection should encapsulate sections of behaviour/code/sequences were YOU(=the sequence) object normal phase progression. that doesnt mean that with the drop you move on to the next phase.it is upto the testwriter/sequence writer to define/determine when phase progression is NOT wanted repeated raise/drop etc is a common scenario. ONLY if there is consensus (by having NO objection to the phase end) the phaser moves to the next phase.some consequences of that are: 1. primary stimulus (when raising objections) needs to be finite 2 if the primary stimulus is NOT finite its upto the developer/user to ensure that raise/drop at least has a chance to reach the all_objections_dropped state (for instance variable gaps, big enough gaps between component behaviour) 3. only primary (and "self" active stimulus) should raise/drop objections - reactive elements should NOT 4. other components (reactive/monitoring) may also raise/drop objections to extend runtime (sort of a drain time but NOT time based). a typical example would be a scoreboard objecting the end of the run-phase when there are transactions pending Quote
Erling Posted November 25, 2011 Report Posted November 25, 2011 some consequences of that are: Why would anyone want to deal with these consequences? I want to have infinite primary stimuli. I want to have multiple sequences running in parallel forever, even with critical sections in them that should not be terminated abortively. An example could be a set of looping sequences running in parallel driving the dut in the same way software is going to drive the dut in the final product. One test could end when a coverage collector bound inside the dut signals enough is enough, another test could end when some other goal has been reached, reusing the stimuli as is. The objections do not solve a problem that I am aware of, but add problems and consequences that I don't need. Therefore, I don't use them. Erling Quote
uwes Posted November 25, 2011 Report Posted November 25, 2011 Why would anyone want to deal with these consequences? I want to have infinite primary stimuli. I want to have multiple sequences running in parallel forever, even with critical sections in them that should not be terminated abortively. An example could be a set of looping sequences running in parallel driving the dut in the same way software is going to drive the dut in the final product. One test could end when a coverage collector bound inside the dut signals enough is enough, another test could end when some other goal has been reached, reusing the stimuli as is.The objections do not solve a problem that I am aware of, but add problems and consequences that I don't need. Therefore, I don't use them. Erling - how do you achieve consensus WHEN to stop your simulation? you need some mechanism to prevent the termination in the "critical sections". no matter how you call the thing its in general doing what objections do as well - running infinite stimulus and have an internal coverage progress watcher is imho not a good strategy. typically i try to run a set of shorter tests instead of a indefinite long one. easier to debug upon a failure, easier to run in parallel, its easier to reuse finite sequences,.... - see point#2 if you have infinite stimulus - thats ok even with objections as long as there are windows in the traffic which allow the simulation to end. Quote
calvapete Posted November 25, 2011 Report Posted November 25, 2011 Okay, my sequences are both reactive and finite. I load up seq_item_count at the start of the test and the sequencer plays out the items reactive to the DUT or the next sequence in the chain, depending on the test bench. This is where I thought I could use objections, to ensure that the sequence does not finish until the last RSP has been received back from the Driver/Next Sequencer. I'm also having an issue passing a seq_item through a chain of sequencers. When I do this, it seems to complete on the first sequence at the same time as it is passed down the chain. My current solution is to clone the seq_item and pass it down the chain, then clone the RSPs back up the chain, but I can't help but think that this shouldn't need to be done. Quote
Erling Posted November 26, 2011 Report Posted November 26, 2011 - how do you achieve consensus WHEN to stop your simulation?. The simulation stops when the test is done, and all other objects are executing outside critical sections. The first condition is taken care of by the toplevel test, the second is dealt with by a common base class for tests. Objections are used only for one hidden raise to avoid the default kill and one hidden drop to have uvm take down the phase process ensemble at end of phase, and proceed. you need some mechanism to prevent the termination in the "critical sections". Yes, but this is about protection, and not expensive inter object communication, which is what objections are doing. A trivial replacement class that can protect code at minimum overhead. Erling Quote
Erling Posted November 26, 2011 Report Posted November 26, 2011 This is where I thought I could use objections, to ensure that the sequence does not finish until the last RSP has been received back from the Driver/Next Sequencer. If the sequence is finite, couldn't you just raise the starting_phase objection and drop it when the RSP has arrived? You can always store the starting_phase manually if this isn't done automatically. I'm also having an issue passing a seq_item through a chain of sequencers. Not sure I understand what you are doing, but it sounds like there is some conflict in accessing the data if cloning helps. More details may help. Erling Quote
uwes Posted November 28, 2011 Report Posted November 28, 2011 Okay, my sequences are both reactive and finite typically this doesnt go together. if its reactive the device never knows how much traffic is comming. therefore it should be able to answer at any time for an infinite number of requests. your device sounds like a DMA style device. you set it up for N transfers, then the device is supposed to perform N transfers, right? you could for instance in the programming sequence raise N objections and with every DUT transfer you see you drop one. /uwe Quote
uwes Posted November 28, 2011 Report Posted November 28, 2011 Yes, but this is about protection, and not expensive inter object communication, which is what objections are doing. A trivial replacement class that can protect code at minimum overhead.Erling objections are a generic way to reach the consensus. obviously there are features in objections which not everyone needs in every testbench such as hierarchical propagation. and yes in some cases you dont need them at all (if you only got one active component/sequence) nevertheless they provide a common functionality applicable to almost all designs (incl. raise/drop ordering, debug,...). speaking about "overhead" if you are concerned about that then you should first relate your simulator speed improvement vs the time needed to build a custom solution. there are more sections in uvm which are simple to utilize and cut your code down BUT come at the expense of a runtime penalty (field macros, uvm config db, string operations in config db, messaging,... raise/drop times should be negligible (even in its current form) compared to the rest of the tb. if this is different for you some design criterias would need to be re-evaluated but this requires your input/testcases/examples. Quote
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.