Get email delivery of the Cadence blog featured here
Many of you out there are SKILL coders (or have these people on your team). SKILL is the extension programming language for all the backend layout products in the Allegro family, including Allegro Package Designer.
If you’ve read up on the blogs in the PCB form like this one and its follow-up, you know everything you need to get started. But, when you start editing the database or performing complex operations that manipulate large numbers of objects, it is important to do so efficiently.
As any good coder knows, though, poorly structured code or the right function called in the wrong context can result in wrong results – or right results with very bad time complexity! Give me a few short minutes of your time to share with you a few APIs that you truly need to be aware of to make the most of your SKILL programs.
Transactions are the name for a set of changes to the database. When you start a transaction, it means that you are starting an action that modifies the database. This transaction, then, can be saved to the database if you want to make it permanent; it can be canceled if you notice there’s a problem and you want to return the database to its previous state. And, above all, transactions can be nested. When you nest transactions, you make a set of changes inside of a larger set of changes.
The main functions in this API include:
axlDBTransactionStart – Starts a new transaction. It returns an index identifier for the transaction.
axlDBTransactionCommit – Saves the transaction contents to the database. Takes an identifier returned from a call to axlDBTransactionStart.
axlDBTransactionRollback – Cancels the transaction contents and removes the changes from the database. Also takes an identifier returned from a call to axlDBTransactionStart.
Why is this API the one I consider the most important? Probably because I make a lot of mistakes (and I assume that my users, however intelligent and well-meaning, make typos and accidental picks in the canvas, too). With a transaction open, I can always give them the opportunity to change their mind, go back a step, and make a different selection. Like a good choose-your-own-adventure book, these give you flexibility and control over what is made permanent in the database.
A good typical flow for transactions looks something like this:
When your command starts (you registered it with axlCmdRegister, right???), start a top-level transaction. You’ll need this to be able to cancel all the changes you made since your command started if the user cancels.
When you start a new individual task inside of your command, begin a new transaction. The best way to manage your transactions is with a list. Whenever you start a new one, cons() it to the front of the list. This way, when you want to rollback an action, it’s always the one at the front!
When an action is complete and finalized, use axlDBTransactionCommit to save it, or get rid of the changes and go back a step with axlDBTransactionRollback. This is always done on the head of your transaction list. And, once the transaction is committed or rolled back, remove it from the list.
When your command is complete, process all the outstanding transactions through a foreach loop from head to tail of the list and either commit (if your user did a done) or rollback (for a cancel) the transactions.
If you want to allow for multiple levels of undo in your flow, you’ll just keep adding to your transaction list in #2 for each new step. That way, you can roll back each step with an axlDBTransactionRollback and return the DB to the previous state.
We know how to save our good choices and get rid of the bad ones. But, if you’re making a lot of changes to the database, then you want to delay certain actions. Allegro is a very powerful tool that maintains many links and automated relationships for you. Whether it’s dynamic shapes, dynamic fillets, on-line DRC, auto silkscreen text, or another background feature, there are many pieces of data the tool will keep current for you to access any time you need to.
That comes at a cost, however. If you are adding a via under each pin of your die component, you don’t need the database to add the dynamic void for each via separately. Instead, you want to add all your vias, make sure they are where you want them, and THEN update the dynamic plane shapes on time to void around them.
Cloaking is what allows you to do this. The axlDBCloak function takes any function call you want to make and the options for what you want it to delay or allow. It will then safely delay the necessary actions while your code is running, turning them back on when complete. The only restriction here is that you cannot ask the user for information while inside of a cloaked action. Because you are delaying strategic database updates, the user might get incomplete information if you did. So, gather the information you need and then use axlDBCloak when making the changes to the database to have them happen as quickly as possible.
The routine takes options for what you want its help with:
shape – delay dynamic shape updates until exiting the cloaking
ignoreFixed – ignore the fixed property on objects (treat things as not being fixed for move/delete)
disableDisplay – do not process updates in the main canvas until finished
Cloaking will always enable a few key options like deferring ratsnest endpoint calculations. The three above are the most commonly used options. You can combine one or more together in a list. A typical call would look like:
axlDBCloak('myDBUpdateFunction(myFunctionArgs) '(shape disableDisplay))
Which will run your myDBUpdateFunction, passing it myFunctionArgs, and will update the shapes and canvas display only once when finished.
If ever you feel like your database updating is taking longer than it should, check for a missing axlDBCloak!
Our third API for today is axlDBControl. This API provides you with access to configure many options in the database. Many things that you will find in Setup - Drawing Parameters or in the main color form can be queried via SKILL code through this function. Some of them can be set, too.
This API is formed of two functions:
axlDBControl – Inquire and set option parameters in the DB like on-line DRC status
axlDBDisplayControl – Inquire and set display options like OpenGL display of net names
Both functions work the same. If you provide just one argument, the name of the control, you can query the value. For those that support change through SKILL, a second argument is a new value to set the control to. The difference is just that simple. Let’s try one out:
axlDBControl('drcEnable) => Returns t or nil to tell you whether online DRC is active
axlDBControl('drcEnable t) => Turns on online DRC. It still returns t or nil to indicate the old value
That’s all there is to it. But, with these APIs you can peek at everything from online DRC and dynamic shape pouring mode to the temp highlight color and whether the grids are displayed.
When it comes to modifying the database, axlDBControl is the function that you want. But, because the display of the database is so central to efficient editing, I wanted to be sure to include the display function as well.
Keep these three main APIs in mind when you’re writing code to update the database and I guarantee you that things will be smoother, faster, and more productive. There are many, many other APIs out there for you to use. Look for them all in your documentation or in the <INSTALL_DIR>/share/pcb/examples/skill/DOC/FUNCS directory. Until next time!