Learning BSV‎ > ‎Interfaces‎ > ‎

Action Methods

Action methods drive data into a module or change state in a module.

interface FIFO;
method Action enq(Bit#(32) data);
method Bit#(32) first();
method ActionValue#(Bit#(32)) deq() ;

In the first method of the FIFO above, enq, we are driving a 32 bit bus of data for the push onto the FIFO. 

To be more complete, an Action method has a optional list of busses, and optional ready and enable signals.  Bluespec generates Verilog signal names that combine the method name and the input data name. Hence, the method enq has an input named data. The signal becomes enq_data.   The generated Verilog for the enq method is:

   //method Action   enq(Bit#(32) data);
input [31:0] enq_data;
input EN_enq;
output RDY_enq;

The data input bus is simply passed to the block as in input. Bluespec generates two additional signals that may be optimized away later if they are not used. The enable signal (which are by default called EN_methodname, such as EN_enq above), is an input which causes the logic defined in the method to execute.

So for the FIFO, the method code is defined in the module as:


    module mkFIFO (FIFO) ;
          Reg#(Int#(32))  repArr[8];      // an array of 8 registers
          Reg#(Int#(3))    rptr <- mkReg(0);
          Reg#(Int#(3))    wptr <- mkReg(0);
          Reg#(Int#(4))    cntr <- mkReg(0);

          Bool notFull = (cntr < 8 );

          method Action   enq(Bit#(32) data) if (notFull);
               regArr[wptr] <= data;
               cntr <= cntr + 1;
               wptr <= wptr + 1;

This method is defined inside the module.  It implements the interface method that was defined in the interface.  Different modules can define different implementations of this method, but there is only one interface definition.  It is common to define one interface for a module, but then to have several module definitions (one transaction level, one behavioral, one hardware level, etc.).

So the method line in the module is the same as the interface definition except now we see if (notFull).  This is how a module can define a ready condition.  This ready condition is the RDY signal used by rules and methods calling this method.  In this case, if the FIFO is full, we set the ready signal as False, so that the calling rule knows the state of this method.  This ready condition can be anything that the designer wants.  Bluespec encourages you to define ready conditions where it makes sense, and to code assuming ready conditions are complete.

There is also an enable signal named EN_enq driven into the method.  This signal will cause the combination logic inside the method to be enabled, or clocked, or to do what it is supposed to do.  In this case, EN_enq will write a register, increment wprt, and increment cntr.  

The Bluespec compiler may use both EN_enq and RDY_enq to enable the firing of rules and methods which call this method.

Compiler attributes can be used to change the default method names.