Tuesday, February 7, 2017

SystemVerilog and Python

Design patterns in programming are when engineers find themselves writing the same code over and over to solve the same problems. Design patterns for statically typed object oriented languages (C++ and Java) were cataloged and enshrined in the famous book, "Design Patterns: Elements of Reusable Object-Oriented Software" by Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm. The authors are lovingly called, The Gang of Four, or the GOF and the book is often referred to as the GOF book.

The subset of SystemVerilog used in writing testbenches is a statically typed object oriented language (it's most similar to Java). As people started using SystemVerilog to write testbenches, frameworks for writing testbenches quickly became popular. These frameworks all provide code that implements design patterns from the GOF book. The various frameworks were similar because they were all essentially implementing the same design patterns. Eventually the various frameworks all coalesced into one, the humbly named, Universal Verification Methodology, or UVM.

Below is a table that matches up GOF design patterns with their UVM implementation. This was adapted from this presentation:

GOF Pattern Name UVM name 
Factory Method, Abstract Factory uvm_factory, inheriting from uvm base classes 
Singleton UVM Pool, UVM Global report server, etc. 
Composite UVM Component Hierarchy, UVM Sequence Hierarchy 
Facade TLM Ports, UVM scoreboards 
Adapter UVM Reg Adapter 
Bridge UVM sequencer, UVM driver 
Observer UVM Subscriber, UVM Monitor, UVM Coverage 
Template Method UVM Transaction (do_copy, do_compare), UVM Phase 
Command UVM Sequence Item 
Strategy UVM Sequence, UVM Driver 
Mediator UVM Virtual Sequencer 

If we switched from SystemVerilog to Python for writing our testbenches, would we need to re-implement each of those parts of the UVM? Python is not a statically typed object oriented language like Java and SystemVerilog. It is a dynamically typed language. Prominent and well respected computer scientist Peter Norvig explored this topic for us already. He did this when Python was still a very young language, so he examined other dynamic languages instead (Dylan and Lisp) and he concluded that of the 23 design patterns from the GOF book, 16 of them are either invisible or greatly simplified due to the nature of dynamic languages and their built-in features. As an example to explain how this could be, he points out that a defining a function and calling it used to be design patterns. Higher-level languages came along and made the pattern of defining and calling a function a part of the language.

This is essentially what has happened with dynamic languages. Many design patterns from GOF are now simply part of the language. According to Dr. Norvig, the patterns that dynamic languages obsolete are:

  • Abstract-Factory
  • Flyweight
  • Factory-Method
  • State
  • Proxy
  • Chain-Of-Responsibility
  • Command
  • Strategy
  • Template-Method
  • Visitor
  • Interpreter
  • Iterator
  • Mediator
  • Observer
  • Builder
  • Facade

That reduces the above table to:

GOF Pattern Name UVM name 
Singleton UVM Pool, UVM Global report server, etc. 
Composite UVM Component Hierarchy, UVM Sequence Hierarchy 
Adapter UVM Reg Adapter 
Bridge UVM sequencer, UVM driver 

Trusting that, if we were to write a pure Python testbench we can see that we would still likely implement a few design patterns. Thinking about this, it makes sense that we'd still probably have classes dedicated to transforming high-level sequence items to pin wiggles, just like the sequencer and driver work together to do in the UVM. It also makes sense that we'd have a class hierarchy to organize and relate components (such as the sequencer and driver equivalents) and sequences (high-level stimulus generation). Thing like that.

The more striking thing is the amount of code we would not need.