Learning BSV‎ > ‎Interfaces‎ > ‎

Interface Example

The example below creates a module which provides a FIFO interface. The module has an input-side FIFO and an output-side FIFO, where the output FIFO is enqueued with the square of values taken from the input FIFO.  The module provides a FIFO interface where the enqueue methods is provided by the input-side FIFO, while the dequeue and first methods are provided by the output-side FIFO.   The clear action method calls the clear methods on both FIFOs.

The interface definition for the FIFOs come from the FIFO package.  To use the FIFO package, you use the import statement.

From the FIFO package:

interface FIFO #(type element_type);
    method Action enq(element_type x1);
    method Action deq();
    method element_type first();
    method Action clear();
endinterface: FIFO

The methods are declared in the FIFO package, but the definition of the methods is done in the module below.

import FIFO::*;

// Create a module with a FIFO interface
(* synthesize *)
module squarer ( FIFO#(int) );

   FIFO#(int) inputside <- mkFIFO ;
   FIFO#(int) outputside <- mkFIFO ;

   // a rule to move the data from input to output FIFO
   rule squarethis ;

      inputside.deq;
      let datain = inputside.first ;
      outputside.enq( datain * datain );
   endrule
 
   // methods are first-class objects and can be assigned from other methods.
   method enq = inputside.enq ;
   method deq = outputside.deq ;
   method first = outputside.first ;

   // The clear method call both FIFO clear method
   method clear  ;
      action
         inputside.clear ;
         outputside.clear ;
      endaction
   endmethod
   
endmodule

Generated Verilog


//
// Generated by Bluespec Compiler, version 2008.03.beta1 (2008-03-28)
//
// On Tue Apr  1 09:32:10 EDT 2008
//
// Method conflict info:
// Method: enq
// Conflict-free: deq, first
// Sequenced before (restricted): clear
// Conflicts: enq
// 
// Method: deq
// Conflict-free: enq
// Sequenced before (restricted): clear
// Sequenced after: first
// Conflicts: deq
// 
// Method: first
// Conflict-free: enq, first
// Sequenced before: deq, clear
// 
// Method: clear
// Sequenced before (restricted): clear
// Sequenced after: first
// Sequenced after (restricted): enq, deq
// 
//
// Ports:
// Name                         I/O  size props
// RDY_enq                        O     1
// RDY_deq                        O     1 reg
// first                          O    32 reg
// RDY_first                      O     1 reg
// RDY_clear                      O     1 const
// CLK                            I     1 clock
// RST_N                          I     1 reset
// enq_1                          I    32 reg
// EN_enq                         I     1
// EN_deq                         I     1
// EN_clear                       I     1
//
// No combinational paths from inputs to outputs
//
//

`ifdef BSV_ASSIGNMENT_DELAY
`else
`define BSV_ASSIGNMENT_DELAY
`endif

module squarer(CLK,
           RST_N,
          
           enq_1,
           EN_enq,
           RDY_enq,
          
           EN_deq,
           RDY_deq,
          
           first,
           RDY_first,
          
           EN_clear,
           RDY_clear);
  input  CLK;
  input  RST_N;
 
  // action method enq
  input  [31 : 0] enq_1;
  input  EN_enq;
  output RDY_enq;
 
  // action method deq
  input  EN_deq;
  output RDY_deq;
 
  // value method first
  output [31 : 0] first;
  output RDY_first;
 
  // action method clear
  input  EN_clear;
  output RDY_clear;

  // signals for module outputs
  wire [31 : 0] first;
  wire RDY_clear, RDY_deq, RDY_enq, RDY_first;

  // ports of submodule inputside
  wire [31 : 0] inputside$D_IN, inputside$D_OUT;
  wire inputside$CLR,
       inputside$DEQ,
       inputside$EMPTY_N,
       inputside$ENQ,
       inputside$FULL_N;

  // ports of submodule outputside
  wire [31 : 0] outputside$D_IN, outputside$D_OUT;
  wire outputside$CLR,
       outputside$DEQ,
       outputside$EMPTY_N,
       outputside$ENQ,
       outputside$FULL_N;

  // remaining internal signals
  wire [63 : 0] inputside_first_MUL_inputside_first___d5;

  // action method enq
  assign RDY_enq = inputside$FULL_N ;

  // action method deq
  assign RDY_deq = outputside$EMPTY_N ;

  // value method first
  assign first = outputside$D_OUT ;
  assign RDY_first = outputside$EMPTY_N ;

  // action method clear
  assign RDY_clear = 1'd1 ;

  // submodule inputside
  FIFO2 #(.width(32), .guarded(1)) inputside(.RST_N(RST_N),
                         .CLK(CLK),
                         .D_IN(inputside$D_IN),
                         .ENQ(inputside$ENQ),
                         .DEQ(inputside$DEQ),
                         .CLR(inputside$CLR),
                         .D_OUT(inputside$D_OUT),
                         .FULL_N(inputside$FULL_N),
                         .EMPTY_N(inputside$EMPTY_N));

  // submodule outputside
  FIFO2 #(.width(32), .guarded(1)) outputside(.RST_N(RST_N),
                          .CLK(CLK),
                          .D_IN(outputside$D_IN),
                          .ENQ(outputside$ENQ),
                          .DEQ(outputside$DEQ),
                          .CLR(outputside$CLR),
                          .D_OUT(outputside$D_OUT),
                          .FULL_N(outputside$FULL_N),
                          .EMPTY_N(outputside$EMPTY_N));

  // submodule inputside
  assign inputside$D_IN = enq_1 ;
  assign inputside$CLR = EN_clear ;
  assign inputside$DEQ = inputside$EMPTY_N && outputside$FULL_N ;
  assign inputside$ENQ = EN_enq ;

  // submodule outputside
  assign outputside$D_IN = inputside_first_MUL_inputside_first___d5[31:0] ;
  assign outputside$CLR = EN_clear ;
  assign outputside$ENQ = inputside$EMPTY_N && outputside$FULL_N ;
  assign outputside$DEQ = EN_deq ;

  // remaining internal signals
  assign inputside_first_MUL_inputside_first___d5 =
         inputside$D_OUT * inputside$D_OUT ;
endmodule  // squarer


Comments