How do I build Assembler block using smaller elements.
For example: Service block consists of seize + delay + release.
Thanks!
This is not super easy, but it's one of the exercises of my course that you can find at noorjax.teachable.com
you can use wait blocks to wait for the quantity of parts to be accumulated, then combine and batch blocks to combine everything together into a service block.
Related
I have a simple model which has two Pedestrian Service blocks after one another. Is there a way to limit the queue for a service so it has a 'knock-back effect' on the queue/path area before?
I assume you can add a wait block before every ped-service that frees an agent if the ped-service queue is below a certain length. But, that seems a little messy (maybe a limitation of the pedestrian library) - would be keen to hear what best practices are from the experts (cough Ben & Felipe) :)
You can add a simple wait or queue block before the service block and only let them exit the queue if the pedestrians in the service blocks are below a threshold.
You need to implement the release logic in the on enter for the queue
as well as for the exit at the service block
But, in order to make your snake path act as a queue you will need to add walls around it, else as per your example the pedestrians will group around the end of the path in a bunch. You will also need to set your pedestrain width to just more than half your path width to ensure they don't bunch inside the path
I am exploring different ways to end a UVM test. One method that has come often from studying different blogs from Verification Academy and other sites is to use the Phase Ready to End. I have some questions regarding the implementation of this method.
I am using this method in scoreboard class, where my understanding is after my usual run phase is finished, it will call the phase ready to end method and implement it. The reason I am using it my scoreboard's run_phase finishes early, and there are some data into queues that need to be processed. So I am trying to prolong this scoreboard run_phase using this method. Here are is some pseudo-code that I have used.
function void phase_ready_to_end(uvm_phase phase);
if (phase.get_name() != "run") return;
if (queue.size() != 0) begin
phase.raise_objection(.obj(this));
fork
begin
delay_phase(phase);
end
join_none
end
endfunction
task delay_phase(uvm_phase phase);
wait(queue.size() == 0);
phase.drop_objection(.obj(this));
endtask
I have taken inspiration for this implementation from this link UVM-End of Test Mechanism for your reference. Here are some of the ungated thoughts in my mind on which I need guidance and help.
to the best of my understanding the phase_ready_to_end is called at the end of run_phase and when it runs it raises the objection for that scoreboard run_phase and runs delay_phase task.
That Delay Phase task is just waiting for the queue to end, but I am not seeing any method or task which will pop the items from the queue. Does I have to call some method to pop from the queue or as according to the 1st point above the raised objection will start the run phase so there is no need for that and we have to wait for a considerable amount of time?
Let me give you some pre-context to this question. I have a scoreboard where there are two queues whose write methods are implemented and they are being fed correctly by their source.
task run_phase (uvm_phase phase);
forever begin
compare_queues(); // this method takes data from two queues and compares them, both queues implementation are fine and they take data from their respective sources. Let me give you a scenario, let's suppose there are a total of 10 transactions being generated but the scoreboard was able to process only 6 of them and there are 4 transactions left when all objections are dropped. So to tackle that I implement this phase_to_ready_end method in my scoreboard.
end
endtask
The problem with this method that I am having is that, when I raise the objection in this phase_ready_to_end and call delay_phase method, nothing happens. And I am curious is there more to this implementation or not?
Sorry for the delay. I have shared more context to the existing question. Please see to that, let me know if it is confusing.
We have a pair of monitors that calls write method implemented inside the scoreboard. The monitors typically capture the transaction from BUS and call these WR methods to push the transactions. Thus two source and destination monitors WR into two - source and destination - queues as and when they find the transactions.
We have a checker task with RD-n-check running in forever loop in the run-phase of scoreboard. It's in a while loop and watches if the destination queue has non-zero entry. Once it finds so, it pops the head entry from destination queue and then pops the head entry from source queue as well and compares the two entries to declare if the check was a PASS or FAIL.
There are more than 2 queues and more than a pair of source/destination of course, but broadly this is the architecture around here.
Now in the current scenario, it seems that the checker tasks stop prints after certain point of time in some of the test cases. Upon adding debug prints thoroughly, it seems that checker tasks that does the job #2/#3 above and gets called inside the forever loop of the run-phase, exits gracefully one last time. However they are entered again - which is to say that the forever loop that should be calling them didn't call. As if the forever loop of run-phase stopped completely.
We also added another forever loop in run-phase that observes whether the queues are empty. From prints inside that parallel loop and from the monitor prints, we know that the queues aren't empty and monitors did push WRs into the queues for a long time.
It seems that the forever loop stopped working suddenly ( going by prints spewed out) all of a sudden but another set of threads that we added in runphase in another forever loop just to monitor those queues - keep printing that the queues have contents. So run-phase shouldn't be over but the checker tasks running in forever has stopped.
We are using Vivado 2020.2 for the simulation. This is a baffling/weird problem for us and we did go through prints multiple times to make sure nothing has been missed out. It seems we are missing very very basic or has hit a bug/broken some basics of UVM coding to land into here.
If you have any help, thoughts here, will appreciate that greatly.
The function phase_ready_to_end() gets called at the end of every task-based phase when all objections have been dropped (or never raised at all).
Typically a scoreboard has a queue or some kind of array of transactions waiting to be checked sent from a monitor via an analysis_port write() method. If your scoreboard is an in-order comparison checker, the queue size is zero when there are no more transactions waiting to be received.
If you look at the code in the link you shared, there is the following in the write_south method doing exactly that:
if (!item.compare(item_stream.pop_front()))
I have an agent which needs to seize two different equipment units, one excavator, and one truck. It seizes excavator first, release it and then it seizes truck. I added some functions to the release excavator block but interestingly the agent goes to seize truck block without going to release excavator block! so thus functions do not work. How this is possible?
Please see the attached file. How can I solve this? Thank you.
That's weird. Have you tried adding any other block in between seize and release exc? In some cases it happens that some code isn't executed (i.e. in the options on a selectOutput) because you defined the conditions in the block inmediately before that. But in your case the counters remain in 0 and the next ones have the same value as the previous ones (you're sure the blocks are properly connected, right? they seem to be connected at first sight).
Our model has a ProductionOrder seize some Operators. The seize block has a Prepare flowchart for the Operators to move through an airlock (PAL) into a room. After the ProductionOrder operation (a delay block), the Operators are released and have a Wrap-Up flowchart that sends them out of the room through the same airlock. Because this airlock can only have 2 people, we need to restrict the combined Operators in the Prepare and Wrap-up flowcharts to 2 people in the airlock regardless of them coming in or going out (i.e. max 2 at any time).
If we do this by connecting the blocks with connectors, an error comes up basically saying you can't connect a Prepare flowchart to a Wrap-up flowchart.
Is there a way to link the circled queues and restricted area start blocks?
Instead of using a queue (PALqueue) use a wait block there (in both flows)
And you can do in the on enter of each wait block PALqueue:
if(PALCapacityLimit.entitiesInside()+PALCapacityLimit1.entitiesInside()<2){
self.free(agent);
}
And in the on onter of the PalInLimit (both)
if(PALqueue.size()>0)
PALqueue.free(PALqueue.get(0)); //remember now PALqueue is a wait block
else if(PALqueue1.size()>0)
PALqueue1.free(PALqueue1.get(0));
And there you go :)
I understand that some indeterminism stems from parfor's parallel nature but I don't understand why it should be entirely random. Is there any way to force parfor to respect (at least loosely) the order of the loop? More specifically I would like that in the case of:
parfor i=1:100
do_independent_stuff()
end
each worker of the pool when asking for a new task (i.e. in this case a new iteration of the loop) to be affected the lowest i that hasn't been computed or affected to a worker yet.
I think its by design that running something in parallel assumes that order is not important, at least in Matlab. Each thread/worker should be independent of each other. However, as indicated in this question, you could try job and task control interface to give you some level of control.
Firstly, in practice, PARFOR isn't "entirely random" - you can easily observe that it sends out chunks of loop iterates in reverse order. In R2013b and later, if you need more control over ordering (if, for example, you know that certain of your independent things are likely to take a long time, and therefore wish to start computing them first), you can use PARFEVAL.
If you need to loosely synchronize things, for instance wait until some thread as finished or has reach some point before to start another one, best should be to use semaphores, locks, mutex, etc...
I don't know if 'Parallel toolbox' includes such synchronization objects, but here is some workaround to create semaphore for instance:
https://stackoverflow.com/a/22874669/684399
You can also use objects in 'System.Threading' namespace (requires .NET):
Init:
someResultAvailable = System.Threading.ManualResetEvent(false);
In some job:
... do work ...
someResultAvailable .Set();
... continue ...
In another one:
... do work ...
if (!someResultAvailable.WaitOne(10000))
{
error('Timeout waiting for result from other thread');
}
... continue now knowing that results are available ...