Overview
In hardware design one frequently has the following situation:
- A value of some type t
- An accompanying valid bit indicating whether the value is meaningful or not.
The BSV library provides the type Maybe#(t) for this situation. The Maybe type is used for tagging values as either Valid or Invalid. If the value is Valid, the value contains a datatype data_t.
Syntax
typedef union tagged { void Invalid; data_t Valid; } Maybe #(type data_t) deriving (Eq, Bits);
Invalid and Valid are the tags of the Maybe type.
Tagged Union representation of Maybe
In hardware, a Maybe is one bit longer than the record type.
Hardware representation of Maybe
Example
Maybe#(int) m1 = tagged Valid 23; //valid bit True, value 23 Maybe#(int) m2 = tagged Invalid; //valid bit False, value unspecified
m2 = m1; // sets m2 valid and 23
Functions
Two functions are provided in the BSV Library:
- isValid
- Returns True if the Maybe argument is Valid
function Bool isValid( Maybe#(data_t) val ) ;
if (isValid(x)) // if x is Valid, a is set to the value of x a = x;
- fromMaybe
- Extracts the Valid value from a Maybe argument. If the tag is Invalid, a default value is returned.
function data_t fromMaybe( data_t defaultval, Maybe#(data_t) val ) ;
x = fromMaybe (0, m1); //if m1 is Valid, m1 is returned. Otherwise, 0 is returned.
Usage Tips
Check validity for condition while retrieving the value
The following example checks the validity of m while retrieving the value:
rule fifoValid (m matches type Valid.d); x <= d;
This technique should also be used in if statements and method conditions.
Just check the tag if the rule fires only when notValid
If the rule condition is notValid, it is better to just look at the tag, than compare to the returned value:
rule checkvalid (!isValid(m))); //GOOD
rule checkvalid (m == Invalid); //NOT GOOD - can get errors if m is not in the correct class
Use fromMaybe to implement an if/else based on validity
If m is Valid, dout is set to m. If m is Invalid, dout is set to 0:
dout = fromMaybe (0, m) ; //BEST
if (m matches tagged Valid .d) //OK dout = d;
if (isValid(m)) dout = validValue (m); else dout = 0; // Worst
|