|
All right strictly reserved. Reproduction or issue to third parties, in any form whatsoever, is not permitted without written authority from the proprietors. |
VHDL Style Guide |
||||
Project Name/Projektname |
Page/Seite |
|||||
|
|
|||||
Prepared / Erstellt |
Subject Responsible / Verantwortlich |
Date/Datum |
Rev. |
File/Datei OpenOffice.org Writer |
||
Mario Fohler |
Peter Thorwartl |
|
1.0 |
|
VHDL STYLE GUIDE
Table of Contents
2. Elements of Entity/Architecture 10
2.1 Generics 10
2.2 Ports 10
2.3 Process 10
2.5 Case 11
2.6 Loops 12
2.7 Function and Procedures 12
2.8 Components and Component Instantation 12
2.9 Simulation and test benches 13
2.10 Types 14
4. Header 17
5. General Coding Rules for Digital Designs 18
5.1 Reset 18
5.2 Clocks 18
5.3 Buses 20
5.4 Finite State Machine FSM 20
5.5 Memories 22
6.1 Library 23
6.4 UPLD User Programmable Logic Devices 24
7. SVN 26
7.1 Rules 26
8. Scripting 27
An object is a named item that has a value of a given type that belongs to a class.
A class is relevant to the nature of the object and represent how the object is used in the model.
An object whose value may not be changed.
Use constants to define data parameters and table lookups.
Constant shall be used to represent limits and parameters.
Constant Name: constant_name_c
Example: (sine_rtl)
...
architecture rtl of sine is
constant sin_ampl_c : vector_t_arr := init_sin_f(depth_g, width_g); -- returns sine amplitude value
signal ampl_cnt_s : integer range 0 to 255 := 0; -- amplitude counter
signal sine_s : std_logic_vector(width_g-1 downto 0) := (others=>'0'); -- sine
begin
...
An object with a past history.
Use signals as channels of communication between concurrent statements (e.g. components, processes).
Keep the same signal name through different hierarchies. So tracing after signals will be easier.
Use a prefixes to name the source of this signal, maybe a underscore and the destination of this signal.
Use a suffix to describe the function of the signal reset, trigger, en,...
Signal Name: signal_name_s
Example: see Constants (1.2.1)
An object with a single current value.
Variables shall be used in preference to signals. Signals carry more overheads than variables do. Unless something needs to be seen in another process, use a variable.
In non-synthesizeable models, avoid using signals to describe storage element. Use variables instead (Signals occupy about two orders more storage than variables during simulation)
In combinatorial processes read variables then write to them. If variables are written then read, long combinatorial logic and latches will be generated. This come from the fact that variables get their value immediately and not like signals after the process suspends.
Variable Name: variable_name_v
Example: (modulator_tb)
...
write_p : process -- write 64 following sin-amplitude values in sin.txt at the work directory (only simulate)
file out_sin_f : text open write_mode is "sin.txt"; -- create file in write mode in work directory
variable out_sin_line_v : line; -- line variable
begin
wait until rising_edge(clk_in_s);
if wr_end_s = '0' and freq_trig_s = '1' then
if wr_count_s = 64 then -- write 64 amplitude values
wr_end_s <= '1'; -- write end/end of file
else
write(out_sin_line_v, dac_amplvalue_s); -- write dac_amplvalue_s value in out_sin_line_v
writeline(out_sin_f, out_sin_line_v); -- write out_sin_line_v in one line of out_sin_f
wr_count_s <= wr_count_s+1; -- increment write counter
end if;
end if;
end process;
...
An object used to represent file in the host environment
For portability reasons the only allowed file type is std.textio.text.
Don’t use absolute path names.
File Handle Name: file_name_f
Example: see Variable (1.2.3)
Use a package for type definitions, if you use it more then once
The type of an object represents its structure, composotion and storage requirement (integer, real, std_logic, …) that an object can hold
Type Name: type_name_t_arr --array
_rec --record
_range --range
_enum --enumeration
Example: (modulator_pkg)
package modulator_pkg is
type vector_t_arr is array (natural range <>) of integer;
function init_sin_f
(
constant depth_c : in integer;
constant width_c : in integer
)
return vector_t_arr;
end;
package body modulator_pkg is
function init_sin_f
(
depth_c : in integer;
width_c : in integer
)
return vector_t_arr is
variable init_arr_v : vector_t_arr(0 to (2 ** depth_c));
begin
for i in 0 to ((2 ** depth_c) / 2) loop -- calculate positive amplitude values
init_arr_v(i) := integer(round(sin((math_2_pi / real(2 ** depth_c))*
real(i)) * real(2 ** (width_c - 1)))) + integer(2 ** (width_c - 1) - 1);
end loop;
for i in ((2 ** depth_c) / 2 + 1) to (2 ** depth_c) loop -- calculate negativ amplitude values
init_arr_v(i) := integer(round(sin((math_2_pi / real(2 ** depth_c))*
real(i)) * real(2 ** (width_c - 1)))) - integer(2 ** (width_c - 1));
end loop;
return init_arr_v;
end;
end;
VHDL contains five design units constructs that can be independently analyzed and stored in a design library.
Each file shall be named according to the unit it contains.
A file shall contain only one design unit. This minimizes the amount of recompilation required when a library unit, on which other library depends, is modified.
A library is a collection of compiled design units.
Example: (modulator_tb)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_unsigned.all;
library modelsim_lib;
use modelsim_lib.util.all;
library std;
use std.textio.all;
Represent the interface I/O definition and generics.
Make use of generics for buffer sizes, bus width and all other unit parameters. This provides more readability and reusability of the code.
Filename: entity_name.vhd
Example: (dac_ltc2624_rtl.vhd)
entity dac_ltc2624 is
generic(
depth_g : integer range 1 to 99 := 8; -- sine signal 8bit quantized
width_g : integer range 1 to 99 := 12 -- 12 bit sine amplitude value
);
port(
btn_reset : in std_logic; -- reset button
clk_in : in std_logic; -- 50MHz clock
clkdv_in : in std_logic; -- 25MHz clock
dac_clk : out std_logic; -- dac clock
dac_cs_n : out std_logic; -- dac enable
dac_data : out std_logic; -- dac data
dac_reset_n : out std_logic; -- dac reset
freq_trig : in std_logic -- frequency for dac data packages
sine : in std_logic_vector(width_g-1 downto 0) -- frequented sine amplitude
);
end;
Architecture defines how the system behaves. This description can be in different levels of abstraction or different purpose.
Together the entity/architecture pair represents a component.
Behavioural beh
Structural structure
Register Transfer Level rtl
Functional fun
Transaction Level Modeling tlm
Testbench tb
Use the company name if it is specific for a company like altera_rtl, xilinx_rtl, lattice_rtl
Use the family name if it is family specific like xc2vp_rtl,xc9500_rtl
Filename: entity_name_architecture_name.vhd
Example: (modulator_rtl.vhd)
architecture rtl of modulator is
...
begin
...
end;
Provide a collection of declarations (types, constant, signals, component) or subprograms (procedures, functions).
The subprogram bodies are not described.
Where possible, packages approved by the IEEE should be used rather than redeveloping similar functionality.
Packages specific to a particular CAD tool standard should not be used.
The number of packages used by a model shall not be excessive.
Filename: package_name_pkg.vhd
Example: see Types and Subtypes (1.3)
Provide a complete definition of the subprograms.
Filename: package_name_body.vhd
Example: see Types and Subtypes (1.3)
Binds a particular architecture to an entity or binds an entity/architecture pair to a component.
Try to use configuration to map entities and architectures and components in a single file.
Filename: config_name_cfg.vhd
Generics provide a channel for static information to be communicated to an entity from the environment.
Unlike constants, the value can supply externally, either in a component instantiation or in a configuration specification.
Avoid using hard-coded numbers for characteristics that may change throughout the lifetime of the model.
Name: generic_name_g
Example: see Entity (1.4.2)
Ports describe the directions of the interface.
Use std_logic or std_logic_vector for external port types.
Do not use ports with type buffer to read output within the code. Instead use out type and add another variable or signal and assign to it the same output value.
Do not use suffixes.
Name: port_name
Example: see Entity (1.4.2)
Process enables the designer to write sequential statements like other programming languages.
There are two types of processes, clocked and combinatorial.
Include all input signals to its sensitivity list. All right hand side signals of an assignment or condition.
Processes shall be associated with a descriptive label.
Clocked processes should define a reset signal.
Name: process_name_p
Example: see Variable (1.2.3)
Avoid using more than three levels of if.
Avoid using long if-then-else statements and use a case statement. This is to prevent inferring of large priority encoder.
Example: see Variable (1.2.3)
Choice in a case statement shall be separated by one blank line and intended
Do not use ()
Example: (freq_ce_rtl)
freq_ce_p : process -- create and select frequency
begin
wait until rising_edge(clk_in);
freq_cnt_s <= freq_cnt_s + 1; -- increment
freq_trig <= '0';
case sw0_freq_sel is -- select sine frequency
when '0' => -- frequency for sw0_freq_sel = '0'
if (sw0_freq_sel_jmp = '1') then
freq_cnt_s <= (others => '0'); -- reset
sw0_freq_sel_jmp <= '0';
end if;
if (freq_cnt_s = freqlow_g - 1) then
freq_trig <= '1';
freq_cnt_s <= (others => '0'); -- reset
end if;
when '1' => -- frequency for sw0_freq_sel = '1'
if (sw0_freq_sel_jmp = '0') then
freq_cnt_s <= (others => '0'); -- reset
sw0_freq_sel_jmp <= '1';
end if;
if (freq_cnt_s = freqhigh_g - 1 ) then
freq_trig <= '1';
freq_cnt_s <= (others => '0'); -- reset
end if;
when others => null;
end case;
end process;
Loop statement shall be labelled.
Next and exit statement shall specify the loop label the control.
Avoid using discrete range, use predefined object attributes
Name: loop_name_l
Example: see Types and Subtypes (1.3)
Function and procedures are used to describe a set of operations or logic that is going to be repeated in many places in the code.
A function is a routine that returns a value. The function defines how the return value is computed based on the values of the formal parameter
A procedure is a subroutine that performs operations using all the visible parameters and objects, and can modify one or more of the visible parameters.
Whenever possible, use constrained arrays, instead of constrained arrays.
Named association shall be used preferably to positional association.
Name: function_name_f
Name: procedure_name_p
Example: see Types and Subtypes (1.3)
A component represents an entity/architecture pair.
Instantiations of components in architectures is a method to define hierarchy because architectures of components can have within them other components.
Components should be labelled.
Named association shall be used preferably to positional association.
Name: component_name
Use the no additional component declaration for a bottom up approach.
Example: (modulator_rtl)
dut_c: entity work.counter(rtl)
port map(
);
Do not assign value of unknowns ‘X’ or check for don’t care ‘-‘. Such values can produce unexpected behaviour in both simulation and syntheses.
Do not use default values or initialisation for signals and variables. Such assignment can cause mismatch between synthesis and simulation.
The verification shall solely be performed using the VHDL test benches; no simulator specific featured or commands shall be used.
Test benches should be self-checking, reporting success or failure for each subtest.
Name: entity_name_tb.vhd
Example: (modulator_tb)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity counter_tb is
generic(
clkcnt_value_g : std_logic_vector := b"100" -- threshold value for counter
);
end;
architecture tb of counter_tb is
constant per_c : time := 20 ns; -- clock period
signal clk_in_s : std_logic := '1'; -- clk (50MHz)
signal clk_out_s : std_logic := '0'; -- divided clk
signal clkcnt_out_s : std_logic_vector (clkcnt_value_g'length - 1 downto 0) := (others => '0'); -- clk counter
signal cnt_en_s : std_logic := '1'; -- clk counter enable
begin
counter : entity work.counter(rtl) -- fetch generic and ports of counter_rtl.vhd
generic map(
clkcnt_value_g => clkcnt_value_g
)
port map (
clk_in => clk_in_s,
clk_out => clk_out_s,
clkcnt_out => clkcnt_out_s,
cnt_en => cnt_en_s
);
clk_in_s <= not (clk_in_s) after per_c/2; -- generate 50MHz clock
cnt_en_s <= '0' after 300 ns; -- set clk counter enable to zero after 300us
end;
Use std_logic_arith, std_logic_unsigned/std_logic_signed packages. This provides the essential conversion functions:
conv_integer(<signal_name>):
converts std_logic_vector, unsigned, and signed data types into an integer data type.
conv_unsigned(<signal_name>, <size>):
converts a std_logic_vector, integer, unsigned (change size), or signed data types into an unsigned data type.
conv_signed(<signal_name>, <size>):
converts a std_logic_vector, integer, signed (change size), or unsigned data types into a signed data type.
conv_std_logic_vector(<signal_name>, <size>):
converts an integer, signed, or unsigned data type into a std_logic_vector data type.
ext(<signal_name>, <size>): zero extends a std_logic_vector to size <size>.
sxt(<signal_name>, <size>): sign extends a std_logic_vector to size <size>.
All conversion functions can take for the <signal_name> data-type a std_logic_vector, unsigned, signed, std_ulogic_vector, or integer. <size> is specified as an integer value.
Denotation:
Do not mix between VHDL coding standards for the whole project.
Use VHDL-93.
Everything (all VHDL keywords and all user-defined identifier) shall be in lower case.
All user-defined identifiers shall be meaningful and have words separated by underscores, based on the English language.
The same identifier name as for the actual hardware and as in the data sheet.
For signals and variables that are active low, this shall clearly indicated by their by suffixing n as in “reset_n”.
Named association shall be used preferably to positional association.
For objects that are global, this shall clearly indicate by their suffix “_gc”
Underscores should be used in literals.
Only literals in base 2, 8, 10, 16 shall be used.
Extended digits in base-16 literals should be in lowercase.
Variable width ports shall be constrained using generics.
Positioning:
Declarative regions and blocks shall be indented by four spaces.
Indentation level in sequential statements shall not exceed 4.
Indented regions in sequential statements shall not have more than 60 lines.
The TAB character shall not be used to indent, only use the space character.
Lines should not exceed 120 characters.
Long Lines shall be broken where there are white spaces.
Line continuations shall be indented to line-up with the first token at the same nesting level or by four spaces.
One lines shall separate concurrent statements and their descriptive comment.
Groups of logically related statements and declaration shall be separated by one blank line.
Unless otherwise specified, tokens shall be separated by one space.
No space shall precede a close parenthesis or semi-colon.
No space should surround a single quote or dot.
Each statement shall start on a new line.
Each declaration shall start on a new line.
Elements in interface declarations shall be vertical aligned.
Elements in signal, constant declarations shall be vertical aligned.
Elements in a named association than span more than one line should be vertical aligned.
Buffer and Linkage ports shall not be used.
Guarded blocks and guarded signals should not be used.
Operators shall not be overloaded lightly.
Attributes ‘range and ‘reverse_range shall be used when scanning arrays.
Enumerates shall be used to represent non-arithmetic discrete values.
Use too many parentheses, never let the tool resolve precedence; explicitly declare precedence via parenthesis.
Use relativ path.
Include only libraries which are really use in the design!
For interfacing other modules use only std_logic and std_logic_vector as type.
For arithmetic operations use library ieee.std_logic_signed_bit.all and ieee.std_logi0.06"c_signed.all
Use preferred libraries ieee.std_logic_1164.all, std.text.all and std.logic_textio.all
Comments:
Comments shall be immediately followed by the code they describe.
Comments for port and signal declarations shall be in the same line.
Each file should have descriptive comment of the content at the top.
--------------------------------------------------------------------------------
-- File : modulator_rtl.vhd
-- Project : modulator
-- Creation : 15.07.2008
-- Limitations : none
-- Errors : none known
-- Simulator : Modelsim SE 6.2a
-- Synthesizer : ISE 10.1
-- Platform : Windows XP
-- Targets : Simulation, Synthese, Implementation
---------------------------------------
-- Naming conv. : so_vhdl_guide.doc
---------------------------------------
-- Authors : Peter Thorwartl (thor)
-- Organization : so-logic
-- Email : thor@so-logic.co.at
-- Address : Lustkandlg. 52/22, A-1090 Vienna Austria/Europe/Earth
--------------------------------------------------------------------------------
-- Copyright Notice
-- Copying of this document and giving it to others and the
-- communication of the contents thereof is forbidden without authority.
-- Offenders are liable to payment of damages. All rights are reserved in
-- event of the grant or patent of the utility model or design.
--------------------------------------------------------------------------------
-- Function description
-- frequency modulator with output for dac
--------------------------------------------------------------------------------
-- $HeadURL:$
-- $Date:$
-- $Author:$
-- $Revision:$
--------------------------------------------------------------------------------
Do not assign an asynchronous reset to sequential statements.
For simulation use default value assignment at signal declaration.
Use only synchronous design techniques.
Example: (modulator_rtl)
entity modulator is
generic(
...
);
port(
clk_in : in std_logic; -- clk 50 MHz
...
);
end;
architecture rtl of modulator is
...
begin
dcm2sim_activation: if (sim_g) generate -- dcm activation
...
end generate;
dcm2sim_deactivation: if not(sim_g) generate -- dcm deactivation
clkdv_p: process
begin
wait until rising_edge(clk_in);
clk_in_s <= not(clk_in_s); -- clk_in divided by 2
end process;
clkdv_s <= clk_in_s;
end generate;
counterled : entity work.counter(rtl) -- generate ~0,5Hz frequency for led
generic map(
clkcnt_value_g => x"2faf07f" -- clk counter threshold value
)
port map (
clk_in => clk_in,
...
);
freq_ce : entity work.freq_ce(rtl) -- generate frequency trigger
generic map(
...
)
port map(
clk_in => clk_in,
...
);
counterampl : entity work.counter(rtl) -- generate amplitude values
generic map(
clkcnt_value_g => x"00000ff" -- clk counter threshold value
)
port map (
clk_in => clk_in,
...
);
sine : entity work.sine(rtl) –- generates digital sine
generic map(
...
)
port map(
...
clk_in => clk_in,
...
);
dac_ltc2624: entity work.dac_ltc2624(rtl) -- fetch freq-trigger and ampl-values and generate dac output signals
generic map(
...
)
....port map(
...
clk_in => clk_in,
...
);
...
end;
Do not use gated clocks.
No internal clk-generation in moduls
Avoid using latches.
Do not use buffer as delay elements.
All blocks external IOs should be registered.
Avoid using both clock edges.
Clock signal must be connected to global dedicated routing resources.
Do not use clocks or reset as data or as enable.
Do not use data as clock or a reset.
Signals that cross-different clock domains should be sampled before and after crossing domains (double sampling is preferred to minimize meta-stability).
Use the lowest possible clock speed in each clock domain.
Use the minimum number of clock domains
Use clock enables
Example: (counter_rtl)
entity counter is
generic(
...
);
port(
...
cnt_en : in std_logic -- clk counter enable
);
end;
architecture rtl of counter is
...
begin
counter_p: process
begin
wait until rising_edge(clk_in);
if (cnt_en = '1') then
...
else
...
end if;
end process;
...
end;
Clock enables can only be inferred in a clocked process.
Clock enables can be inferred explicitly by testing an enable signal. If the enable is true, the signal is updated. If enable is false, that signal will hold its current value.
Clock enables can be implicitly inferred two ways:
Not assigning to a signal in every branch of an if-then-else statement or case statement. Remember that latches will be inferred for this condition in a combinatorial process
Not defining all possible states or branches of an if-then-else or case statement.
Use
Digital Clock Manager like DCMs, DLLs, …
Start buses at the LSB.
Use MSB to LSB for data buses.
Use LSB to MSB for delay lines and shift registers.
Start counting with one
Avoid using internal tri-state signals, they no longer exist on FPGAs. The will be modelled with two buses, one for reading and one for writing.
Generally, use three process statements for a state machine: one process for next-state decoding, one for output decoding, and one for the registering of state bits and outputs.
Use a Mealy look-ahead state machine with registered outputs whenever possible, or use a Moore state machine with next-state output decoding and registered outputs to incur the minimum amount of latency.
Use enumeration types for the states
Use one hot encoding for FPGAs
Use binary, gray, sequential coding for CPLDs
Example: (statemachine_rtl)
entity statemachine is
port(
clk_in : in std_logic; -- 50MHz clock
dac_clk_low : out std_logic; -- set dac clk to zero
shreg_en : out std_logic; -- shiftregister enable
statem_en : in std_logic -- statemachine enable
);
end;
architecture rtl of statemachine is
type state_type_t_enum is (shreg_end,shreg_start,clk_pause); -- three states of state machine
signal dac_clk_low_s : std_logic := '0'; -- set dac clk low
signal shreg_en_s : std_logic := '0'; -- set shiftreg enable low
signal statem_loop_s : integer range 0 to 49 := 0; -- state loop
signal statem_s : state_type_t_enum; -- enumerated state machine
begin
statem_statereg_p : process -- shift states
begin
wait until rising_edge(clk_in);
if ((statem_en = '1') or (dac_clk_low_s = '1')) then
case statem_s is
when shreg_end =>
statem_s <= shreg_start;
when shreg_start =>
if (statem_loop_s = 48) then
statem_s <= clk_pause;
statem_loop_s <= 0;
else
statem_loop_s <= statem_loop_s + 1;
end if;
when clk_pause =>
if (statem_loop_s = 1) then
statem_s <= shreg_end;
statem_loop_s <= 0;
else
statem_loop_s <= statem_loop_s + 1;
end if;
when others => null;
end case;
end if;
end process;
statem_stateoutput_p : process(statem_s) -- define output to state
begin
case statem_s is -- generate shiftregister enable and clk output low signal
when shreg_start =>
shreg_en_s <= '1'; -- start shift register
dac_clk_low_s <= '0';
when clk_pause =>
shreg_en_s <= '0'; -- end shift register
dac_clk_low_s <= '1'; -- set dac clk low
when shreg_end =>
shreg_en_s <= '0';
dac_clk_low_s <= '0';
when others => null;
end case;
end process;
shreg_en <= shreg_en_s;
dac_clk_low <= dac_clk_low_s;
end;
Use synchronous single-port or dual-port block memories for sync read and write.
Use asynchronous distributed RAMs for sync write and asynchronous read.
Example: for a ROM
-- 8x32 lut-matrix
type lut8x32_t_arr is array (0 to 31) of std_logic_vector(7 downto 0);
-- 8bit amplitude values of 32bit quantized sin
constant wave_c : lut8x32_t_arr := (
0 => X"8C", 1 => X"A5", 2 => X"BC", 3 => X"D0",
4 => X"E2", 5 => X"F0", 6 => X"FA", 7 => X"FE",
8 => X"FE", 9 => X"FA", 10 => X"F0", 11 => X"E2",
12 => X"D0", 13 => X"BC", 14 => X"A5", 15 => X"8C",
16 => X"73", 17 => X"5A", 18 => X"43", 19 => X"2F",
20 => X"1D", 21 => X"0F", 22 => X"05", 23 => X"01",
24 => X"01", 25 => X"05", 26 => X"0F", 27 => X"1D",
28 => X"2F", 29 => X"43", 30 => X"5A", 31 => X"73"
);
Directory Structure Example
/lib
/vhdl
/msim61f_ise91sp3
/msim62a_ise10sp1
/verilog
/msim62a_ise91sp3
/msim62a_ise10sp1
/pads
/templates
/oo
/lib is the location for project libraries, templates, shared files for multiple projects
/vhdl for vhdl libraries
/verilog for verilog libraries
/pads for layout software symbols, parts, decals
/templates for examples open office
Project Directory Example
project/
/<company_name1>
/<project_name1>
/<project_name2>
/<company_name2>
/<project_name3>
/<project_name4>
<project> is the root of all the projects developed by the company, can be readable for all staff members
<company> company name of the customer
<project-name> is the formal name of the project under development, used also for svn and time table entries
<project-name>/
info/
/xilinx
/marvell
pcb/
soft/
tools/
upld/
/info additional information form the customer or websites
/pcb schematics and layout files, also production data like gerber and excellon files and searchable PDF of schematic and layout
/upld is the location for the FPGA, CPLD, … data
/soft directory for additional software like drivers
/tools additional tools
/pcb is the location for the layout data
/upld
/src
/result
/release
/src Everything insight the source directory should be under version control, no binary files
No version numbers in file names under revision control
/result temporary files generated from the tools in subdirectories with the <toolname>\ like ise91sp3, ise82sp3, edk91sp2, msim61f, pads2007, matlab2006b
/release and subdirectory with some kind of design names
automatically generated zip files include src dir report files and programming file ( *.mcs, *.bit, *.elf, *.svf,...) with name of the tag.
src\.
doc\.
figure\.
*.png
*.vsd
html\.
pdf\.
c\.
*.c
*.cpp
*.h
java\*.java
vhdl\*.vhd
verilog\*.v
<toolcompany>\*<toolversion_confname>.*
cmd\
*.make
*.bat
*.sh
Short but meaningful names
Use only lower case characters
No special character, only alphanumeric and the underscore _ to separate two two substrings are allowed, no spaces.
Name big things first like cpu_register, not register_cpu !
Use only English terms, avoid keywords or commands.
Good names are part of the documentation.
Rename names if the change the functionality
The structure of the file system hierarchy shall mirror the logical structure of the system being modelled. A directory should correspond to one and only one design unit.
Do not use version numbers, if the files are under version control like SVN.
All sources will be kept on a server at so-Logic and be revision controlled by SVN. For off line work you are able to copy the sources to a local directory. \<project_name>\.svn
The header fields will be automatically updated every time you check in your sources code in.
Tag the files every time you make a release. (send a bitstream to the customer or reaching a milestone)
web interface svn webinterface https://svn01.so-logic.net/websvn
Use the default layout structure of SVN
/trunk ... the head version
/branches ..different version, normally merged back to trunk
/tags ..named version or milestones
Commit your changes every time and add comments!
Tag if you need to go back to exact version.
Use two make files
One called Makefile this has many targets to call the real makefile like so_demo.make
Use only relative paths
Add help for different targets
Remove unnecessary targets
Use automatic name to number conversion for ID generation and names for bit stream or read back from CPUs
Try to automate all step of design flow.
Try to be compatible to use graphical tools
Examples for using of the 32 bit identification number:
# VERSION string digit 12345678
# 1. digit year
# 2. and 3. digit week
# 4. day of week 1 Monday 7 .. Sunday
# 5. digit PROJECT
# 0 .. so_hs
ifeq ($(PROJECT), so_hs)
P=0
endif
ifeq ($(PROJECT), infineon_hs)
P=1
endif
# 6. digit DESIGN
# 0 .. iotest check pinout, GTP and DCM use for all use cases
ifeq ($(DESIGN), iotest)
S= 0
endif
# 1 .. pcbtest with CPU
ifeq ($(DESIGN), pcbtest)
S = 1
endif
# 2 .. ibert serial io toolkit
ifeq ($(DESIGN), ibert)
S= 2
endif
# 3 .. HSPG
ifeq ($(DESIGN), hspg)
S = 3
endif
# 4 .. HSLA
ifeq ($(DESIGN), hsla)
S = 4
endif
# 6 .. HSPL_L
ifeq ($(DESIGN), hspl_l)
S = 6
endif
# 7 .. HSPL_TV
ifeq ($(DESIGN), hspl_tv)
S = 7
endif
# 8 .. HSPL_TJ
ifeq ($(DESIGN), hspl_tj)
S = 8
endif
# 7. digit BOARD
# 0 .. ML505 Demoboard Xilinx
ifeq ($(BOARD), ml505)
B=0
endif
# 1 .. first version of print FPGA board
ifeq ($(BOARD), hsfb1)
B=1
endif
# 8. digit PART
ifeq ($(PART), lx50t)
DEVICE=xc5vlx50t-ff1136-1
T=0
endif
ifeq ($(PART), lx110t)
DEVICE=xc5lvx110t-ff1136-1
T=1
endif
ifeq ($(PART), fx70t)
DEVICE=xc5vfx70t-ff1136-1
T=2
endif
ifeq ($(PART), fx100t)
DEVICE=xc5vfx100t-ff1136-1
T=3
endif