Table of Contents
HDLs (Hardware Description Languages) like SystemVerilog can be difficult to understand. To make SystemVerilog code more readable and maintainable, you are required to follow coding standards. These standards are explained below. Each and every lab will be graded against this coding standard.
Files
- R1: A new .sv file will be created for every SystemVerilog module you create.
- R2: The name of any SystemVerilog file you create must match the name of the module it contains. For example, if you have a SystemVerilog file with a module named
FourFunctions
, the filename will be FourFunctions.sv. - R3: You will create multiple modules in some of the labs. Submit these individually as requested.
File Header
-
R4: When Vivado creates a new .sv file it will place a
`timescale 1ns / 1ps
directive as the top line and then fill in its own comment header block. DO NOT remove the timescale line, but replace the comment header block with:/*************************************************************************** * * Module: <module Name> * * Author: <Your Name> * Class: <Class, Section, Semester> - ECEN 220, Section 1, Winter 2020 * Date: <Date file was created> * * Description: <Provide a brief description of what this SystemVerilog file does> * * ****************************************************************************/
-
R5: Each file should also include the
`default_nettype none
macro directive.
Signals
- Signal types:
- R6: Declare module inputs as
input wire logic
- R7: Declare module outputs as
output logic
- R8: Declare internal signals as
logic
- R9: The keywords
reg
, andvar
are not allowed to be used, andwire
can only be used for inputs as described above.
- R6: Declare module inputs as
- Signal names:
- R10: Use descriptive names (e.g.
clrTimer
instead ofn7
). - R11: Use an
_n
suffix for active low signals (e.g.write_n
).
- R10: Use descriptive names (e.g.
- R12: When signals are declared, they will not use an initializer. For example, this is incorrect:
logic nextState = 0;
. Rather, signals will be declared as inlogic nextState;
. If you want a signal to initialize to some known value, provide a control signal (likeclr
) which will set it to that value.
Comments and Indenting
- R13: Indentation will be used in the code to show its structure.
- R14: Each
always_ff
block and everyalways_comb
block will be preceded by a comment describing its function and how it should operate. - R15: If the name of a signal is expressive enough (e.g.
clrTimer
) then a comment describing may not be needed. Otherwise, all signal declarations will have an associated descriptive comment. Be careful – what is considered “descriptive enough” is subjective. Every semester students lose points because they think thatn5
is descriptive but the TA does not. Err on the side of descriptive names or just always add a comment that tells what each signal is for.
Design Requirements
- R16: The only assignment operator allowed in an
always_ff
block is the <= operator. The only assignment operator allowed inassign
statements andalways_comb blocks
is the = operator. - R17: Every
always_comb
block must begin by assigning default values to all signals being driven in the block. - R18: Every
always_ff
block will include functionality allowing the registers within the block to be set to known values via the assertion of aclr
orload
signal. The exception to this may be something like a shift register which will eventually shift in known data and therefore which does not necessarily require an explicitclr
orload
signal. - R19: Outputs from counters, state machines, etc. will be combinational except in very rare cases.
- R20: Finite state machines will be coded using the style of the textbook including the use of an enumerated type for the state type (with an ERR state), an
always_comb
for the combined IFL/OFL, and analways_ff
for the state register.
Style
- R21: The code for the different sub-modules in a module will be grouped together. For example, the statements associated with the timer circuitry will appear together, followed by the statements associated with the bit counter circuitry, followed by the state machine. Each such section of circuitry will have comments delimiting it.
- R22: Local signal declarations will come just after the module definition and its port declarations.
- In programming (as well as HDL-based design) there are two common ways of naming signals so that their meaning is obvious.
- One way is called camel case and consists of starting the signal name with a lower case letter and then capitalizing subsequent words as in: clearTimer, resetConfigurationRegisters, or launchMissile.
- The second way is to make everything lower case and use underscores to separate the pieces as in: clear_timer, reset_configuration_registers, and launch_missile.
- Choose one of these two styles, be consistent, and use descriptive signal names.
- R23: Similarly, there are common ways of naming modules and constants. Modules will start with a capital letter as in: EventCounter or InitializationRegisters. For constants (sometimes called parameters in SystemVerilog), they will be uppercase as in INITVAL, THRESHOLD, or DATAWIDTH.
Conclusion
Why would any of this be important? This is the way that design is done in industry (except their style rules are much more extensive and may take many pages to describe). In a large design with millions of signals and thousands of modules, this adds uniformity to the design to help make the code more readable, understandable, and maintain-able.