2018-09-28 17:54:21 +02:00
|
|
|
Naming conventions
|
2024-09-15 04:24:02 +02:00
|
|
|
------------------
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
directory - lowercase (directory)
|
|
|
|
|
filename - corresponding class name without prefix (Filename)
|
2024-03-06 05:10:52 +01:00
|
|
|
class - upper camel case (ClassName)
|
2025-09-30 23:08:05 +02:00
|
|
|
member function - lower camel case (memberFunction)
|
2024-03-06 05:10:52 +01:00
|
|
|
member variable - snake case with trailing underscore (member_variable_)
|
2018-09-28 17:54:21 +02:00
|
|
|
Trailing underscore prevents conflict with accessor
|
|
|
|
|
member function name.
|
2024-03-06 05:10:52 +01:00
|
|
|
function - lower camel case (functionName)
|
2024-07-14 02:08:43 +02:00
|
|
|
variable - snake case
|
2018-09-28 17:54:21 +02:00
|
|
|
comments - use capitalized sentences that end with periods
|
|
|
|
|
|
|
|
|
|
C++ code files should use a .cc file extension
|
|
|
|
|
C++ header files should use a .hh file extension
|
|
|
|
|
|
2024-03-06 05:10:52 +01:00
|
|
|
Use pragmas to protect headers from being read more than once instead of
|
|
|
|
|
ifdef/define.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
2024-03-06 05:10:52 +01:00
|
|
|
#pragma once
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
In general it is better to for class variables to use pointers to
|
|
|
|
|
objects of other classes rather than embedding the instance directly.
|
|
|
|
|
This only requires that the class be declared rather than defined,
|
|
|
|
|
many times breaking a dependency on another header file.
|
|
|
|
|
|
|
|
|
|
Header files that define the classes of a sub-directory allow other
|
|
|
|
|
headers to have pointers to the objects without pulling in the details
|
|
|
|
|
of the class definitions. These headers are named "DirectoryClass.hh"
|
|
|
|
|
where Directory is the capitalized name of the sub-directory.
|
|
|
|
|
|
|
|
|
|
Place comments describing public functions and classes in header files
|
|
|
|
|
rather than code files because a consumer is more likely to have
|
|
|
|
|
access to the header and that is the first place they will look.
|
|
|
|
|
|
|
|
|
|
The return type of a function should be on the line before the
|
2024-03-06 05:10:52 +01:00
|
|
|
function name. Arguments should be on separate lines to make it easier
|
|
|
|
|
to remove or add them without having to reformat the lines as they
|
|
|
|
|
change length.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
return_type
|
2024-03-06 05:10:52 +01:00
|
|
|
function(type1 arg1,
|
|
|
|
|
type2 arg2)
|
2018-09-28 17:54:21 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Functions should be less than one screen long. Break long functions
|
2024-03-06 05:10:52 +01:00
|
|
|
up into smaller ones. Lines should be less than 90 characters long.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
2024-03-06 05:10:52 +01:00
|
|
|
Avoid assignments inside `if'-conditions. For example, don't write
|
|
|
|
|
this:
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
if ((foo = (char *) malloc (sizeof *foo)) == 0)
|
|
|
|
|
fatal ("virtual memory exhausted");
|
|
|
|
|
|
|
|
|
|
instead, write this:
|
|
|
|
|
|
|
|
|
|
foo = (char *) malloc (sizeof *foo);
|
2024-07-14 02:08:43 +02:00
|
|
|
if (foo == nullptr)
|
2018-09-28 17:54:21 +02:00
|
|
|
fatal ("virtual memory exhausted");
|
|
|
|
|
|
|
|
|
|
|
2025-01-28 17:23:38 +01:00
|
|
|
Do not use braces around if/for that are one line.
|
|
|
|
|
|
2018-09-28 17:54:21 +02:00
|
|
|
if (pred)
|
2025-01-28 17:23:38 +01:00
|
|
|
bar = 1;
|
|
|
|
|
else
|
|
|
|
|
bar = 3;
|
|
|
|
|
|
|
|
|
|
Use braces around if/for bodies that are more than one line.
|
|
|
|
|
|
|
|
|
|
if (pred) {
|
|
|
|
|
for (int i = 0; i < len; i++) {
|
2018-09-28 17:54:21 +02:00
|
|
|
...
|
|
|
|
|
}
|
2025-01-28 17:23:38 +01:00
|
|
|
}
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
Add a default clause to all switches calling switchCaseNotHandled:
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case edge_interconnect:
|
|
|
|
|
...
|
|
|
|
|
default:
|
|
|
|
|
switchCaseNotHandled();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Put return types for functions on the line before the function name:
|
|
|
|
|
|
|
|
|
|
Cell *
|
|
|
|
|
Library::findCell(char *name)
|
|
|
|
|
{
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Class member functions should be grouped in public, protected and then
|
|
|
|
|
private order.
|
|
|
|
|
|
|
|
|
|
class Frob
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
protected:
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
friend class Frobulator;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-04 17:25:17 +02:00
|
|
|
Class member functions should not be defined inside the class unless they
|
|
|
|
|
are simple accessors that return a member variable.
|
|
|
|
|
|
2024-03-06 05:10:52 +01:00
|
|
|
Avoid using [] to lookup a map value because it creates a key/null value
|
|
|
|
|
pair if the lookup fails. Use map::find or sta::Map::findKey instead.
|
2018-09-28 17:54:21 +02:00
|
|
|
|
|
|
|
|
Avoid nested classes/enums because SWIG has trouble with them.
|
|
|
|
|
|
2025-01-21 03:42:25 +01:00
|
|
|
Avoid all use of global variables as "caches", even if they are thread local.
|
|
|
|
|
OpenSTA goes to great lengths to minimize global state variable that prevent
|
|
|
|
|
multiple instances of the Sta class from coexisting.
|
|
|
|
|
|
2025-10-04 17:25:17 +02:00
|
|
|
Do not use thread_local variables. They are essentially global
|
|
|
|
|
variables so they prevent multiple instances of an Sta object from
|
|
|
|
|
existing concurrently, so they sbould also be avoided. Use stack state
|
|
|
|
|
in each thread instead.
|
|
|
|
|
|
2024-09-15 04:24:02 +02:00
|
|
|
Regression Tests
|
|
|
|
|
................
|
|
|
|
|
|
|
|
|
|
Tests are run with the tcl script test/regression:
|
|
|
|
|
|
|
|
|
|
Usage: regression [-help] [-threads threads] [-valgrind] [-report_stats] tests...
|
|
|
|
|
-threads max|integer - number of threads to use
|
|
|
|
|
-valgrind - run valgrind (linux memory checker)
|
|
|
|
|
-report_stats - report run time and memory
|
|
|
|
|
Wildcarding for test names is supported (enclose in "'s)
|
|
|
|
|
|
|
|
|
|
Tests log files and results are in test/results. The result/test.log
|
|
|
|
|
is compared to test.ok to determine if a test passes.
|
|
|
|
|
|
|
|
|
|
Test scripts are written in tcl and live in the /test directory.
|
2025-10-04 17:25:17 +02:00
|
|
|
Compress large liberty, verilog, and spef, files., Use small or
|
|
|
|
|
existing verilog and liberty files to prevent repository bloat.
|
2024-09-15 04:24:02 +02:00
|
|
|
|
|
|
|
|
The test script should use a one line comment at the beginning of the
|
|
|
|
|
file so head -1 can show what it is for. Use file names to roughly
|
|
|
|
|
group regressions and use numeric suffixes to distinguish them.
|
|
|
|
|
|
|
|
|
|
The script test/save_ok saves a test/results/<test>.log to test/<test>.okfile.
|
2025-10-04 17:25:17 +02:00
|
|
|
|
|
|
|
|
To add a new regression:
|
|
|
|
|
add <test>.tcl to /tcl
|
|
|
|
|
add <test> name to test/regression_vars.tcl
|
|
|
|
|
run <test> with test/regression <test>
|
|
|
|
|
use save_ok <test> to save the log file to >test>.log
|