[BSV] Introduction to Bluespec SystemVerilog

Last edited at 2025-04-27
54 Views

Why BSV?


BSV (Bluespec SystemVerilog) is a high level hardware description language (HDL). With BSV, we can describe the hardware's behavior with very abstract and intuitive expressions, and it can be fully synthesized into a real hardware design. (The Bluespec compiler will translate the BSV code into a Verilog code.)


In this post, we will look at basic concepts and terminologies in BSV programming.

If you are trying to set up a BSV development environment in your machine, refer to my previous post or the official documentation and user guide.



Hello World


This code shows the basic structure of a BSV code.


package HelloWorld;
   //first design in the Bluespec language
   String s = "Hello world";

   (* synthesize *)
   module mkHelloWorld(Empty);
     rule say_hello;
       $display(s);
     endrule
   endmodule
endpackage


A package is like a namespace, in which all your code elements are organized. A module specifies the components of hardware you want to design. The (* synthesize *) attribute specifies which module of the code is translated into the actual hardware design. The modules in BSV are conventionally named like mkModule (Here 'mk' stands for make), implying that a single module can be instantiated multiple times with different parameters.


Inside a module, a rule describes an internal behavior of the module. The behavior described in a rule is repeated at each clock cycle (just like the 'always' block in Verilog). So in the code above, the module prints "Hello world" in the simulation console every one clock cycle.


Rules can have guards that specify the conditions for the rule to fire. Rules also have implicit guards, which automatically prevents the rule from firing if at least one of the behavior specified in the rule (e.g. calling a method of another module) is not possible. If one or more behavior in the rule is impossible, all the other behaviors in that rule is not fired as well. Hence we say that a single rule specifies the module's one atomic behavior.


A method corresponds to input and output pins in Verilog. Methods describe how the outside world communicates with the module: following is an example code.


package Tb;
  (* synthesize *)
  module mkTb (Empty);
    Ifc_type ifc <- mkModuleDeepThought;
    rule theUltimateAnswer;
      $display ("The answer is: %0d", ifc.the_answer (10, 15, 17));
      $finish (0);
    endrule
  endmodule: mkTb
  
  interface Ifc_type;
    method int the_answer (int x, int y, int z);
  endinterface: Ifc_type

  (* synthesize *)
  module mkModuleDeepThought (Ifc_type);
    method int the_answer (int x, int y, int z);
      return x + y + z;
    endmethod
  endmodule: mkModuleDeepThought
endpackage: Tb


A module is accessed from the outside via an interface. The concept is very similar to interfaces in object-oriented programming. An interface consists of methods, and acts like a 'contract' between the module and outside worlds, stating how the module should be accessed. An interface can be assigned to multiple modules that can be accessed in the same way. The interface of a module is identified in the parenthesis next to the module's name. The Empty identifier means that the module has no interface.


I hope this post helped you understand the overall structure of BSV language. The next post will cover variables, types and combinational circuits in BSV.



References

  1. Rishiyur. S. Nikhil, Kathy Czeck. "BSV by Example". Bluespec(2010).
  2. Bluespec SystemVerilog Reference Guide
  3. Class materials of SNU CSE (2025)