SCOORE Coding Style
From Vlsiwiki
Contents
Coding Rules
- Always use big endian. E.g. reg [n:0] variable
- Try to use active high always (no active low like reset_N)
- Avoid latches
- Code must be synthesizable for FPGA and ASIC. Only testbenches can use behavioral.
- Do not use timing delays
- Do not use wait, fork, joint, and while commands
- Use for command if and only if the loop conditions are constants.
- No initialization assignments. Use reset signal when necessary
Compact begin/end indentation
if (a) begin ... end else begin ... end
- Try to have less than 1000 lines per file
- File name equals module name: Each module has its own file
- Do not use hardcoded numeric values. Use defines or parameters
- Use connection by name when instantiating a submodule. Ex:
pipe fe(.clk(clk), .reset(reset));
- Declare modules following the Verilog-2001 new specification
module idStage ( input clk ,input [0:3] nCommited ,output [0:4] var);
- Use case stmts, avoid ifs stms whenever possible. If no priority is required, make sure that the different cases are mutually exclusive (parallel case) and that all the options are covered (full case).
- All cases covered. Always cover all input patterns, either by specifying them or using a default case. Place assertions on non-possible cases
- Synopsys dc_shell checks:
- No latches: Run “all_registers -level_sensitive” to list latches
- Check design: run “check_design”. It is OK to have warnings if you understand them.
- no threestate: “all_threestate -cells” should have an empty list
- full/parallel: dc_shell should automatically recognize all the case statements as full/parallel. If not, add a comment explaining why. E.g. output from dc_shell
=============================================== | Line | full/ parallel | =============================================== | ??? | auto/auto | ===============================================
Comments
- Do not overuse comments. Never comment “how” is done, comment “why” is done. The code explains the “how”, if it is not clear, re-structure. Code should be clean enough to understand it without comments. There are 3 keywords for comments:
- FIXME is used for functionality not working (should be fix as soon as possible)
- TODO is an improvement not implemented due to lack of time
- WARNING is for very weird behavior in a section of code
FSM Rules
- Avoid tricks with encoding (one-hot, gray...). Let the tool choose. To do so, declare states as parameter:
parameter [2:0] // synopsys enum my_states IDDLE = 3’d0, S1 = 3’d1, ... reg [2:0] /* synopsys enum my_states */ state; reg [2:0] /* synopsys enum my_states */ state_next;
- Remember that always @(posedge clk) are not allowed. Use flop_r as follows:
flop_r #(.Size(3), .Reset_Value(IDDLE) f1 (.clk (clk), .reset (reset), .din (state_next), .q (state));
- Big FSMs (>500LoC) should be implemented as separate module
Creating New Files
- When creating a new file, add the same copyright notice (GPL2). Add a module description, and the file name to the xml file
- Try to have only one module per Verilog file. The module name should match the Verilog file name
- All file names must be lowercase
- Before creating a new file check that the same functionality is not already implemented
Module Input/Output
- All the clocked modules must be a “Synchronous Moore Machine”
- We use flops and pulse triggered latches. To make it transparent, use the “Synchronous Moore Machine” from the flops library
- All the inputs and outputs in the module are wires. The outputs are registered using the flops library
- Flip-flops library available (storage/rtl/flop.v)
- flop: posedge flip-flop without reset
- flop_r: posedge flip-flop with reset. Reset_Value parameter can change the default reset value
- cgflop: posedge flip-flop with clock gating (enable)
- cgflop_r: posedge flip-flop with clock gating (enable) and reset
- Modules without clock signal are assumed to be combinational logic only.
- Port ordering: Declare one port per line. Use the following order:clock,reset, input (enable/busy, control, data), output (enable/busy, control data)
Clock/Reset
- Clock properties:
- flip-flops use the posedge of the clock
- Computer resets on high reset signal. Reset signal will be high for at least 32K full clock cycles. If you need to clear a table, iterate on different clock cycles (reset high)
- Do not use any @(posedge ...) statement. If you need to use flip-flops use the flop library
flop #(.Size($bits(YourType))) f1 (.clk(clk), .din(your_in), .q(your_out));
- Use reset signal if necessary for functionality. Not all the modules have reset signal. RAM-like structures do not have reset signal. External state machine should clear the values if necessary.
- No logic should use clock as input. Clock is only passed to structures in storage library
Blocking/Non-Blocking
- Only use blocking assignments (=)
- Combinational blocks only use blocking assignments (=). Synchronous blocks only use non-blocking assignments (<=). Since we do not have synchronous block. We only use non-blocking assignments on low level libraries like flops & memory_bank
- Use always_comb on the sensitivity list. Do not add list of parameters.
always_comb begin case (sel) // 1'b0: y = a; 1'b1: y = b; default: y = 1'bx; endcase end
- Assign to the same variable in a single always block. Group together in the same always.
Emacs Verilog Mode
- Do not use tabs, write spaces instead of tabs (tab stop is 2). If you use the emacs formating parameters found at the end of this document, this will be done automatically. The reason for not having tabs is that each person has a different setup
- Column width. Do not to go over 80 columns (at least it should be very rare)
- Use the following style for module instantiation (spacing)
mod_name (.clk (clk) ,.reset (reset) ...
- If you use emacs get verilog-mode.el and copy it to
your .emacs.d directory. Then, set this options (.emacs) ("Library/Preferences/Aquamacs Emacs/Preferences.el" for Aquamacs).
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Load verilog mode only when needed (autoload 'verilog-mode "verilog-mode" "Verilog mode" t ) ;; Any files that end in .v should be in verilog mode (setq auto-mode-alist (cons '("\\.v\\'" . verilog-mode) auto-mode-alist)) ;; Any files in verilog mode should have their keywords colorized (add-hook 'verilog-mode-hook '(lambda () (font-lock-mode 1))) (add-hook 'verilog-mode-hook '(lambda () (add-hook 'local-write-file-hooks (lambda() (untabify (point-min) (point-max)))))) (setq verilog-indent-level 2 verilog-indent-level-module 2 verilog-indent-level-declaration 2 verilog-indent-level-behavioral 2 verilog-indent-level-directive 1 verilog-case-indent 2 verilog-auto-newline t verilog-auto-indent-on-newline t verilog-tab-always-indent t verilog-auto-endcomments nil verilog-minimum-comment-distance 40 verilog-indent-begin-after-if t verilog-auto-lineup '(all))
Work Methodology Rules of Thumb
This section describes basic working methodology that you should try to follow:
- Synthesize frequently. Optimize area for FPGA and maintain the ASIC frequency target.
- Use SVN frequently: Update every day, commit frequently
- “svn update” before and after editing a file
- “svn commit” every time that a change compiles
- “svn add <file>” whenever you create a new file
- Do not work more than 8 hours without a commit
- Design peer review: You should explain your design to someone else before starting implementation. The explanation should include all the modules, inputs, outputs.
- Write assertions as you code. Do not add them latter
- After finding a bug, add an assertion to protect against it
- Write testbenches for big components. Ex: IF0, cache
- Refactor whenever you see something ugly