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:

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:
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