Archive for September, 2009

25 September, 2009

Another installment of “Longwinded Answers to Frequent SystemVerilog Questions: $root versus $unit”

Believe me – I tried to make this shorter. It’s difficult for me to explain things without a historical perspective.

Verilog was invented to be an interpreted language. Verilog-XL was (and still is) an interpretive engine with single compilation unit use model. In an interpreted engine, all of the source code is parsed and loaded into memory. This means you have to specify all the source files of a design, including the source files of any required libraries, within a single command line before simulating.

VCS (Verilog Compiled Simulator) continued this single compilation use model even though it compiled the code into a machine object saved on disk. Later, it introduced an incremental compile feature that only compiled certain files that needed it, but you still had to specify all the source files on the command line. This is not the same as separate compilation available in most software programming languages where source code can be converted into machine code independently.

Tools such as NCsim and Modelsim introduced the concept of separate compilation, loosely based on the work library concept from VHDL. This is relatively easy to do in Verilog because module definitions are self contained.  It turns out that module instantiation syntax is easy to recognize, so the compiler does not need to see the definition of module that is being instantiating beforehand. However, parameter overrides and hierarchical references limit the amount of machine code you can generate in the compilation step. The elaboration step that follows does a lot of the work of generating machine code to handle this.

Superlog, the predecessor to SystemVerilog, was also invented as an interpreted language. It introduced the concept of $root as a global scope that allowed any kind of declaration (data types, classes, variables) along with module definitions nested in that global scope. Any uninstantiated module becomes implicitly instantiated in $root. That’s fine for a single compilation unit, but you can no longer separately compile every  module because they may have dependencies on declarations outside their scope. For example

class C;
endclass
module top;
C c_h;
endmodule

There’s no problem if this is compiled as a single file, but if module top were to be compiled separately from the class C definition, it wouldn’t know what the identifier C was supposed to represent, and wouldn’t be able to parse the file.

So the IEEE committee borrowed the concept of packages from VHDL and standardized the concept of a compilation unit. A package allows you to compile definitions in a separate step and import those definitions into another compilation step. Packages create separate namespaces for those definitions as wall as imposing compilation order dependencies.

A compilation unit formalizes a scope that represents what is visible in a compilation step – called $unit in SystemVerilog. If you have a design that is compiled as a single compilation unit, there is really no conceptual difference between $unit and $root. However, once you have a design with multiple compilation units, then $unit represents the top level of each compilation unit, and there is nothing in $root except for the implicitly instantiated module instances. The only time you need to use $root or $unit is when a local name in the current scope hides a name in a higher level scope. For example

Compilation unit 1

function void print;
  $display("comp1");
endfunction
module mod1;
  mod2 m2();

 function void print;
   $display("mod1");
 endfunction
  initial $unit::print(); // prints “comp1”
          //print() would print “mod1”)
endmodule

Compilation unit 2

function void print;
 $display("comp2");
endfunction
module mod2;
  mod3 mod1(); // same name as top-level module
  function void print;
    $display("mod2");
  endfunction
  initial $root.mod1.print(); // print “mod1”
          // mod1.print() would print “mod3”
endmodule
module mod3;
 function void print;
   $display("mod3");
 endfunction
endmodule

This example prints “comp1” and “mod1” in either order. Note that there is no way for compilation unit 1 to directly refer to anything in compilation unit 2, or the other way around.

I hope this clears up some of the confusion between $root and $unit in SystemVerilog.

Dave Rich

,

11 September, 2009

I have lots of blog entries about 95% ready to publish. This entry is from an e-mail I wrote a few months ago when somebody asked about SystemVerilog coding guidelines. I thought it would make a good article. It’s been sitting as a draft because I always have trouble finding the right title or opening words to catch people’s attention. I couldn’t come up with anything better, so here it is: SystemVerilog Coding Guidelines

My official position about this is that you pick a style and stick to it.

Which style you pick is far less important than developing the required culture that will follow it. People can spend hours arguing over the merits of camelCaps versus under_score, but once the decision is made, people on the project need to document it, adhere to it, and police it. Otherwise you’re just wasting everyone’s time.

Why are coding guidelines so important? So someone else can read your code, or maybe you can read your own code six months after you wrote it. Good comments and documentation are an import part, but you still need to be able to read the code.

This concept of reading someone else’s code without understanding the underlying conventions reminds me of the classic short article “Meihem In Ce Klasrum” by Dolton Edwards. The article was written as a satirical response to George Bernhard Shaw’s final wishes to simplify the English language. See how easy the last paragraph is to read once you understand the new writing conventions. Reading your code should be just like that (although not as cryptic).

My advice would be to pick a style from industry and adapt it to fit SystemVerilog. For example, from Google: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml or from the Free Software Foundation: http://www.gnu.org/prep/standards/

All of these rules for naming conventions, indentation, and file organization still apply to SystemVerilog. Additional rules would be for unsupported constructs, which should be in the release notes for the tool(s) you are using. Finally, there are a few constructs to avoid, like program blocks and wildcard indexes for associative arrays, most of which might be worth hours of debate, each.

Dave Rich

, ,

@dennisbrophy Tweets

  • Loading tweets...

@dave_59 Tweets

  • Loading tweets...

@jhupcey Tweets

  • Loading tweets...