C++ Coding Guidelines for PRET
1 Overview
The PRET simulator's implementation follows the C++ coding guidelines presented in this document. These coding guidelines are derived from Ptolemy II's coding guidelines. However, our guidelines have several additions to and exceptions from the Ptolemy II's coding guidelines. We document these additions and excpetions here.
2 Pre-requisites
Before continuing to read this document, we advise the reader to do the following:
- Download and install Astyle version 1.22 [1].
- Read the Ptolemy II guidelines [2].
2.1 Using Astyle
Astyle is a source code beautifier for C/C++. We require that users format their code using this tool. There are versions available for most platforms. The options we use with Astyle are:
- -style=java: Default Java indentation style.
- -pad=open: Pad operators with spaces.
- -unpad=paren: Remove padded parenthesis.
- -convert-tabs: Convert tabs to spaces.
- -suffix=none: The original file is replaced with the formatted file. The original unformatted file is removed.
An example of running Astyle of a file is:
astyle --mode=c --style=java --suffix=none --pad=oper --unpad=paren \
--convert-tabs test_file.h
2.2 Ptolemy II Coding Style
Most of our guidelines follow the style used in the Ptolemy II project. This document is available at [2]. There are some obvious differences between Java projects and C++ projects such as import versus #include. Those aspects that clearly do not apply to C++ are ignored.
3 Exceptions to Ptolemy II's Coding Guidelines
We document exceptions to the Ptolemy II's coding guidelines in this section.
3.1 Camel Casing
We choose to not use camel casing for class, method, and variable names.
Instead, we separate our words with underscores.
Diligent use of underscores is required.
3.2 Alphabetical Ordering of Private Data Members
We do not enforce alphabetical ordering of private data members.
Instead, we advocate a grouping of private members that make sense to be grouped in that order.
For example, the code listing below shows a snippet of alphabetically ordering the private data members and the listing following that shows how we arrange them.
We group the private data members based on its use. For example, all private data members of the form *_stage represent the different stages in the processor pipeline.
So, these are presented together.
private:
sc_clock* _clock;
cycle_counter* _cyc_cnt;
decode* _decode_stage;
#ifdef _NO_SYSTEMC_
hw_thread_ptr _d_to_ra;
#else
sc_signal< hw_thread_ptr > _d_to_ra;
#endif
except* _except_stage;
execute* _execute_stage;
#ifdef _NO_SYSTEMC_
hw_thread_ptr _ex_to_mem;
#else
sc_signal< hw_thread_ptr > _ex_to_mem;
#endif /* _NO_SYSTEMC_ */
#ifdef _NO_SYSTEMC_
fetch* _fetch_stage;
#else
sc_signal< hw_thread_ptr > _f_to_d;
#endif /* _NO_SYSTEMC_ */
hw_thread_ptr _f_to_d;
memory_controller* _mem_cont;
mem* _mem_stage;
#ifdef _NO_SYSTEMC_
hw_thread_ptr _mem_to_except;
#else
sc_signal< hw_thread_ptr > _mem_to_except;
#endif /* _NO_SYSTEMC_ */
sc_clock* _pll_clock;
#ifdef _NO_SYSTEMC_
hw_thread_ptr _pool_to_f;
#else
sc_signal< hw_thread_ptr > _pool_to_f;
#endif /* _NO_SYSTEMC_ */
#ifdef _NO_SYSTEMC_
hw_thread_ptr _ra_to_ex;
#else
sc_signal< hw_thread_ptr > _ra_to_ex;
#endif /* _NO_SYSTEMC_ */
regacc* _regacc_stage;
hw_thread_controller* _thread_pool;
private:
sc_clock* _clock;
sc_clock* _pll_clock;
cycle_counter* _cyc_cnt;
memory_controller* _mem_cont;
hw_thread_controller* _thread_pool;
fetch* _fetch_stage;
decode* _decode_stage;
regacc* _regacc_stage;
execute* _execute_stage;
mem* _mem_stage;
except* _except_stage;
#ifdef _NO_SYSTEMC_
hw_thread_ptr _pool_to_f, _f_to_d, _d_to_ra, \
_ra_to_ex, _ex_to_mem, _mem_to_except;
#else
sc_signal< hw_thread_ptr > _pool_to_f, _f_to_d, _d_to_ra, \
_ra_to_ex, _ex_to_mem, _mem_to_except;
#endif /* _NO_SYSTEMC_ */
4 Additions to Ptolemy II's Coding Guidelines
These are in addition to the guidelines presented in Ptolemy II's coding guidelines.
4.1 Where to Comment: Declarations or Definitions
Comments go with the class declarations (header files). The format is the same as presented in the Ptolemy II coding guidelines. Implementation comments are inserted in the implementation (cpp files).
4.2 Prevent Multiple Definitions in Header Files
Following the copyright statement, we add preprocessor #ifndef commands to prevent bad effects of including header files more than once. Below is a code snippet of using the preprocessor commands on header file myheader.h.
#ifndef _MYHEADER_H_
#define _MYHEADER_H_
. . . // Code seen by the compiler
#endif /* _MYHEADER_H_ */
Note the naming convention of the preprocessor flag.
4.2.1 Comment #endif
Note that we add a comment /* _MYHEADER_H_ */ at the #endif command for better readability. All #ifdef and #ifndef preprocessor commands must end with an #endif that is commented with the preprocessor flag as shown above.
4.3 Alphabetical Ordering of Files to #include
Most #includes should be listed in alphabetical order. There are exceptions to this. For example, header files that redefine certain classes or types that must precede the declaration of other header files. Other than those, the rest should be listed in alphabetical order.
4.4 Underscore Private Data Members and Methods
We reiterate that private data members must start with an underscore. This holds true for methods that are private.
4.5 Reference and Pointer Declarations
We place the symbols for reference (&) and pointer (*) immediately after its type declaration.
We do not pad these symbols with spaces in this context.
This holds for data member and method declarations.
fetch * _fetch_stage; // Incorrect
fetch* _fetch_stage; // Correct
hw_thread_ptr * get_thread(int thread_num) const; // Incorrect
hw_thread_ptr* get_thread(int thread_num) const; // Correct
core(const string & str); // Incorrect
core(const string& str); // Correct
4.6 Destructor Declaration
Destructors are often needed in C++. The place to declare and document these are just after the constructors.
4.7 Padding Template Parameters
We always pad template parameters with spaces. This holds for both < and > .
sc_signal<hw_thread_ptr> _ra_to_ex; // Incorrect
sc_signal< hw_thread_ptr> _ra_to_ex; // Incorrect
sc_signal<hw_thread_ptr > _ra_to_ex; // Incorrect
sc_signal< hw_thread_ptr > _ra_to_ex; // Correct
References
[1] "Artistic Style: A Free, Fast and Small Automatic Formatter." [Online].
Available: http://astyle.sourceforge.net/astyle.html
[2] "Ptolemy II Coding Guidelines." [Online]. Available:
http://ptolemy.eecs.berkeley.edu/ptolemyII/ptIIlatest/ptII/doc/coding/style.htm