VHDL Style Guide (VSG)
VHDL Style Guide describes it self as a tool that “provides coding style guide enforcement for VHDL code”. It is similar to clang-tidy or Black in that it can fix your code to follow a coding styleguide. This post is a quick overview of VSG to help you get started using it.
Table of Contents
The docs are here and the repository is here. Install with: pip install vsg
Example
To showcase the basic features of VSG we will be running it on the half adder posted on nandland, but with some mistakes injected to make this a bit more interesting. The code looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity half_adder is
port (
i_bit1 : in std_logic;
i_bit2 : in std_logic;
--
o_sum : out std_logic := '0';
o_carry : out std_logic := '0'
);
end half_adder;
architecture rtl of half_adder is
begin
o_sum <= i_bit1 xor i_bit2;
o_carry <= i_bit1 and i_bit2;
end rtl;
The command to run VSG on the file is: vsg -f half_adder_original.vhd
, which gives the output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
================================================================================
File: half_adder_original.vhd
================================================================================
Phase 1 of 7... Reporting
Total Rules Checked: 82
Total Violations: 4
Error : 4
Warning : 0
----------------------------+------------+------------+--------------------------------------
Rule | severity | line(s) | Solution
----------------------------+------------+------------+--------------------------------------
port_012 | Error | 10 | Remove assignment
port_012 | Error | 11 | Remove assignment
entity_015 | Error | 13 | Add *entity* keyword
architecture_010 | Error | 19 | Add *architecture* keyword.
----------------------------+------------+------------+--------------------------------------
NOTE: Refer to online documentation at https://vhdl-style-guide.readthedocs.io/en/latest/index.html for more information.
Four errors and three different rules that have been broken; the first two errors are due to ports being initialized, the third and fourth error are due to a missing keyword along with the end keyword (entity and architecture respectively).
Now we want VSG to fix all these errors it caught, but first I’ve copied the original file and renamed it half_adder_fixed.vhd
so I can look at the changes, VSG also has the -b/--backup
option for this purpose, but I don’t like how it works (copying the file to another file with a .bak
appended to the filename and overwriting the original).
To have VSG fix the file, we run: vsg --fix -f half_adder_fixed.vhd
and get the output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
================================================================================
File: half_adder_fixed.vhd
================================================================================
Phase 1 of 7... Reporting
Total Rules Checked: 82
Total Violations: 2
Error : 2
Warning : 0
----------------------------+------------+------------+--------------------------------------
Rule | severity | line(s) | Solution
----------------------------+------------+------------+--------------------------------------
port_012 | Error | 10 | Remove assignment
port_012 | Error | 11 | Remove assignment
----------------------------+------------+------------+--------------------------------------
NOTE: Refer to online documentation at https://vhdl-style-guide.readthedocs.io/en/latest/index.html for more information.
The port_012
rule is set to not be fixable by default, it can be fixed by hand or for a little extra work you should be able to make VSG fix it by following these steps:
-
Run:
vsg -rc port_012 > config.json
-
Edit the json file to have, at least,
"fixable": true
for theport_012
rule, like shown in Listing 4 below -
Run:
vsg --fix -c config.json -f half_adder_fixed.vhd
Now VSG has fixed all our errors.
1
2
3
4
5
6
7
8
================================================================================
File: half_adder_config.vhd
================================================================================
Phase 7 of 7... Reporting
Total Rules Checked: 521
Total Violations: 0
Error : 0
Warning : 0
Continuous Integration
In case you want to use VSG in CI, there is an option (-j file.xml) to output JUnit xml files.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" ?>
<testsuite errors="0" hostname="katla" failures="1" timestamp="2021-04-24T11:44:26" tests="1" time="0" name="vhdl-style-guide">
<properties>
</properties>
<testcase name="half_adder_*.vhd" time="0" classname="failure">
<failure type="Failure">
source_file_001: 0 : No such file or directory
</failure>
</testcase>
<system-out>
</system-out>
<system-err>
</system-err>
</testsuite>
Adding vsg to GitLab CI is straightforward:
image: ghdl/vunit:gcc
vsg:
stage: test
before_script:
- pip3 install vsg
script:
- vsg -f half_adder.vhd -j vsg_results.xml
artifacts:
reports:
junit: vsg_results.xml
With this GitLab presents an overview of errors:
Conclusion
Besides fixing the errors, VSG has also changed indenting in accordance with it’s default rules. The rules for error detection and indenting are highly configurable.
The final result is this beautifully formatted file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity half_adder is
port (
i_bit1 : in std_logic;
i_bit2 : in std_logic;
--
o_sum : out std_logic;
o_carry : out std_logic
);
end entity half_adder;
architecture rtl of half_adder is
begin
o_sum <= i_bit1 xor i_bit2;
o_carry <= i_bit1 and i_bit2;
end architecture rtl;
We get a nice clean file, with in theory no manual labor. In practice, even if the tool may not be able to fix certain errors, at least it points them out for you and fixes some of them.
Changelog
2021-04-24
- Update output according to version 3 of VSG, which fixes some previous issues with configuration.
- Add information about JUnit output.
Comments? You are welcome to start a discussion on Github.