Reference 1
Modules and interfaces form the heart of BSV.
Modules and interfaces turn into actual hardware.
An interface for a module m
mediates between m
and other, external modules that use the facilities of m
, i.e. clients
of m
.
A single module definition of a FIFO, and multiple instantiations of this FIFOs in a design.
Pure hierarchy.
In a module definition, mkM
, one can specify instantiations of other modules.
Every module instance unambiguously has a single parent module instance.
The top of the hierarchy as the root module.
Every module instance has a unique set of child module instances.
If no children, we refer to it as a leaf module.
A design will contain interface declarations, and each of these ma have multiple instances.
Example: an interface declaration I may have one instance $i_1$ for communication between module instances $a_1$ and $b_1$, and another instance $i_2$ for communication between module instances $a_2$ and $b_2$.
Three parts: state, rules, interface.
always
blocks in Verilog)methods
that encapsulate the possible transactions that clients can perform. When compiled into RTL, an interface becomes a collection of wires.Ambiguity in Verilog/SystemVerilog RTL state elements by variables: variable can be mapped into various kind of state elements by a synthesis tool: a bus, a latch, a flip-flop, or even nothing at all.
BSV removes the ambiguity:
all state instances are specified explicitly using module instantiation.
an ordinary declared variable in BSV never implies state, i.e. it never holds a value over time.
An interface contains methods
and subinterfaces as its members.
Each method
represents one kind of transaction between a module and its clients. Will be wires in RTL.
Difference between a method and a function: method also carries implicit condition.
Implicit condition: each method has an implicit ready wire, which governs when it is legal to use it.
one of the major advantages of BSV is that the compiler automatically generates all the control circuitry needed to ensure that a method (transaction) is only used when it is legal to use it. –> any hints to system security forging languages/os/hardware???
A stack of integers:
interface IntStack;
method Action push (int x);
method Action pop;
method int top;
endinterface: IntStack
A stack with polymorphic type:
interface Stack#(type a);
method Action push (a x);
method Action pop;
method a top;
endinterface: Stack
// to use:
typedef Stack#(int) IntStack;
interface ILookup;
interface Server#( RequestType, ResponseType ) mif;
interface RAMclient#( AddrType, DataType ) ram;
method Bool initialized;
endinterface: ILookup
Methods of subinterfaces are accessed using dot notation to select the desired component, e.g.,
ilookup.mif.request.put(...);
mk
convention: make
, suggesting a module definition is not a module instance. When the module is instantiated, one invokes mkFoo
to actually create a module instance.
Parameters –> constants, same as verilog/systemverilog. parameter
to generate Verilog parameter; without parameter
, a Verilog port is generated.
Interfaces –> argument/port; input/output;
Provisos –> type classes (overloading groups).
Examples:
A module with parameter a
and an interface Fifo
:
module mkFifo#(Int#(8) a) (Fifo);
...
endmodule
A module with arguments and an interface, but no parameters:
module mkSyncPulse (Clock sClkIn, Reset sRstIn,
Clock dClkIn,
SyncPulseIfc ifc);
...
endmodule
A module definition with parameters, arguments, and provisos:
module mkSyncReg#(a_type initValue)
(Clock sClkIn, Reset sRstIn,
Clock dClkIn,
Reg#(a_type) ifc)
provisos (Bits#(a_type, sa));
...
endmodule
Can also be written as Parameters and Arguments be combined:
module mkSyncReg (a_type initValue,
Clock sClkIn, Reset sRstIn,
Clock dClkIn,
Reg#(a_type) ifc)
provisos (Bits#(a_type, sa));
...
endmodule
one line form
[attributeInstances] type identifier <- identifier ( [moduleActualParameterArg {, …}]);
each module has an implicit clock and reset. can be changed by explicitly specifying a clocked_by
or reset_by
argument.
interface ArithIO#(type a); //interface type called ArithIO
method Action input (a x, a y); //parameterized by type a
method a output; //contains 2 methods, input and output
endinterface: ArithIO
module mkGCD#(int n) (ArithIO#(bit [31:0]));
... //module definition for mkGCD
... //one parameter, an integer n
endmodule: mkGCD //presents interface of type ArithIO#(bit{31:0])
//declare the interface instance gcdIFC, instantiate the module mkGCD, set n=5
module mkTest ();
...
ArithIO#(bit [31:0]) gcdIfc <- mkGCD (5, clocked_by dClkIn);
...
endmodule: mkTest
module instantiation using a clocked_by
statement:
interface Design_IFC;
method Action start(Bit#(3) in_data1, Bit#(3) in_data2, Bool select);
interface Clock clk_out;
method Bit#(4) out_data();
endinterface : Design_IFC
module mkDesign(Clock prim_clk, Clock sec_clk, Design_IFC ifc);
...
RWire#(Bool) select <- mkRWire (select, clocked_by sec_clk);
...
endmodule:mkDesign
full form on two consecutive lines, similar to SystemVerilog.
First line: identifier with an interface type.
Second line: instantiates the module and defines the interface.
module mkTest (); //declares a module mkTest
... //
ArithIO#(bit [31:0]) gcdIfc(); //declares the interface instance
mkGCD#(5) a_GCD (gcdIfc); //instantiates module mkGCD
... //sets N=5, names module instance a_GCD
endmodule: mkTest //and interface instance gcdIfc
module mkDesign(Clock prim_clk, Clock sec_clk, Design_IFC ifc);
...
RWire#(Bool) select(); // declare
mkRWire t_select(select, clocked_by sec_clk); // instantiate module
...
endmodule:mkDesign
Definition of methods.
Inside a module definition.
method [type] identifier ( methodFormals ) [implicitCond]; functionBody endmethod [: identifier]
Implicit condition:
implicit condition precedes the semicolon that terminates the method definition header.
// the implicite condition
// if false, any rule invokes the method will not be fired.
method ... foo (...) if (expr);
...
endmethod
// a conditonal statement inside the method.
// condition does no prevent the rule being fired.
//
method ... foo (...); if (expr)
...
endmethod
Method body is exactly like a function body.
Example:
interface GrabAndGive; // interface is declared
method Action grab(Bit#(8) value); // method grab is declared
method Bit#(8) give(); // method give is declared
endinterface
module mkExample (GrabAndGive);
Reg#(Bit#(8)) value_reg <- mkReg(?);
Reg#(Bool) not_yet <- mkReg(True);
// method grab is defined
method Action grab(Bit#(8) value) if (not_yet);
value_reg <= value;
not_yet <= False;
endmethod
//method give is defined
method Bit#(8) give() if (!not_yet);
return value_reg;
endmethod
endmodule
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?