When defining interfaces, the prototypes for the methods are declared. However, it is up to the module which provides the interface to define the methods. This allows different modules to provide the same interfaces, yet produce very different implementations for these interfaces. This section describes some guidelines for defining methods for interfaces. Within a module, communication between separate methods, separate rules, or between rules and methods occurs through module level Bluespec SystemVerilog elements, such as registers, FIFOs, or other modules. To ascertain that redundant flops are not added and latency is kept to a minimum, the following guidelines should be kept in mind. 1. Combine all combinational logic from the ports to the first stage of state elements into the interface methods. eg. x1 and y1 are input ports and sum is the first stage of state elements Reg#(a) sum <- mkReg (0) ; // instantiate an register interface ... // Add the two inputs storing result in register sum. method Action calc( x1, y1 ); action sum <= x1 + y1; endaction endmethod // note: types for x1 and y1 are taken from the interface definition. 2. Define rules for transitions in the state elements. i.e. for designs with multiple stages of flip-flops, all the intermediate logic can be defined in terms of rules. e.g. stage1 and stage2 are registers. Depending upon an opcode which is registered, stage2 gets the value of stage1 either as it is or inverted rule calc (True) case(opcode) 3'b001: begin stage2 <= stage1; end 3'b010: begin stage2 <= 1 - stage1; end ... endcase endrule 3. Good design requires that output ports are directly registered or derived only from state elements. The output or Mealy logic should be placed in the methods as well.e.g. z1 is an output port which is high if all bits of register product are highReg#(Int#(16)) product <- mkRegU ; ... method Bit#(1) z1(); z1 = & product; // reduction and endmethod; ... Sharing Signals in an InterfaceConsider an interface to a memory system as follows:
interface Memory_ifc ; In this definition, there would be four buses (read_addr, read (return value from read method), write_addr, and write_datain) plus three handshaking signals (RDY_read, RDY_write, and EN_write). It may be desirable to have the address bus shared between the two methods. This section shows some styles on how this can be done. Using a Common MethodThe read and write methods may be combined into a single method.
interface Memory_ifc ; In this example, there are three buses (data_out, read_write_addr, and read_write_datain ) plus three handshaking signals (RDY_read_write, RDY_data_out, and EN_read_write). Using a Separate Method for the Shared SignalsA separate action method is added which takes in the address for both the read and write methods. The implementation of the addr method may require some special techniques, such as using an RWire.
interface Memory_ifc ; In this example, there are three buses (addr_addr, read, and write_datain) plus five handshaking signals (RDY_addr, RDY_read, RDY_write, EN_addr and EN_write). Combining InterfacesConsider that interfaces are treated like structures (collections) of methods, then it is possible to combine separate interfaces into one, (i.e., an interface composed of other interfaces).
interface Part1_ifc ;
|
Learning BSV > Interfaces >