Scheduling Tasks with hiRegTimer()
Contents:
- How to use hiRegTimer()
- Repeating tasks
- Practical example
- Understanding SKILL’s tm structure
- More tips
- 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
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
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