Aller au contenu

Tools

Editing VHDL files

VHDL files, like most source code, are simply text files. Any text editor can be used to make VHDL. However some are more adapted than others. Emacs (Windows, GNU/Linux, MacOS) is one of them, thanks to its VHDL major mode and electric minor mode. Emacs automatically switches to VHDL mode when opening or creating a file with a .vhd extension. Notepad++ under windows is also an interesting tool to edit in VHDL. VSCode is a good editor as well.

Emacs

We are not going to make a manual of emacs here, others have surely done it much better than we could (but in 611 pages) https://www.gnu.org/software/emacs/manual/pdf/emacs.pdf

This link points to a two-page pdf document giving the main emacs keyboard shortcuts: https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf

The advantage of emacs in addition to being very complete is that it is multi-platform. Its disadvantage is that the learning curve is very steep.

Note: the notation of the shortcuts below is the one adopted in almost all Emacs documentation. For example the shortcut noted Ctrl+C Ctrl+T S I means :

  1. Press the Ctrl key, and keep it pressed
  2. Press and release the C key
  3. Press and release the T key
  4. Release the Ctrl key
  5. Press and release the S key
  6. Press and release the I key

In Emacs documentations the key M in shortcuts stands for the meta key. On most keyboards it is the Alt key (to the left of the space key).

The general shortcuts of the emacs VHDL mode

The most useful Emacs shortcut in VHDL mode

Ctrl+C Ctrl+B : Beautify, clean up a VHDL code, to use without moderation !!!

Keyboard shortcuts to insert Templates

Shortcut common part Shortcut suffix Description
Ctrl+C Ctrl+T Ctrl+H insert header
Ctrl+P and S or N or T insert package (1164/numeric_std/textio)
E+N insert entity
A+R insert architecture
P+C insert process (comb)
P+S insert process (seq)
S+I insert signal

Keyboard shortcuts to manipulate input/output ports

Shortcut common part Shortcut suffix Description
Ctrl+C Ctrl+P Ctrl+W copy ports
Ctrl+E paste as entity
Ctrl+C paste as component
Ctrl+I paste as instance
Ctrl+S paste as signals
Ctrl+C paste as constants
Ctrl+G paste as generic map
Ctrl+Z paste as initialisation
Ctrl+T paste as test bench

Notepad++

The Notepad++ editor is free and open source, available under windows only. Its main asset is its very efficient rectangular editing. Just hold down the ALT key and select with the mouse. There is a VHDL plugin that offers some of the functions of the VHDL mode of emacs. https://notepad-plus-plus.org/downloads/

VSCode

TODO

Modelsim

Simulation and Modelsim Script

To simulate a circuit, you need a test bench Test bench file and use a simulator. It is often faster to run simulations in Modelsim with Tcl scripts. To launch the execution of a script in Modelsim, you must go to the directory containing the script and then execute the command "do script.do" in the "Transcript" area of Modelsim.

Here is an example of a script that allows you to compile the VHDL files, launch and parameterize the simulation and choose the signals you want to display:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#
# Create work library
#
vlib work
#
# Compile sources
#
vcom -explicit  -93 "Test.vhd"
vcom -explicit  -93 "Registre.vhd"
vcom -explicit  -93 "RegistreDecalage.vhd"
vcom -explicit  -93 "Counter.vhd"
vcom -explicit  -93 "FSM.vhd"
vcom -explicit  -93 "tb_Test.vhd"
#
# Call vsim to invoke simulator
#
vsim -novopt -t 1ns -lib work work.tb_Test
#
# Source the wave do file
#
do wave.do # appel du script qui affiche les signaux
#
# Set the window types
#
view wave
view structure
view signals
#
# Run simulation for this time
#
run 1000ns # il est possible de changer la duree
#
# End
#

The script wave.do has this format :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /tb_test/I_Clock
add wave -noupdate /tb_test/I_Reset
add wave -noupdate /tb_test/I_Load
add wave -noupdate -radix unsigned /tb_test/I_DLoad
add wave -noupdate /tb_test/I_Enable
add wave -noupdate -radix unsigned /tb_test/O_Count
add wave -noupdate -divider -height 50 <NULL>
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {233 ns} 0}
quietly wave cursor active 1
configure wave -namecolwidth 150
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ns} {1050 ns}

However, it is much easier to build it with the Modelsim graphical interface, and to save it (By moving to the wave window to make it active, file -> Save Format.

Useful commands to use directly in the console window (Transcript): - restart -force ; run 500us allows to force the restart of a simulation and to launch a run for the indicated time - quit -sim allows you to end a simulation, for example to change the working directory to start another one.

Vivado scripts

In the same way that it is possible to use Tcl scripts with modelsim, it is possible to do it with Vivado.

Here are some commands that can be used in a script or directly in the "Tcl Console" of vivado.

Command Description
reset project delete all the files created by Vivado during the different phases of the flow while keeping all the source files. Equivalent to the "Clean up project files" of ISE.
set_param project.enableVHDL2008 1 Activate the VHDL 2008 support (partial support, and different according to different depending on the tools, to be used with care).
launch_runs synth_1 -jobs 8 Launch the synthesis "synth_1" on 8 processor cores
reset_run synth_1 Interrupt the synthesis "synth_1".
launch_runs impl_1 -jobs 8 Launches the "impl_1" implementation on 8 processor cores. Launch the synthesis if it has not been done before
reset_run impl_1 Interrupts the implementation "impl_1"
route_design -timing_summary calculate the timings of the design and thus to know precisely the critical path.

Constraint file

In Vivado, the constraint file contains, among other things, the correspondence between the inputs and outputs of the circuit we design and the pins of the FPGA chosen to implement this circuit. It is also possible to constrain the clock period that we want to reach. The synthesis tool then looks for the best timing/area compromise to minimize the area while being able to respect the chosen timing.

The syntax of vivado constraint files (*.xdc files) is based on that of Synopsys constraint files (*.sdc).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
### Input clock I_Clock_name, period 1,5 ns, duty cycle 50%
create_clock -period 1.500 -name I_Clock_name -waveform {0.000 0.750} I_Clock_name

##7 segment display
##Bank = 34, Pin name = IO_L2N_T0_34,                       Sch name = CA
set_property PACKAGE_PIN L3 [get_ports {O_7segment[6]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[6]}]
##Bank = 34, Pin name = IO_L3N_T0_DQS_34,                   Sch name = CB
set_property PACKAGE_PIN N1 [get_ports {O_7segment[5]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[5]}]
##Bank = 34, Pin name = IO_L6N_T0_VREF_34,                  Sch name = CC
set_property PACKAGE_PIN L5 [get_ports {O_7segment[4]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[4]}]
##Bank = 34, Pin name = IO_L5N_T0_34,                       Sch name = CD
set_property PACKAGE_PIN L4 [get_ports {O_7segment[3]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[3]}]
##Bank = 34, Pin name = IO_L2P_T0_34,                       Sch name = CE
set_property PACKAGE_PIN K3 [get_ports {O_7segment[2]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[2]}]
##Bank = 34, Pin name = IO_L4N_T0_34,                       Sch name = CF
set_property PACKAGE_PIN M2 [get_ports {O_7segment[1]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[1]}]
##Bank = 34, Pin name = IO_L6P_T0_34,                       Sch name = CG
set_property PACKAGE_PIN L6 [get_ports {O_7segment[0]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {O_7segment[0]}]

Naming and coding convention

All names should preferably be in English. Use of a capitalized prefix followed by a "_" according to the kind:

Name Description
I_NameOfInput for an input
O_NameOfOutput for an output
IO_NameOfInputOutput for an input/output
SC_NameOfCombinatorialSignal for an internal combinatorial signal
SR_NameOfRegisteredSignal for a internal flip-flop signal
V_NameOfVariable for a internal variable in a process or function
CST_NAME_OF_CONSTANT for a constant
A_NameOfArray for an array
G_NameOfGeneric for a generic
T_NameOfType for a type
R_NameOfRecord for a record

it may seem very wordy, but is in fact very useful for readability during simulations and debug and make the code easy to reuse

Use of a suffix preceded by a "_" depending on the signal:

Name Description
I_Reset_n for an active low signal
I_Clock_g for a system wide used signal (g for general)

Dernière mise à jour: March 19, 2024