Custom VHDL code formating

A few people asked me recently if the VHDL code formater in Sigasi can be customized to their code style. So I decided to write a blog post about so it can easily be Googled.

Can the formatter of Sigasi be customized? (The short answer is No. The long answer is Yes.)

Technically speaking we (the Sigasi developers) can easily modify code formatting. But we did not create a user interface to do this. The reason is that there are so many rules (and corner cases). So creating a UI to customize formatting would be a too much work for the added value it brings. So at this time, you can not customize Sigasi's formatting rules (except for the use of spaces vs. tabs).

However if you want a custom style (that differs from the Sigasi default), we can implement this custom style for you. We can even implement type-time linting checks that verify that all coding guidelines are respected. Contact us for more information.

Hendrik

Comments

I would be more than happy if

I would be more than happy if I could define 'user formatting' (and a few other rules like component instantiation) with a 'text file' – I don't need a GUI for that.

E.g. when instantiating a

E.g. when instantiating a component the result looks like this:

wor : wide_or
    generic map(WIDTH_D => WIDTH_D)
    port map(A => A,
                     B => B,
                     Z => Z);
(converted the tabs to spaces, but does not work well here)
Ugly! I have to manually reformat it to my (personal?) liking:
wor : wide_or
    generic map (
        WIDTH_D => WIDTH_D
        )
    port map (
        A => A ,
        B => B ,
        Z => Z
        ) ;

Formatting instantiations

Hi Josy,

Sigasi tries to respect existing newlines when it (re)-formats your code. If I remember it well, you can make Sigasi format your code in your style if you put a newline before the opening parenthesis and before the closing parenthesis of the port and generic map.

Hendrik.

This is the component

This is the component declaration:

	component wide_or
		generic (
			WIDTH_D : natural := 8
			) ;
		port (
			A		:	in	std_logic_vector(WIDTH_D – 1 downto 0) ;
			B		:	in	std_logic_vector(WIDTH_D – 1 downto 0) ;
			Z		:	out	std_logic_vector(WIDTH_D – 1 downto 0) 
			) ;
		end component ;		
(tabs should be 4 not 8)
I don't see where to add a newline?

Unclear

Sorry, my original answer was incomplete. I meant to add the newlines before the parenthesis of the port and generic map. I have updated my original comment accordingly.

Hendrik.

Now I'm confused. What I

Now I'm confused.
What I meant to demonstrate is that upon a component instantiation my formatted component gets mangled into something I have to reformat manually to get the formatting I originally had.

Confusion

Do I understand that you expected the component instantiation to have the same formatting as the original component declaration?

That is not how Sigasi internally works. The code for the instantiation is generated from an abstract model of the component (which contains no formatting information). The code is generated with internal formatting rules.

What I meant to say is that with some minor interventions, you can still use the default Sigasi formatter.

  1. instantiate your component with autocomplete
  2. manually insert newlines:
    1. after generic map (
    2. before and after ) port map (
    3. before ) ;
  3. if you run the formatter now, the code style will be almost literally the same as what you described

I hope this is a little less confusing.

Hendrik.

I can see clearer now

Do I understand that you expected the component instantiation to have the same formatting as the original component declaration?
That is not how Sigasi internally works. The code for the instantiation is generated from an abstract model of the component (which contains no formatting information). The code is generated with internal formatting rules.

Yes, that is what I expected. I could have lived with a different placement of the closing parenthesis, but not with the ugly first line of generic map and port map.Those internal formatting rules is what I proposed to control with the UNIX-style configuration file.

What I meant to say is that with some minor interventions, you can still use the default Sigasi formatter.
instantiate your component with autocomplete
manually insert newlines:
after generic map (
before and after ) port map (
before ) ;
if you run the formatter now, the code style will be almost literally the same as what you described

I never used the internal formatter, as the other editors (Quartus, PsPad, etc .) I use don't have formatters (or I never searched for or stumbled upon them). So I write neatly formatted code while I go along (and I always tidy-up directly)

I hope this is a little less confusing.
Yes, i'll look into the formatter again.
Thanks,
Josy

Textual UI

Hi Josy,

unfortunately, even a textual UI would be an awful lot of work. There are many, many rules and corner cases.

Hendrik.

Is the choice really between

Is the choice really between exposing all or nothing? There must be some low hanging fruit.
For me setting automatic vertical alignment to "off" would be good enough.
It is really annoying to not be able to change simple stuff that surely must be just an on/off setting for you.
Your competitor emacs supports shutting off vertical alignment.

Formatting options

Based on user feedback we are steadily introducing more formatting options (see Sigasi 2.24).
Each new option makes the formatter harder to test, so we think twice before adding more.

That said, adding a toggle for disabling vertical alignment certainly makes sense.

Hendrik.

It makes me happy that you

It makes me happy that you would consider adding this.
Although I understand that you do not want to multiply your testing efforts other comparable tools for editing code typically have these basic options already.
Adding just a few such options would satisfy the needs of most users.

Formatting Rules

Are the current rules (maybe without corner cases) listed somewhere explicitly?
Right now, there are a few ugly spots here and there. I'll just quickly show some examples of my favorite pet peeves.

  • Enumerations and sensitivity lists:
    Right now, all identifiers are just written one after the other, separated by commas until the line breaks at some number of characters. I usually have them aligned all in a column instead, i.e. each identifier on its own line:
    read_proc: process (
    	cs,
    	wr_rd_n,
    	addr_out,
    	rx,
    	tx
    	)
    begin
    ...
    end process read_proc;
    and
    type fsm_state is (
    	idle,
    	sync
    	);
  • Component declaration/instantiation:
    Pretty much what has been said already:
    component dff
    	generic(
    		init : STD_LOGIC := '0'
    	);
    	port(
    		clk   : in  STD_LOGIC;
    		reset : in  STD_LOGIC;
    		D     : in  STD_LOGIC;
    		WE    : in  STD_LOGIC;
    		Q     : out STD_LOGIC
    	);
    end component dff;

    I align my generics and ports starting on a new line and usually either have one big group or smaller groups of semantically connected ports separated by one or more newlines without comments (think doxygen). These are then aligned inside their respective sub-groups.
    entity decoder
    	port(
    		clk   : in STD_LOGIC;
    		reset : in STD_LOGIC;
     
    		--! \name SDRAM Signals
    		--! @{
     
    		--! SDRAM Data Bus
    		--! Unidirectional Data Bus for SDRAM
    		sdram_data : in  STD_LOGIC_VECTOR(31 downto 0);
    		sdram_clk  : out STD_LOGIC                      --! SDRAM Clock
    		--! @}
    	);
  • Initial Indentation
    Most lines start with initial tabulation for some reason. This unnecessarily increases the overall indentation. For instance, I always have constants/signals/variables in declarative parts not indented, because I find this easier to read and manage. Same goes for component declarations and processes/procedures/functions/instantiations. I usually end up having them declared without indentation and then having to remove all additional tabs at the end of the declaration.

Hi Rob, thanks for sharing

Hi Rob, thanks for sharing your opinion. You make some good points.

In case you haven't done so, it may be useful to reduce the size of a vertical tab

Just mimic xemacs vhdl-mode's beautify

As far as I know, beautify is the "gold standard" in formatting.

Beautify is also customizeable, so maybe those switches would be a start for the customization gui.

Hi Andy, are there specific

Hi Andy, are there specific switches or formatting options that you would like to see in Sigasi?

format options

Need an option to uppercase (or lowercase) all keywords (this is helpful when code listings are reviewed without the help of a highlighting editor.)

Choice between indentation or waterfall for subprograms with mult-line argument lists. Currently, Sigasi appears to choose indentation with fixed tabstops if the 1st argument is on a new line, or waterfall if the 1st argument is on the same line as the opening '('. However, for waterfall, the closing ") return xxx is" should be vertically aligned with the opening '(', whereas it is currently indented one tabstop. True waterfall helps visually distinguish the subprogram signature from the local declarations.

Disable formatting in certain places

There are occasions when I just want to format the code in some slightly unusual way, and not have it reformatted – is there some pragma you could include to allow this maybe?

thanks!

Hi Martin! No, that doesn't

Hi Martin!
No, that doesn't exist today. I haven't seen it in software IDE's either…

It appears that Eclipse's

It appears that Eclipse's Java formatter can do it:

http://stackoverflow.com/a/3353765/106092

Format region

Hi Martin,

as Philippe said, you can not exclude a region for the VHDL formatter.
What you can do however, is the inverse operation. You can format only a specific region (the selection). Is that a solution for your use case?

Hendrik.

Unfortunately, not really

Unfortunately, not really :(

My favoured workflow is to type a few lines of code then press Ctrl-Shift-F followed by ctrl-S, so I'm continually re-running the formatter to keep my code consistent (it's a workflow I've got into with Eclipse for other languages too). It's only occasionally a problem, but it'd be nice to be able to exclude the occasional region…