Scheduling Tasks with hiRegTimer()

Contents:

  1. How to use hiRegTimer()
  2. Repeating tasks
  3. Practical example
  4. Understanding SKILL’s tm structure
  5. More tips
  6. Conclusion

In Cadence's Virtuoso environment, automation tools and scripts are essential for optimizing chip design development. We can benefit even more from automating tasks to run at regular intervals or specific times without manual intervention. Whether you need to monitor conditions or execute background tasks for resource cleanup, scheduling these tasks to run repeatedly is invaluable.

SKILL offers a function for scheduling tasks - hiRegTimer(). This function allows you to schedule and execute tasks at regular intervals, freeing up your time and resources for more critical activities. This guide will show you how to use hiRegTimer() to schedule and repeat your tasks efficiently.

1. How to use hiRegTimer()

The hiRegTimer() function takes two arguments - a function to run (provided as a string) and a number representing tenths of seconds after which the function should run.

Example:

1procedure( func() 2 printf("Hello\n") 3) 4 5hiRegTimer("func()" 100)

In this example, we register func() to run after 10 seconds.


Example of running hiRegTimer() function in CIW

Example of running hiRegTimer() function in CIW

Note: Scheduled tasks will run in the current Virtuoso session. If you reopen Virtuoso, tasks from the previous session will be removed.

2. Repeating tasks

To repeat a task, we’ll need to run hiRegTimer() again. To do so, we can create a simple recursion, like this:

1procedure( func() 2 printf("Hello\n") 3) 4 5procedure( repeatTask(function) 6 let( (repeatCommand) 7 8 sprintf(repeatCommand "%s repeatTask(\"%s\")" function function) 9 hiRegTimer(repeatCommand 100) 10 );let 11);procedure

Here, the first argument of hiRegTimer() is modified to include a recursive call to repeatTask(). In the example above, the repeatCommand variable will contain “func() repeatCommand(\”func()\”)”.

Tip: To stop the function from repeating, simply redefine repeatTask() to do nothing.

1procedure( repeatTask(function) 2 nil 3)

3. Practical example

Let’s implement a wrapper function to schedule a task at a specific time and optionally repeat it daily.

1procedure( sayHello() 2 printf("Hello\n") 3) 4 5 6procedure( scheduleTask(function scheduleTime @key (everyDay nil)) 7 /* 8 Schedules a task to be executed at a specified time, optionally 9 repeating every day. 10 11 @param function string 12 The name of the SKILL function to be executed at the scheduled time. 13 14 @param scheduleTime string 15 The target time in the format "HH:MM:SS" at which the function should 16 be executed. 17 18 @param everyDay boolean 19 An optional parameter indicating whether the task should be scheduled 20 to repeat every day. Defaults to 'nil'. 21 */ 22 let( (secondsLeft scheduleFunction) 23 24 secondsLeft = getSecondsLeft(scheduleTime) 25 scheduleFunction = function 26 when( everyDay 27 sprintf(scheduleFunction "%s scheduleTask(\"%s\")" function function) 28 );when 29 30 hiRegTimer(scheduleFunction secondsLeft*10) 31 );let 32);procedure 33 34 35procedure( getSecondsLeft(otherTime) 36 /* 37 Calculates the number of seconds remaining until a specified time on 38 the current or next day. 39 40 @param otherTime string 41 The target time in the format "HH:MM:SS" for which the remaining 42 seconds are to be calculated. 43 44 @return integer 45 Returns the number of seconds left until the specified time. If the 46 time has already passed today, it calculates the seconds remaining 47 until the same time on the next day. 48 */ 49 let( (monthsTable dateTime day month year otherDateTime secondsLeft 50 maxDaysInMonth) 51 52 monthsTable = getMonthsTable() 53 54 dateTime = timeToTm(stringToTime(getCurrentTime())) 55 day = dateTime~>tm_mday 56 month = monthsTable[dateTime~>tm_mon+1] 57 year = dateTime~>tm_year + 1900 58 sprintf(otherDateTime "%s %d %s %d" month day otherTime year) 59 60 secondsLeft = compareTime(otherDateTime getCurrentTime()) 61 when( secondsLeft <= 0 62 ; Consider the next day 63 maxDaysInMonth = getMonthDaysNumber(month) 64 when( month == "Feb" && mod(year 4) != 0 65 maxDaysInMonth = 28 66 );when 67 68 day += 1 69 when( day > maxDaysInMonth 70 ; Next month 71 day = 1 72 month = monthsTable[dateTime~>tm_mon+2] 73 unless( month ;13th month doesn't exists 74 ; Next year 75 month = monthsTable[1] 76 year += 1 77 );unless 78 );when 79 80 sprintf(otherDateTime "%s %d %s %d" month day otherTime year) 81 82 secondsLeft = compareTime(otherDateTime getCurrentTime()) 83 );when 84 85 secondsLeft 86 );let 87);procedure 88 89 90procedure( getMonthsTable() 91 /* 92 Gets a table mapping month numbers to their corresponding three-letter 93 abbreviations. 94 95 @return table 96 Returns a table where each key is a month number (1 through 12), and 97 each value is the corresponding three-letter abbreviation of the month 98 name. 99 */ 100 let( (monthsTable) 101 102 monthsTable = makeTable('monthsTable nil) 103 monthsTable[1] = "Jan" 104 monthsTable[2] = "Feb" 105 monthsTable[3] = "Mar" 106 monthsTable[4] = "Apr" 107 monthsTable[5] = "May" 108 monthsTable[6] = "Jun" 109 monthsTable[7] = "Jul" 110 monthsTable[8] = "Aug" 111 monthsTable[9] = "Sep" 112 monthsTable[10] = "Oct" 113 monthsTable[11] = "Nov" 114 monthsTable[12] = "Dec" 115 116 monthsTable 117 );let 118);procedure 119 120 121procedure( getMonthDaysNumber(month) 122 /* 123 Returns the number of days in a given month, accounting for leap years 124 in February. 125 126 @param month string 127 The three-letter abbreviation of the month name. 128 129 @return integer 130 Returns the maximum number of days in the specified month. February 131 is assumed to have 29 days to account for leap years. 132 */ 133 let( (maxDays) 134 cond( 135 ( month == "Feb" 136 maxDays = 29 137 ) 138 ( or(month == "Apr" month == "Jun" month == "Sep" month == "Nov") 139 maxDays = 30 140 ) 141 ( or(month == "Jan" month == "Mar" month == "May" month == "Jul" 142 month == "Aug" month == "Oct" month == "Dec") 143 maxDays = 31 144 ) 145 );cond 146 147 148 maxDays 149 150 );let 151);procedure

Here, our function schedules a provided function at a specific time. If the specified time is already passed, it will schedule for the same time on the next day.

Helper functions:

  • getSecondsLeft(): Calculates seconds remaining until a specified time. It does the comparison between current time and the target date (today or tomorrow).
  • getMonthsTable(): Maps month numbers to three-letter abbreviations.
  • getMonthDaysNumber(): Returns the number of days in a given month, accounting for leap years.

To schedule a task once, run:

1scheduleTask("sayHello()" "16:55:00")

To repeat it every day:

1scheduleTask("sayHello()" "16:55:00" ?everyDay t)

4. Understanding SKILL’s tm structure

SKILL’s tm structure requires a bit of clarification:

1dateTime = timeToTm(stringToTime(getCurrentTime()))

The tm structure holds info about the time and date.


tm structure’s parameters and values

tm structure’s parameters and values

However, month and year parameters are not straightforward:

  • Month representation is from 0 to 11 - For example, in case of May, it will show a number of 4. So, in your SKILL code you’ll have to consider that and to add 1 to the month’s number:
1dateTime~>tm_mon + 1
  • Year representation starts from 1900 - For example, in the year of 2025, it will show a number of 125. So, you’ll always need to add 1900 to it:
1dateTime~>tm_year + 1900

5. More tips

  • You should take care not to schedule anything that is too lengthy to run, since this will appear to occasionally freeze the user interface as the scheduled task runs.
  • It’s hard to keep track of which functions are registered to run in intervals. So try not scheduling many.
  • You may check Cadence’s examples of using the hiRegTimer() function. Start with this one: Cadence hiRegTimer() Example

6. Conclusion

By leveraging hiRegTimer(), you can automate routine tasks and optimize your workflow. Explore its capabilities and see how it can enhance your project efficiency.

Author: Eugeny Khanchin