|
|
A Good Verilog Coding Style is a prime requirement in every Design, for predictable results, and
reusing the codes for various applications.
- Indent the code so that the code is readable.
- Ensure the code is generic across all technologies and not specified to a single technology.
- Ensure the consistent signal names across the hierarchy.
- Ensure that each RTL file contains file headers as comment comprising of { Name of the RTL, Version
tag, Authors involved and their email-id's , information about the paramets used in the constructs,
last edited, Bug-fixes history, Brief about what the code is performing}.
- Ensure only one verilog statement per line.
- Ensure that speed-critical logics are in seperate module.
- Maximize the usuage of gated-clocks, as this saves power.
- Prefer clock-generating circuitary in seperate module files.
- Ensure one port declaration on one line, followed by comments about the port.
- Preserve port order.
- Declare the internal nets in the design.
- Limitation on the line length{for example:not more than 75}.
- Avoid the usage of 'include construct.
- Ensure that the power-downed signals are in an known state.
- Ensure that the coding style does not contains combinational feedback loops.
- Never assign "x" value to the signals.
- Maximize the usage of parameters instead of text-macros.
- Use parameters for state-encoders.
- Ensure that the design coding does not generate tri-state logic.
- Use the concept of base+ offset for coding address busses.
- Tie the un-used bits to a known value.
- Connect based on port-names while instantiating.
- Ensure that no access of nets and variables outside the module context.
- Avoid using ports of type "inout" in the design.
- Ensure that the latches are transparent during scan-phase.
- Ensure that the PLL bypass is present to verify with out PLL's.
- Minimize top-level glue logic coding style.
- Ensure only one module is defined in a file.
- Ensure that the active low signals are suffix'ed with '_b' and clocks named with domain
names for example clock_a, clock_b, "_z" for high impedance signals, "_o" for output
signals, "_i" for input signals, "_ns" for state-machine next states, "_se"
for scan-enable signals.
- Prefer using case statements, instead of using long if and else statements.
- Ensure that default statement is used in the case statements.
- While designing FSM behaviours , prefer three always blocks(1. register definitions. 2. Defining
next-logic. 3. Defining outputs).
- Ensure that the unused module inputs are driven and not floating.
- Ensure that the design has enough amount of spare-logic to incorporate the last minute design
bug-fixes.
- Ensure that the same test-benches are used for RTL and gate level simulations.
- Ensure that the design does not contain initial blocks and delay elements.
- Ensure that the whole design is resetable to a known state. No internal logic generated asynchronous
resets.
- Ensure the reset is not an late arriving signal w.r.t clocks due to dense reset trees.
- In case if the desired reset is an asynchronous signal, ensure that it is part of the sensitivity list
as according to the verilog if the reset signal is not part of the sensitivity list then it is inferred as
a synchronous reset.
- As in the case of an synchronous reset design, assist the synopsys synthesis tool with the comment
//synopsys sync_set_reset_n "rst_n" , As for the synthesis tool reset is also treated as any
other signal in case of synchronous-resets. In case of synchronous reset designs, in order to maintain the
pulse-width of the signal, a small counter type of circuit is required.
- Extra care is required while designing with synchronous resets and also designs having clock-gating
logic. Poor coding styles can make the design non-resetable as it may be blocking the clocks reaching .
- Ensure that a situation doesn't trigger an asynchronous set and asynchronous resets for the same
flip-flop.
- Ensure that the de-assertion of the asynchronous resets is not close to the clock-edge so that the
flip-flop could be prevented from being entering in to metastable state.
- Ensure that a recovery and removal timing checks are performed for resets to ensure the optimal
behaviour.
- Even though the design is working with asynchronous reset style, Ensure that the resets are
synchronized passing through synchronizers. Ensure that these synchronizer flops are not part of the
scan-chain stitching in the design.
- Ensure that the resets are not used as data or clock signals in the design.
- Ensure that the reset is priority over any other signal in the case of an if-else construct.
- Ensure that the signals which cross the clock-domains are synchronized.
- Ensure that the design does not contain while statements.
- Understanding the signals & functionalities based on the signal names (like For Clock definitions
naming the signal with "clk", naming resets with "res", and to know the whether the
signal is active-high or active low triggerred( For example : resets which are active-low are named with
res_n).
- Ensure that clock-dividers are by-passed during scan stitching.
- Coding style which is generic and re-usuable.
- Avoid using verilog UDP in the design.
- Coding style which will not have simulation and synthesis mis-match results.
- Coding style friendly to Synthesis and not having constructs which synthesis tool cannot understand.
- Coding style which ensures the correct digital logic will be generated after performing synthesis. The
basic digital mismatches could be infering (For example : Latch for a Flip-flop requirement, Priority
Encoder for a Mux Design requirement).
- Coding Style which are DFT(Design for Test) friendly.
Usage of Blocking(=) & Non-blocking(<=) statements and Steps to prevent Race-conditions .
Race conditions are situtations, the order of execution isn't always guaranteed within verilog.
- Use blocking statements for coding combinational logic
- Use non-blocking statements for coding sequential logic
- Never mix blocking and non-blocking in a same procedural block
- Never assign a value to the same variable multiple times in different always blocks. Even though it is
a non-blocking statements the design is prone to race-condition
- To get to know more depth in to the concept Refer the paper:
Be Sensitive about the Sensitivity list
- Synthesis tools assumes to generate combinational logic from an always block, if it does not contain
statemens like "posedge" or "negedge".
- Ensure that a complete list of signals present in the sensitivity list in an always block, thereby the
simulation results for a pre-synthesis versus the post-synthesis match.
- Ensure only one clock per sensitivity list.
Synopsys Full-case and parallel case directives
Synopsys full_case directive :
When the Synthesis tool(Synopsys Design Compiler), comes across with the comment
(//synopsys full_case, before case statements), the tool is guided stating that though all the cases
are not mentioned , these are the possible cases design can honour so the tool for the rest of the
non-listed cases the synthesis tool assumes that the outputs are don't cares.
(synopsys parallel_case, before case statements), the tool is guided stating that it optimizes the
logic, assuming that the case statements would match only one case , prevents the synthesize tool from
optimizing the un-necessary logic.
Various ways of Coding the same logic (for example :Mux)
// first example with continuous assignment
wire z;
assign z = sel ? x : y;
// second example with if and else
reg output;
always @ (x or y or sel)
if (sel)
output = x;
else
output = y;
Unsupported Verilog Language Constructs
Synthesis tool does not support the following Verilog Constructs:
Unsupported definitions and declarations
- Primitive definition
- time declaration
- Ranges and arrays for integer declarations.
- event declarations
- triand, trior, tri1, tri0 and trireg net type
- Ranges and arrays for integers.
Statements not supported by synthesis tool
- defparam statement
- initial statement
- repeat statement
- delay control statement
- event control
- wait statement
- fork statement
- deassign statement
- force statement
- release statement
Unsupported operators
- Case equality and inequality operators (=== and !==)
- Division and modulus operators for variables
Unsupported gate-level constructs
- nmos,cmos, pmos, rnmos, rpmos, rcmos
- pullup, pulldown, tranif0, tranif1, rtran, rtainf0, and rtainf1 gate type signals
Miscellaneous constructs, such as hierarchical names within a module
Unsupported Simulation Directives
- 'accelerate
- 'celldefine
- 'default_nettype
- 'endcelldefine
- 'endprotect
- 'expand_vectornets
- 'noaccelerate
- 'noexpand_vectornets
- 'noremove_netnames
- 'nounconnected_drive
- 'protect
- 'remove_netnames
- 'resetall
- 'timescale
- 'unconnected_drive
|