Learning BSV‎ > ‎Interfaces‎ > ‎

Library Interfaces

The Bluespec library provides interfaces for many common hardware elements, such as Registers, FIFOs, and Register Files.  These interfaces are polymorphic; that is, the interfaces are parameterized on the type of data used in the elements.  Moreover, several variations of modules can provide the same interface types, thus allowing easy reuse when modules change.

Reg Interface

Probably the most common interface is type Reg#(type a), which is an interface to a register. The definition is polymorphic on the type of data (type a), and provides two methods: _read and _write
  interface Reg #(type a_type);
       method Action _write(a_type x1);
       method a_type _read();
   endinterface: Reg

Bluespec provides a shorthand notation for reading and writing registers, because of their frequency of use.  The following two action blocks are functionally equivalent in the code fragment below. 
        // instantiate 2 registers
        Reg#(Data_t)    debug_datain <- mkRegU ;
        Reg#(Data_t)    datain       <- mkRegU ;
        // Using explicit function calls of the Reg interface
           datain._write( datain._read + 500 );
           debug_datain._write( datain._read ) ;

        // Alternative, using Reg interface shorthand notation
           datain <= datain + 500 ;
           debug_datain <= datain ;

The Reg interface type is provided by several modules from the Bluespec Library; these include mkReg, mkRegA, mkRegU, mkConfigReg, mkConfigRegA, and mkConfigRegU.

FIFO Interface

Like the Reg interface, the FIFO interface is polymorphic on its type: FIFO#(type a). It provides four methods, and its prototype is:

interface FIFO #(type a);
    method Action enq(a x1);
    method Action deq();
    method a      first();
    method Action clear();

The FIFO interface type is provided by the  module constructors: mkFIFO, mkFIFO1, mkSizedFIFO, and mkLFIFO.   Other modules which are not FIFOs may provide this interfaces.  Moreover, the FIFO type interface provides a basis for the GetPut interface, and is a common building block for many
modules and interfaces.

RWires and PulseWires

Although RWire is not a common hardware element, it provides a useful tool in the Bluespec environment for transporting data between methods and rules without the cycle latency of a register.  The RWire interface is defined:

interface RWire #(type a);
    method Action     wset(a x1);
    method Maybe#(a)  wget() ;

The interface can considered as a wire plus a valid signal.  The wset method writes a value to the wire and sets the valid signal.  The wget method returns the value and the valid signal in a Maybe type.

There are two alternative interfaces for RWires,  one in the common Reg interface, and the second is the PulseWire interface, which wraps a RWire without any data.

interface RWire #(type a);
    method Action     send ();
    method Bool      _read() ;

The use of these interfaces, and the corresponding modules constructors mkWire and mkPulseWire, are strongly encouraged over the primitive RWire.