Quantcast
Channel: Cadence Functional Verification
Viewing all articles
Browse latest Browse all 652

Concurrent Actions in Specman: Part 2

$
0
0

In the previous blog: Concurrent Actions in Specman, we discussed the existing options: all of  (which awaits completion of all branches) and first of (which terminates at the first completion of any branch). In 19.03 we added enhancement on top of these existing options, we made them more dynamic. 

In all the examples in the previous blog, the number of branches was constant (all the examples used 2 branches). What if we need the number of branches to be dynamic and be determined only in run time? Let’s take for example an agent that has a TCM named send_data() and the environment has a list of agents. It needs to execute the send_data() TCM of each item in agents and wait until all are done. If we use for each on agents, the TCMs will run in sequel, one after the other. If we use the concurrency action all of, we must explicitly define the actions so we cannot use it on list items (assuming the size is unknown). What we need is the combination of both.

Starting from Specman 19.03, we have a new capability, the concurrent actions can be dynamic. Meaning, we can put all oforfirst ofnext to the for each in list statement as demonstrated in the following examples.

We will go back to the examples we used in the previous blog – we used the daily task of feeding a child. Look at the child unit.

unit child {
   eat() @sys.any is {
      message(LOW, "Child started eating the food");
      wait [90] * cycle;
      message(LOW, "Child finished eating all the food");
     };  
};

Example 1: all ofnext toeach in list items (using ‘for each’ syntax)

Let’s first start with an example that does not need this dynamic. Let’s assume I want to have a dinner with my kids and I want to know when they are all done. I have no problem (even with older versions of Specman) - assuming I have 3 kids for example, I can use all of in the following way:

 all of{
   children[0].eat();
   children[1].eat();
   children[3].eat();
 };

But on weekends we sometimes have guests we want to feed as well and the number of kids coming over is changing. What we need to do is to use the new capability by using all ofnext to for each:

unit familyVisit {
   children : list of child is instance;

   eat() @sys.any is {
      all of for eachin children {
      it.eat();
      };

     message(LOW, "All children are fed.");
  };
};

This is the result of running this code. As you can see we have 5 children that are having dinner concurrently. Note that if we remove the all of that is before the “for each” statement, the children will eat one after the other serially.

Running the test ...

[0] child-@1: Child started eating the food
[0] child-@2: Child started eating the food
[0] child-@3: Child started eating the food
[0] child-@4: Child started eating the food
[0] child-@5: Child started eating the food
[90] child-@1: Child finished eating all the food
[90] child-@2: Child finished eating all the food
[90] child-@3: Child finished eating all the food
[90] child-@4: Child finished eating all the food
[90] child-@5: Child finished eating all the food
[90] familyVisit-@6: All children are fed.
Last specman tick - stop_run() was called

 

Example 2: first of for list items (using ‘for each’ syntax)

Let’s assume that I want to also serve deserts and have some contest- I will serve deserts until one of the children is finished, then deserts are over! We will use first of:

 

extend child{
   have_desert()@sys.any is {
      message(LOW, "Child started eating ate his desert.");
      wait [100] * cycle;
      message(LOW, "Child finished eating his desert.");
      };
};

 

extend familyVisit{
   have_desert() @sys.any is{
      first of for each in children{
      it.have_desert();
      };
      message(LOW, "One child finished his desert, deserts are over!.");
    };
};

 

This is the result of running this code:
 
[0] child-@1: Child started eating ate his desert.
[0] child-@2: Child started eating ate his desert.
[0] child-@3: Child started eating ate his desert.
[0] child-@4: Child started eating ate his desert.
[0] child-@5: Child started eating ate his desert.
[100] child-@1: Child finished eating his desert.
[100] familyVisit-@6: One child finished his desert, deserts are over! .
Last specman tick - stop_run() was called
 

Example 3: first of for list items (using ‘for i from x to y’ syntax)

In the two examples we have seen, we were using the “for each” syntax. Note that you can also iterate over list items and activate concurrent actions using the ‘for i from x to y' syntax. In our example, let’s assume that we have only 3 deserts and we want to give them only to the second, third and fourth children around the table:

 

extend familyVisit{
   few_have_desert() @sys.any is{
      all of for i from 2 to 4{
      children[i].have_desert();
      };
     message(LOW, "The 3 children finished their deserts.");
   };
};

This is the result of running this code: 
[0] child-@1: Child started eating ate his desert.
[0] child-@2: Child started eating ate his desert.
[0] child-@3: Child started eating ate his desert.
[100] child-@1: Child finished eating his desert.
[100] child-@2: Child finished eating his desert.
[100] child-@3: Child finished eating his desert.
[100] familyVisit-@4: The 3 children finished their deserts.
   

Enjoy your concurrent actions!

Orit Kirshenberg

Specman team


Viewing all articles
Browse latest Browse all 652

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>