The return value of a function is specified as assigning to the function name. This:

Need a way to group signals to form busses

Consider moving attribute specifier to after variable declaration instead of before. This makes mixed attribute/non-attribute variable declarations line up better to make the code more readable

Consider curly braces intead of begin/end since they are shorter to type and widespread in many languages

VHDL has an automatic assignment enum type, Verilog needs similar. SystemVerilog has this but seems in the scope of the verilog langauge to add it as well.

module declaration is inconsistent with other syntax. Instead of:

module my_module(input wire clk);


It should be:

module my_module(input wire clk) begin


Is there a verilog equivilent of VHDL's “others”?

Should not depend on module compile order. This almost seems more tool specific but I'm fairly certain that its specified in the LRM (TODO: check). For example, if you issue “`default_nettype none” in a first file you must put “`default_nettype wire” in the second or it may fail to compile because it uses implicit nettypes

Undefined variables are not always errors (ie without using `default_nettype none). For example, if you have:

my_port my_port_0(.I(undefined), .O(also_undefined))


The compiler happily synthesizes this as unconnected signals since it can't match them to anything. This is also almost more tool specific but there is a large amount of code out there that depends on this behavior.

Its also unfortunate that “`default_nettype none” really does (at least) two things:

The first I consider a real error/language defficiency. The second, while I don't do it, I see it more as stylistic in the same way that a lot of people write “int” rather than “signed int” in C.

Verilog has this odd 32 bit built in standard that should really be arbitrary. For example, when doing like

wire [255:0]  my_signal = 'b1


it should behave like VHDL others: should not be limited to arbitrary limits like 32 (64 in newer Verilog…wow what a terrible fix)


SystemVerilog is a CF merge of three EDA tools proprietary extensions. It adds an obscene number of keywords to the language as a result of the vendors going down separate paths and trying to merge everything back together.

CISC vs RISC language

Verilog is a CISC in the sense that instead of a collection of simple keywords that can be used to create powerful constructs, it instead favors a large number of powerful keywords.

One of the big problems with this approach has been that its difficult for vendors to actually implement the language.

Key/value inconsistency

The way that you define key/value pairs for modules is different than how you do it for structures:

  • Modules use .key(value)
  • Structs use key:value

Python has the same issue and they have (probably?) thought about this more (= for functions, : for dicts). Is there a fundamental reason to do it this way?


Import vs include

The basis of import is around `include technical debt: the prprocessor state is carried over to the next file rather than restarted on each new file. I have yet to see a project that actually relies on this behavior but I only imagine they must exist. If someone was able to declare that this was not longer required, I imagine that import would have not been added.

Overall, import is probably a step in the right direction. I could criticize that there are now two mechanisms to do the same thing but I have no problem with the existing of if and case for the same reason: slightly different tool that will sometimes work slightly better in a different situation.


does assert require a pass/fail clause?


void' (my_func(1, 2, 3));


Casting to void seems odd.

enum casting rules

Inconsistent: if I can assign an enum to a number I should be able to compare it to a number. That is, if a cast was required in one instance it should have been in the other.

Verilog traditionally has been looser syntax. The VHDL way would have been to require a cast but Verilog should not have required it.

sformat vs sformatf

sformat(txt, "stuff: %d", 123);
txt = sformatf("stuff: %d", 123);


sformat is useless: just assign the return from sformatf

keywords vs import

They solved the wrong problem: instead of adding more keywords, they should have gone further with the import concept to extend to things like sformat. C went down this approach originally (ex: printf didn't require an important) but eventually required imports for all functions.


This adds a lot of synactical overview. Propose instead to have syntax to invert the polarity to solve the source/driver problem.


Need to think these over. Would it have been better to add attributes in lieu of new keywords?

verilog/criticism.txt · Last modified: 2015/04/13 19:06 by mcmaster-guest
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki