General Comments
The design, verification, and implementation of an FPGA-based digital system
requires you to manage a considerable amount of detail. The computer tools are
not at all forgiving. Apparently minor mistakes can stop you in your tracks. You
need to work in a careful and meticulous manner.
There are infinitely many incorrect methods to implement a design; the number
of correct methods is very small.
Therefore, you should strive to be creative in the paper-and-pencil phase of
your design (creative within the bounds of sound digital design practice, of
course), but do not get creative once you begin writing Verilog descriptions.
The design entry phase should be nothing more than a translation of your
existing design into a usable format for computer simulation and hardware
implementation. The only acceptable place for creativity during Verilog entry is
in how you express the behavior of a particular register-level component such as
a counter. All else must be considered a template!
When you faithfully adhere to the design rules below, you will experience
significantly lower frustration levels, and you will also produce cleaner
designs. On the other hand, if you choose to stray from the standards and invent
your own methods, then plan to spend a great deal more time on your
project than is necessary!
Sequential Circuit Verilog Structure
All sequential circuit ‘always’ blocks must be structured as
follows:
always @ (posedge MasterClock or posedge MasterReset)
if (MasterReset) begin
// Set value of register when
// asynchronous master reset is asserted
...
...
end
else begin
// Set register values for normal operation (responses to
// level-sensitive inputs).
// Helpful to read each assignment line ("<=") as
// "on next clock edge, register ___ gets the value ___."
...
...
end
| Note that signals that you test during the “normal operation” part
specifically do not show up in the sensitivity list. |
| The entire behavior of a device (register, counter, shift register,
etc.) must reside in exactly one 'always' block |
| It is permissible (and even likely) that you will create a circuit
description that tests a control input to determine whether to set an output
to the same value that is used during asynchronous reset. Keep the concepts of
“asynchronous reset” behavior and “synchronous initialization” totally
separate, even if they lead to the same result (the device output goes to
zero, for example). |
| You must not attempt to do anything else for a sequential ‘always’ block
than what is shown above. Common attempts include multiple clocks, multiple
resets, level-sensitive resets with edge-sensitive clocks, clock only, etc. If
you choose to stray from this standard, you likely won’t see any
problems in functional verification, because the simulator is much more
forgiving than the synthesizer. It is much better at the outset to write your
description in a way that is expected by the synthesizer. |
Master Reset
|
The design must have exactly one master reset signal |
|
The master reset signal must asynchronously force all
flip-flops in the design to a known state |
|
The master reset signal must not be used as an input to any
combinational circuit |
|
The master reset signal must not be used as part of the
"normal operation" section of a sequential 'always' block |
Master Clock
|
The design must have exactly one master clock signal |
|
All flip-flop clock inputs must connect only to
the master clock signal |
|
No "gated clocks" are permitted anywhere in the design |
|
The master clock signal must not be used as an input to any
combinational circuit |
|
The master clock signal must not be used as part of the
"normal operation" section of a sequential 'always' block |
Datapath / Controller
|
Controller and all datapath elements must operate on the same
master clock edge |
|
Each datapath element must be described by a single 'always'
block or 'assign' statement |
|
When selective operation of a device is required, then
synchronous enabling signals must be used (i.e., no gated clocks permitted anywhere in design) |
Verilog Identifiers
All Verilog identifiers must be structured as a three-part name of
the form
vT_D
where
v = Verilog type,
T = signal type or category, and
D = descriptive phrase.
Verilog Type (v):
Symbol |
Interpretation |
i |
input port |
o |
output port |
r |
registered (but not an output port) |
w |
wire |
p |
parameter |
Signal Type (T):
Symbol |
Interpretation |
G |
Global system resource such as master clock and
master reset |
C |
Control point; created by system controller, used by
datapath |
S |
Status signal (or condition signal); created by
datapath, used by system controller |
D |
Data or information |
M |
coMmand signal to controller that originates from a
device external to the system |
E |
Externally-controlled device; created by system
controller, and used by device external to the system |
Q |
Associated with state register in the controller |
N |
Numerical constant (used with parameter) |
Descriptive Phrase
The "description" portion of the identifier must be constructed
according to the signal type T as
follows (use uppercase letters to improve readability):
|
C, M, or E - action sentence (verb, noun). Examples or input
and output ports: oC_InitializeTimer,
iC_SetTimerToZero,
iM_BeginProcess |
|
S - statement of fact, or statement of state. Examples:
iS_TimerIsDone, oS_KeyIsUp, oS_TankIsEmpty |
|
D - state the essential information embodied in the device,
instead of simply referring to the device itself. For example, suppose you
have a counter to keep track of elapsed time (the counter is registered, but
is not an output, so use 'r' as the Verilog type). Use
rD_ElapsedTime
as the name of the counter, instead of rD_Counter
or even rD_Timer. Note: it might take you a while to get used to this
naming convention, but it pays big dividends in terms of clarified thinking
about your design! |
|
Q - state the primary activity performed in this state.
Examples: pQ_WaitForKeyPress, pQ_InitializeAllDevices,
pQ_SaveMeasurement |
|