A Good Verilog Coding Style
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 usage of gated-clocks, as this saves power.
- Prefer clock-generating circuitry in separate 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 a known state.
- Ensure that the coding style does not contain 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 suffixed 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 a 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 meta-stable 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 inferred (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 situations, where 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 statements 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
Labels: ASIC/IC Studybook
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home