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: IntStackA 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: ILookupMethods 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);
...
endmoduleA module with arguments and an interface, but no parameters:
module mkSyncPulse (Clock sClkIn, Reset sRstIn,
Clock dClkIn,
SyncPulseIfc ifc);
...
endmoduleA 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));
...
endmoduleCan 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));
...
endmoduleone 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: mkTestmodule 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:mkDesignfull 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:mkDesignDefinition 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)
...
endmethodMethod 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?