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