Skip to content

Latest commit

 

History

History
241 lines (181 loc) · 4.64 KB

BluespecQuickReference.md

File metadata and controls

241 lines (181 loc) · 4.64 KB

Bluespec Quick Reference

A heavily abbreviated Bluespec reference accompanying the Intro Guide. Covers more basic syntax than the Bluespec Reference Card (which doesn't even have for loops?)

Comments

// single line comment
/* multiline
comment */

Types

Bit#(n)
Int#(n)  // signed
Uint#(n) // unsigned
Integer  // static elaboration only
Bool

Action
ActionValue#(t)
Rules
Tuple2#(t1, t2) ... Tuple7#(t1,..., t7)

Values

0       // constant zero
42      // decimal 42 of arbitrary size
'1      // Enough 1 bits to fill the needed width
4'b1010 // 4-bit value 1010 in binary

True    // Bool
False   // Bool

Operators and Built-In Functions

If a and b are variables of type Bit#(n), expressions include:

a & b   a | b   a ^ b   ~a

a + b   a - b   a * b   a / b   a % b

a << b  a >> b

{a, b}  // Bit concatenation
a[0]    // Bit indexing (0 is the least significant bit, i.e. the right!)
a[7:0]  // Bit slicing (inclusive of both indices, so this has 8 bits)

// Add or remove bits from the left; you may need to put them into a variable
// with explicitly declared type
signExtend(a) zeroExtend(a) truncate(a)

// Comparisons give values of type Bool
a == b  a != b  a < b   a > b   a <= b  a >= b

If p and q are variables of type Bool, expressions include:

p && q  p || q  !p

p ? a : b

If i is an Integer, you can use fromInteger(i) to convert it to a Bits#(n)

pack converts from various types to Bit#(n), unpack converts from Bit#(n) to various types.

Type-Level Operations

Type-level      Equivalent math
TAdd#(a, b)     a + b
TSub#(a, b)     a - b
TMul#(a, b)     a * b
TDiv#(a, b)     ceiling(a / b)
TLog#(a)        ceiling(log_2 a)
TExp#(a)        2^a (2 to the power of a, not 2 xor a)
TMax#(a, b)     max(a, b)
TMin#(a, b)     min(a, b)

If a is a numeric type, you can use valueOf(n) to convert it to an Integer.

Variable Declarations

Bit#(3) a = 7;  // a has explicit type Bit#(3)
let b = {a, a}; // type of b is inferred

Tuples

Tuple2#(Bit#(1), Bit#(2)) pair = tuple2(1, 0);

Bit#(1) first = tpl_1(pair);
Bit#(2) second = tpl_2(pair);
// or
match {.first, .second} = pair;

Structs

typedef struct {
    Bit#(1) foo;
    Bit#(2) bar;
} NewType;

NewType myNewVar = NewType{foo: 1, bar: 2};

let newFoo = myNewVar.foo;
let newBar = myNewVar.bar;
// or
match tagged NewType {foo: .newFoo, bar: .newBar} = myNewVar;

Enums

typedef enum Color { Red, Green, Yellow, Blue } deriving (Bits, Eq);
Color color = Red;

Control Flow

if (condition) begin
    x = 5;
end

for (Integer i = 0; i < max; i = i + 1) begin
    do_something();
end

Switch

case (someValue)
    1: do1();
    2: do2();
    default: do3();
endcase

let foo = case (someValue)
    1: bar;
    2: baz;
    default: quux;
endcase;

Functions

function ReturnType fnName(Type var1, Type var2); // semicolon!
    some_stuff();
    return other_stuff();
endfunction

Modules

interface MyInterface;
    method Action myAction(Bit#(1) flag);
    method ActionValue#(Bool) getMyResult;
endinterface

module mkMyModule(MyInterface);
    Reg#(Bool) myReg <- mkRegU;

    rule doSomething;
        do_some_stuff();
    endrule

    method Action myAction(Bit#(1) flag) if (myReg);
        do_some_other_stuff();
    endmethod

    method ActionValue#(Bool) getMyResult if (!myReg);
        return True;
    endmethod
endmodule

Registers

In a module, outside rules and methods, use <- to create registers and modules.

Reg#(Bit#(1)) myReg <- mkRegU();
Reg#(Bool) myRegFlag <- mkReg(False);

In a module rule or method, use <- to perform ActionValues.

let result <- someModule.someMethod(someArg);

In a module rule or method, use <= to write into registers. Reading from registers is implicit.

myReg <= 1; // write 1 to x

Module Example

interface Tripler;
    method Action start(Bit#(32) n);
    method ActionValue#(Bit#(32)) getResult;
endinterface

module mkTripler(Tripler);
    Reg#(Bit#(32)) x <- mkRegU;
    Reg#(Bit#(32)) y <- mkRegU;
    Reg#(Bool) busy <- mkReg(False);
    rule tripleStep if (busy && x > 0);
        x <= x - 1;
        y <= y + 3;
    endrule
    method Action start(Bit#(32) n) if (!busy);
        x <= n;
        y <= 0;
        busy <= True;
    endmethod
    method ActionValue#(Bit#(32)) getResult if (busy && x == 0);
        busy <= False;
        return y;
    endmethod
endmodule