131 lines
4.6 KiB
Markdown
131 lines
4.6 KiB
Markdown
# Style Guide for ROSE (and other FLORA projects)
|
|
Coding style matters a lot. Good coding styles makes the code look
|
|
better to the eye, and can help mitigate some pitfalls and confusions.
|
|
|
|
## Indentation
|
|
For all indentation, use **spaces**, not tabs.
|
|
|
|
The rationale behind this is to avoid different indent width settings
|
|
in different editors. It's a great trade-off of making your source
|
|
file a little bigger for portability to different editors.
|
|
|
|
### C
|
|
Use 8 spaces. This is not only to adhere to the Linux kernel's coding
|
|
style, but also to prevent your indentation levels from getting too
|
|
big.
|
|
|
|
### Verilog/SystemVerilog
|
|
Use 4 spaces. Unlike C, HDL is more on the combinational logic
|
|
side, so we can expect some more `if-else` clauses embedded together.
|
|
|
|
**IMPORTANT: If the indentation is blowing lines off the 80-char
|
|
width, you should probably consider refactoring the logic.**
|
|
|
|
### Python
|
|
Use 4 spaces. This is enough for scripts, and a choice by the people
|
|
behind python.
|
|
|
|
### Shell Scripts
|
|
Use 4 spaces. There might be arguments to make it 2, but 4 is the
|
|
minimum if you want to spot something appearing in an incorrect level
|
|
when you've been staring at the screen for 15 hours.
|
|
|
|
### Line width
|
|
80 characters is preferred, but it can be extended by 20 characters or
|
|
so to accommodate longer identifiers.
|
|
|
|
If it breaches 80 characters, consider breaking it into multiple lines.
|
|
|
|
However, it is important to note that when passing many
|
|
parameters/logic, it should always be broken into logical chunks for
|
|
each line.
|
|
|
|
## Avoid magic numbers
|
|
Unless it's the bit-length of a byte or something that's commonly
|
|
known and obvious at first glance, use a constant to store it.
|
|
|
|
## Arrays
|
|
Avoid using arrays that are more than 2 dimensions. If you need to
|
|
store multiple dimensions of data, consider using `struct` to clarify
|
|
what each dimension stores.
|
|
|
|
## Naming schemes
|
|
Names are only meaningful to humans, and the rationale behind the
|
|
following guidelines is to allow anyone reading the code to know what
|
|
an identifier refers to without scrolling back to its definition or
|
|
other references.
|
|
|
|
### Snake case or camel case?
|
|
Snake case.
|
|
|
|
### Scoping
|
|
For all identifiers, it's important to note the scope of their usage.
|
|
Names are there to avoid confusion, not add to them, and the
|
|
considerations about confusion should fall in the same scope as their
|
|
usage.
|
|
|
|
### Abbreviating
|
|
Using abbreviations is okay and a good idea under the right
|
|
circumstances.
|
|
|
|
As a general rule of thumb, the aggressiveness of abbreviating words
|
|
is inversely proportional to the size of the scope. But it's a **bad
|
|
idea** to abbreviate global identifiers that are not commonly used.
|
|
|
|
### Constants
|
|
For all constants, use **ALL_CAPS**.
|
|
|
|
### Global identifiers
|
|
Use **FULL NAMES** unless it's something pre-agreed on or by
|
|
specifications like `mosi` or `sys_clk`.
|
|
|
|
## Commenting
|
|
Comments are great, but don't over-comment, they are there
|
|
for exactly two things:
|
|
|
|
1. Tell people **what** the code does
|
|
2. Give a signal for future development (e.g. implementation notes,
|
|
usage warnings, required guarantees)
|
|
|
|
If you need to explain how your code does something using comments,
|
|
it's a better idea to re-write the code.
|
|
|
|
### Signals
|
|
Comment signals should always be contained in the same line so that
|
|
you can `grep` for them, the only exception to this is within
|
|
documentation, where you usually search for them.
|
|
|
|
1. `TODO`: something to be done in the future
|
|
2. `NOTE`: keep note of something when using/running the code
|
|
3. `IMPORTANT`: knowing this is crucial to using/running the code
|
|
4. `REQUIRES`: requirements for the code to run properly
|
|
5. `GUARANTEES`: guarantees that the code has this feature when ran
|
|
|
|
## Output Messages
|
|
Like comment signals, messages should also be in complete lines and
|
|
`grep`-friendly.
|
|
|
|
All messages should use capitalized signals denoting what type of
|
|
message it is (e.g. `ERROR`, `WARNING`, `INFO`) and enclosed in square
|
|
brackets ('[' and ']') so they can be easily processed by `sed` or
|
|
`awk`.
|
|
|
|
If there is the need for a timestamp, put the timestamp after the
|
|
signal but within the closing bracket, leave no spaces between the
|
|
signal and the timestamp, and separate the two parts with a colon ':'.
|
|
|
|
## Tricks and workarounds
|
|
Don't try to write "smart" code, instead, write code that everyone can
|
|
understand without too much explanation.
|
|
|
|
## Styles specific to Verilog/SystemVerilog
|
|
|
|
### Always use `logic`
|
|
Unless absolutely necessary, use `logic` or types built on top of
|
|
`logic`. This is to incorporate the idea of ownership into the code.
|
|
|
|
Every bit of data should have only one unique driver.
|
|
|
|
### Avoid inferring latches
|
|
Every bit of data should be verbosely passed to other blocks of code.
|