bnrgl.pdf

(49 KB) Pobierz
175182199 UNPDF
Guidelines for Writing VHDL Models in a Team Environment
Janick Bergeron
Bell-Northern Research Ltd
P.O. Box 3511, Station C
Ottawa, Ontario, Canada K1Y 4H7
janick@bnr.ca
Abstract
used as a word separator in user-defined identifi-
ers (see section 2).
When a large VHDL model is being developped
by several individuals, a set of guidelines is nec-
essary to ensure maintainability, consistency and
readability throughout. This paper presents a set
of guidelines covering issues like file naming,
capitalization and code layout, successfully used
within BNR.
Table 1: File Naming Convention
Entity entityName .vhd
Architecture entityName - archName .vhd
Configuration entityName - confName .vhd
Package packageName .vhd
Package Body packageName - body.vhd
Section 1. File System Structure
The structure of the file system hierarchy shall
mirror the logical structure of the system being
modelled. This makes it easier to locate the model
of a particular sub-module of the system. It does
not imply that each component in a structural
description have to be in individual subdirecto-
ries: a structural description of a “logical” struc-
tural component of the overall system should be
in a single directory. Soft-links may be used to
“instantiate” a directory containing a re-used sub-
component into the various directories where it is
used.
A file shall contain one and only one library unit.
This minimizes the amount of recompilation
required when a library unit, on which other
library units depend, is modified. It also helps in
structuring the model in the host computer’s file
system as described in this section.
Each file shall be named according to the unit it
contains as shown in Table 1. This makes identi-
fying the file that contains a particular library unit
easier and, when alphabetically sorted, each enti-
ties are grouped with its corresponding architec-
ture and configuration, and package declarations
are grouped with their corresponding body. Since
certain file systems are case-insensitive, the case
mix of the filename need not follow the case mix
of the various library unit names it is made of. If
the file system imposes a limit on the length of a
filename, a different convention that yields
shorter names should be used (but a convention
nonetheless) in favor of keeping longer, more
meaningful names for the library units. Note that
a dash (-), not an underscore, separates the com-
ponents of the filename since the underscore is
RadarSys/
D S P/
CPU/
Makefile
datapath/
ALU/ Fetch/
RCS/
alu.vhd
VSS.lib/
Figure 1: File System Hierarchy
A directory shall correspond to one and only one
library . This is a requirement of certain toolsets.
It also reduces clutter of library units in a single
library.
175182199.033.png 175182199.034.png 175182199.035.png 175182199.036.png 175182199.001.png 175182199.002.png
User A
Central
User B
RadarSys/
RadarSys/
RadarSys/
D S P/
C P U/
D S P/
CPU/
DSP/
CPU/
datapath/
ALU/ Fetch/
ALU/ Fetch/
datapath/
RCS/
alu.vhd
VSS.lib/
RCS/
alu.vhd
VSS.lib/
soft-link
Figure 2: Private and Central Model Repository
A directory shall have the same name as the top-
most unit it contains. The top-most unit should be
the only unit in the library usable outside of this
library and all others considered private. This
facilitates the identification of the top-level enti-
ties in a “logical” structural model. This guide-
line does not apply when a directory (and library)
contains several shared packages.
soft-links to the missing portions in the central
repository (see figure 2).
Each directory shall contain a makefile. A rule
named “ all ” should compile all units contained in
the directory and invoke make for all subdirecto-
ries. If several toolsets are used, the makefiles
should be named “ Makefile . toolName ” and a
soft-link named “ Makefile ” should point to the
makefile for the tool currently used. BNR has
released in the public domain a tool to automati-
cally create a makefile for various VHDL toolsets
from a set of VHDL source files[1].
The name of a VHDL library shall be
“directoryName _LIB ”. It facilitates the identifi-
cation of the library that contains the units
located in a given directory and vice-versa. It
implies that the various directories in the hierar-
chy containing the model must have unique
names but that is also almost garanteed by the
previous guideline.
all:
for dir in $(SUBDIRS); do \
cd $$dir; \
make all; \
cd ..; \
done
make all
If the VHDL system requires a directory or a file
for its own data or object files, it shall be named
“toolName .lib ”. This allows the use of several
VHDL systems on a single source hierarchy. If
several version of the same tool are used, the ver-
sion number should also be included.
All VHDL source and testcase input files shall be
maintained using a source control system. Sys-
tems like (but not limited to) SCCS or RCS
should be used. BNR has a PERL script which
provides an interface identical to Digital’s CMS
to both systems. The source control system files
should be kept in a subdirectory named “RCS” or
“SCCS” in each directory containing VHDL
source files.
Vantage-3.3.lib
Vantage-4.1.lib
VSS.lib
A complete copy of the entire hierarchy of the
model shall be kept in a shared central location.
This copy is a snapshot of the latest working ver-
sion of the model others can refer to. Develop-
pers copy their portion of the model into this
central repository at appropriate points through-
out the development
Section 2. VHDL Syntax
All VHDL reserved words shall be in lowercase
and all other keywords shall be in uppercase.
User-defined keywords should not depend on
capitalization to be readable or meaningful since
a tool or filter may recapitalize the VHDL source.
It also makes user identifiers stand out from the
VHDL keywords.
Each member of the development team shall have
a copy of only the portion of the hierarchy for
which (s)he is responsible for. Each member cre-
ates a complete picture of the model by having
175182199.003.png 175182199.004.png 175182199.005.png 175182199.006.png 175182199.007.png 175182199.008.png 175182199.009.png 175182199.010.png 175182199.011.png 175182199.012.png 175182199.013.png 175182199.014.png 175182199.015.png 175182199.016.png 175182199.017.png 175182199.018.png 175182199.019.png 175182199.020.png 175182199.021.png 175182199.022.png 175182199.023.png 175182199.024.png 175182199.025.png 175182199.026.png 175182199.027.png 175182199.028.png
entity MEMORY is
port(WHERE: in ADDRESS_TYP;
WHAT: inout DATA_TYP;
WRITE_IT: in BOOLEAN);
end entity MEMORY;
Only literals in base 2, 8, 10 or 16 shall be used.
These bases are the only ones most computer sci-
entists and hardware designers are familiar with.
Extended digits in base-16 literals and base spec-
ifiers shall be in uppercase. This makes for more
consistent and readable literals.
User-defined identifiers shall be meaningful and
have words separated by underscores. Abbrevia-
tions and acronyms should be avoided at all cost
because they reduce readability and maintainabil-
ity. Identifiers should have at least 8 characters.
ADDRESS_BUS := 16#45E7FF0A#;
DATA_VALUE := 0”0377”;
Real literals shall be in decimal only. Non-inte-
ger mantissas and exponents in based literals are
very confusing.
PROGRAM_COUNTER
LEFT_DATA_BUS
User-defined type and subtype identifiers shall
end with “ _TYP ”. Coming up with significant
but different names for signals, variables and type
marks is often difficult and make the type mark
more meaningful.
Allowable replacement characters shall not be
used. They are a provision for limited character
sets and should be avoided at all cost. This sec-
tion of the LRM (13.10) makes for an excellent
“Trivial Pursuit” question amongst collegues.
type DATA_TYP is ...;
subtype ADDRESS_TYP is ...;
User-defined package identifiers shall end with
_PKG ”. This makes it possible to have similar
names for the types and the packages that con-
tains them. It also makes the package name more
meaningful.
Section 3. VHDL Source Layout
Declarative regions and blocks of statements
shall be indented by 4 spaces . A block of state-
ment can be the concurrent statement part of an
architecture, the “else” clause of an if statement,
the body of a subprogram, etc...
package INT_64_BIT_PKG is
type INT_64_BIT_TYP is ...
end package INT_64_BIT_PKG;
process
variable VARIABLE_NAME ...
begin
if CONDITION then
STATEMENT;
STATEMENT;
All predefined attributes shall be in lowercase.
Although they are not reserved words, it facili-
tates differentiating them from user-defined
attributes.
else
if CLOCK’event and CLOCK = ‘1’
STATEMENT;
end if;
end process;
The identifiers in predefined packages shall be
used in uppercase. Since the identifiers in pack-
ages like STD.STANDARD or
STD_1164_STANDARD can be overloaded as
any other user-defined identifier, they should be
capitalized the same way. It also helps identifying
them as separate from the language itself.
Indentation levels in sequential statements shall
not exceed 4 . A large number of indentation lev-
els is often an indication of bad programming
style. Use subprograms to break the code into
manageable parts.
Underscore shall not be used in literals. This lex-
ical convenience mechanism is questionable as
some downstream tool may not accept it and
complicates the automatic translation of VHDL
into other languages that do not support it.
175182199.029.png
begin
if CONDITION then
loop
if CONDITION then
loop
LAST_LEVEL;
end loop;
end if;
end loop;
end if;
formatted. They are also difficult to see unless
they are located close to the right margin.
Multi-line comments shall start and end with with
an empty comment line. It makes the comment
paragraph stand out from the surrounding code.
Single-line comments should be reserved for stra-
tegic comments in hard-to-understand code.
--
-- This is a multi-line
-- comment followed by the
-- code it describes
--
STATEMENT;
end;
Indented regions in sequential statements shall
not have more than 60 lines. This keeps indented
regions from spanning more than two pages when
printed which makes inspecting the code easier
when a complete control region is visible. Long
indented regions are often an indication of bad
programming style. Use subprograms to break
the code into manageable parts.
Comments shall be immediately followed by the
code they describe. One should be able to read a
comment to help understand the code one is
about to read, not the other way around.
The TAB character shall not be used to indent.
Only used the SPC character. A mix of TAB and
spaces may result in improper indentation when
viewed in an environment with different tabstop
settings. The TAB key can still be used to indent
code in EMACS in an appropriate VHDL mode
but should only insert space characters. Use the
UNIX command expand(1) to replace TABs with
spaces.
Each file shall have a descriptive comment of its
content a the top. This can include the name of
the authors and subsequent contributors, copy-
right notices and a description of the content of
the file.
--
-- Interface of RS-232 modem
--
-- Janick Bergeron
-- Bell-Northern Research Ltd
-- janick@bnr.ca
--
-- (c) Copyright
--
Lines shall not exceed 80 characters in length. It
avoids confusing wrap-arounds when viewing the
source on a regular text terminal, standard-sized
window or when printed.
Northern Telecom Ltd.
Long lines shall be broken where there is white
spaces. Breaking a line between adjacent tokens
is confusing.
--
All rights reserved.
--
entity RS_232_MODEM is
...
end RS_232_MODEM;
Line continutations shall be indented to line-up
with the first token at the same nesting level or by
4 spaces. It makes it possible to quickly disting-
ish the continuation of a line from a new state-
ment.
Concurrent statements (and their descriptive
comments) shall be separated by 2 blank lines.
This clearly separates the section of codes which
execute in parallel.
SINK = FUNCTION_NAME(PARAM1,
PARAM2,
PARAM3);
-- Clock generator
CLOCK <= not CLOCK after 5 ns;
variable LONG_NAME =
VERY_LONG_EXPRESSION;
Comments shall be on a line of their own. Trail-
ing comments are cumbersome when the line is
lenghtened or shortened and often need to be re-
-- State Transition
process(CLOCK)
begin
STATE <= NEW_STATE;
end process;
175182199.030.png 175182199.031.png
Groups of logically related statements and decla-
rations shall be separated by 1 blank line. A
group is a sequence of statements or declarations
performing a given task at the same indentation
level as other goups and includes its descriptive
comment. It visually separates sections of codes
that perform different tasks.
STATEMENT;
if CONDITION then
STATEMENT;
else
STATEMENT;
end if;
Each declaration shall start on a new line. It
makes it easier to identify individual ports, gener-
ics, signals and variables, change their order or
modify the type of one of them.
-- Decode the instruction
STATEMENT;
STATEMENT;
-- Execute the instruction
STATEMENT;
signal NAME1: SIGNAL_TYP;
signal NAME2: SIGNAL_TYP;
Choices in a case statement shall be separated by
1 blank line and not be indented.. The sequence
of statements should immediately follow the case
alternative specification and be indented nor-
mally by 4 spaces. This visually separates the
various alternatives to choose from.
Elements in interface declarations shall be verti-
cally aligned . This allows quick identification of
the various kind of interface declaration, their
name, direction and type.
procedure FOO(
signal FORM1: in A_TYP
variable FORM2: inout BIT;
constant FACTOR: in REAL;
RESULT: out BIT);
case EXPRESSION is
when CHOICE1 =>
STATEMENT;
when CHOICE2 =>
STATEMENT;
Elements in named associations than span more
than one line shall be vertically aligned. It makes
identifying the formals and actuals easier.
when others =>
STATEMENT;
end case;
CALL(FRM1 => ACT1, FRM2 => VAL,
FRM3 => PI, RESULT => Z);
Unless otherwise specified, tokens shall be sepa-
rated by 1 space. This aerates the code and makes
it easier to read.
Concurrent statements shall be labeled . It facili-
tates cross-referencing when a statement is
replaced by a component instantatiation in an
alternative architecture and makes for better doc-
umentation.
No space shall preceed a close parenthesis,
comma, colon or semi-colon nor follow an open
parenthesis and no space shall surround a single
quote or dot. Furthermore, an open parenthesis
that encloses function arguments or array indices
should abut its subject array or function name.
This makes the code look more like written natu-
ral language.
-- Clock generator
CLOCK_GENRATOR:
CLOCK <= not CLOCK after 5 ns;
Loop statements shall be labeled. It enables bet-
ter loop control with the next and exit statements.
VAR := FCT(A, B.C) + D’right;
EXPRESSION := A * (B + C);
INFINITE_LOOP: loop
STATEMENT;
end loop INFINITE_LOOP;
Each statement shall start on a new line. More
than one statement on a single line makes the
code difficult to read or scan quickly. This
includes statements within statements.
Next and exit statements shall specify the loop
label they control. It makes for more readable
code in nested loops and will prevent errors if a
portion of the body of the loop containing a next
or exit statement is included in an inner loop
later.
175182199.032.png
Zgłoś jeśli naruszono regulamin