Home

Awesome

SKILL Tools

Tools to ease working with SKILL and SKILL++ in Cadence Virtuoso. The main feature of interest is the unit testing framework in the folder qtest. This repo contains the code that I use regularly in my PhD so it's also available in case anyone finds any use for it. There's not a lot of SKILL code in the wild beyond the Cadence forums.

Project Structure

FolderNamespacePurpose
circuitsqubCircuit analysis
design_environmentqubManipulating the Cadence Virtuoso design environment
geometryqubGeometry calculations
oceanqubProcessing simulation results
pcellqubGenerating custom PCells
qtestqtestUnit testing.
stdqubA "standard library" of useful functions.
inductor_generatorqubInductor PCell generation.

Importing the project

Create the environment variable QUB_CODE_REPO_DIR and point it at the repo root directory. Add the src folder to the SKILL path and run (load (strcat (getShellEnvVar "QUB_CODE_REPO_DIR") "/src/init.ils")) and all other modules will be imported. The src folder can be added to the SKILL path like so: (setSkillPath (append (getSkillPath) (list (strcat (getShellEnvVar "QUB_CODE_REPO_DIR") "/src/")))). If the inductor PCell code is to be used, this code library needs to be re-added using libInit.il for the Virtuoso library that the PCell resides in or else stream-out will fail.

Unit Testing

The unit testing framework is modelled after Python's unittest module and provides a basic set of assertions for testing your code.

Example Test

The test is run by calling load on the file containing the test.

(qtest::runSuites
  (qtest::TestSuite ((f qub:::join_lists))
    (qtest::TestCase join_three_lists
      (qtest::assertEqual (list "X" 2 3 4 5 6)
                           (f (list (list 1 2) (list 3 4) (list 5 6))))))
  (qtest::TestSuite ((f qub::flatten_list))
    (qtest::TestCase normal_use
      (qtest::assertEqual (list 1 2 3 4 5 6 7)
                           (f (list 1 2 (list 3 (list 4 (list 5 6) 7))))))))
(load "./code/src/std/test_lists.ils")
1 of 2 tests passed (1 failures) (0 skipped) (0 expected failures)
Test: join_three_lists
Result: Fail
 Message: No msg.
 Inputs: (list("X" 2 3 4 5 6) (f list(list(1 2) list(3 4) list(5 6))))
 Evaluated Inputs: (("X" 2 3 4 5 6) (1 2 3 4 5 6))

Main Functions and Macros

qtest::runAllTests

Parameter(s)Side Effect(s)
Directory (string)Calls load on all files prefixed with test_ in the directory

Takes a folder path and loads all modules prefixed with test_.

qtest::TestCase

Parameters(s)Keyword ParametersOutput(s)
Test Name (unquoted symbol)skip (bool)List of the test name symbol and the function object
bodyexpect_fail (bool)

Represents a single test. Can contain any code but must return the result of an assertion function. The test name is contained in a list with the function object so tests don't pollute the top level namespace.

Skipping a test

To mark a test to be skipped, set the skip keyword argument to true.

Marking a test that you expect to fail

Set the expect_fail keyword argument to true. If the test passes it will count as a pass but if it fail it will not be recorded as a fail.

qtest::TestSuite

Parameter(s)Output(s)
Test CasesList containing lists returned by qtest::TestCase

A collection of test cases. A suite should be used to test a single function or method.

qtest::runSuites

Parameter(s)Side Effect(s)
Any number of Test SuitesPrints the results of the tests

Test suites should be written in the body of this macro. When the module file is loaded in Virtuoso, the tests are initialised and the results are printed in the CIW.

Assertions

Each assertion takes a keyword argument msg which is printed if the test fails.

qtest::assertEqual

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

Checks if two objects are equal. Uses the qub::equal method to allow you to implement equality for your own objects as well as numbers, strings etc.

qtest::assertNotEqual

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

Checks if two objects are not equal. Uses the qub::notEqual method to allow you to implement equality for your own objects as well as numbers, strings etc.

qtest::assertTrue

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result

Checks that the argument is true.

qtest::assertNil

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result

Checks that the argument is nil.

qtest::assertEq

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

Both arguments are the same object.

qtest::assertNotEq

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

The arguments are different objects.

qtest::assertMember

Parameter(s)Keyword ParametersOutput(s)
valuemsg (string)qtest::Result
list

The object is a member of the list.

qtest::assertNotMember

Parameter(s)Keyword ParametersOutput(s)
valuemsg (string)qtest::Result
list

The object is not a member of the list.

qtest::assertIsInstance

Parameter(s)Keyword ParametersOutput(s)
Objectmsg (string)qtest::Result
Quoted Class

The object is an instance of the class.

qtest::assertNotIsInstance

Parameter(s)Keyword ParametersOutput(s)
Objectmsg (string)qtest::Result
Quoted Class

The object is not an instance of the class.

qtest::assertRaises

Parameter(s)Keyword ParametersOutput(s)
Function Callmsg (string)qtest::Result

Checks that the expression raises an error using error. It may not catch other errors within the expression.

qtest::assertAlmostEqual

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

Checks that two floats are almost equal. Uses qub::almostEqual which is a port of Python's math.isclose and uses the same optional arguments.

qtest::assertNotAlmostEqual

Parameter(s)Keyword ParametersOutput(s)
amsg (string)qtest::Result
b

Checks that two floats are not almost equal.

Standard Library Functions and Macros

qub::checkType

ParametersSide Effects
ObjectThrows an error if the object is of the expected type.
Quoted Class Name

For implementing run-time type checking in functions.

qub::equal

ParametersResult
aBool
b

A generic function for implementing equality for your own types.

qub::nequal

ParametersResult
aBool
b

A generic function for implementing inequality for your own types.

qub::allEqual

ParametersResult
@rest valuesbool

Checks if all values are equal. It uses qub::equal for checking equality.

qub::listFileRec

ParameterResult
Path (string)List of files in the directory

Recursively searches the path for all files. It ignores all dotted directories.

qub::foldl

ParamaterResult
fn(accumulator value)The "folded" value
Initial Value
List of Values

The HaskellWiki can probably explain this better than I could.

qub::foldr

The same as qub::foldl but it calls reverse on the list before it processes it.

qub::sum

Sums a list of numbers

qub:::lcmp

An implementation of python's list comprehensions. The predicate is optional.

>>>(qub:::lcmp (times x 2) for x in (list 1 2 3 4) if (evenp x))
(4 8)

qub::joinLists

ParamaterResult
List of listsA single list of the values within the input lists

qub::range

Keyword parametersResult
startList of integers
stop
step

A port of python's range function.

>>>(qub::range ?start 0 ?stop 20 ?step 3)
(0 3 6 9 12
    15 18
)

qub::almostEqual

ParametersKeyword ParametersResult
arel_tolBool
babs_tol

Checks that two values are almost equal. This is a generic function and can be applied to your own types. The method specialised on numbers is a port of Python's math.isclose and uses the same optional arguments.

rel_tol is the relative tolerance. 0.05 would be a 5% relative tolerance. abs_tol is the absolute tolerance.

qub::startsWith

ParametersResult
stringBool
prefix (string)

Checks if a string begins with a particular prefix