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:

half_adder_original.vhd
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;
Listing 1: Original Half Adder design

The command to run VSG on the file is: vsg -f half_adder_original.vhd, which gives the output:

half_adder_original.txt
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.
Listing 2: Output after running VSG on the original half adder design

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:

half_adder_fixed.txt
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.
Listing 3: Output after running VSG on the fixed half adder design

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:

  1. Run: vsg -rc port_012 > config.json

  2. Edit the json file to have, at least, "fixable": true for the port_012 rule, like shown in Listing 4 below

  3. Run: vsg --fix -c config.json -f half_adder_fixed.vhd

config.json
1
2
3
4
5
6
7
{
  "rule": {
    "port_012": {
      "fixable": true
    }
  }
}
Listing 4: VSG config

Now VSG has fixed all our errors.

half_adder_config.txt
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
Listing 5: Output after running VSG with a configuration

Continuous Integration

In case you want to use VSG in CI, there is an option (-j file.xml) to output JUnit xml files.

results.xml
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>
Listing 6: XUnit/JUnit results file

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:

vsg_ci_gitlab.png
Gitlab Results
Gitlab Results

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:

half_adder_config.vhd
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;
Listing 7: Original Half Adder design

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.