What SystemVerilog features should be avoided in synthesis?

nguthrie picture nguthrie · Dec 1, 2013 · Viewed 8.7k times · Source

SystemVerilog introduced some very useful constructs to improve coding style. However, as one of my coworkers always says, "You are not writing software, you are describing hardware." With that in mind, what features of the language should be avoided when the end result needs to be synthesized? This paper shows what features are currently synthesizable by the Synopsys tools, but to be safe I think one should only use the features that are synthesizable by all of the major vendors. Also, what constructs will produce strange results in the netlist which will be difficult to follow in an ECO?

In summary: I like compact and easy to maintain code, but not if it causes issues in the back end. What should I avoid?

Edit: In response to the close vote I want to try to make this a bit more specific. This question was inspired by this answer. I am a big fan of using the 'sugar' as Dave calls it to reduce the code complexity, but not if some synthesis tools are going to mangle signal names and make the result difficult to deal with. I am looking for more examples like this.

Answer

dave_59 picture dave_59 · Dec 1, 2013

Theoretically, if you can write software that is synthesized into machine code to run on a piece of hardware, that software can be synthesized into hardware. And conversely, there are hardware constructs in Verilog-1995 that are not considered synthesizable simply because none of the major vendors ever got around to supporting it (e.g. assign/deassign). We still have people using //synopsis translate on/off because it took so long for them to support `ifdef SYNOPSYS.

Most of what I consider to be safe for synthesis in SystemVerilog is what I call syntactic sugar for Verilog. This is just more convenient ways of writing the same Verilog code with a lot less typing. Examples would be:

  • data types: typedef, struct, enum, int, byte
  • use of those types as ports, arguments and function return values
  • assignment operators: ++ -- +=
  • type casting and bit-streaming
  • packages
  • interfaces
  • port connection shortcuts
  • defaults for function/tasks/macro arguments, and port connections

Most of the constructs that fall into this category are taken from C and don't really change how the code gets synthesized. It's just more convenient to define and reference signals.

The place it gets difficult to synthesize is where there is dynamically allocated storage. This would be class objects, queues, dynamic arrays, and strings. as well as dynamically created processes with fork/join.

I think some people have a misconception about SystemVerilog thinking it is only for Verification when in fact the first version of the standard was the synthesizable subset, and Intel was one of the first users of it as a language for Design.