470 likes | 598 Views
Constructive Computer Architecture Tutorial 1 BSV Types Andy Wright 6.175 TA. Constructive Computer Architecture Sequential Circuits - 2 Arvind Computer Science & Artificial Intelligence Lab. Massachusetts Institute of Technology. Sequential Circuit for Multiply.
E N D
Constructive Computer Architecture Tutorial 1 BSV Types Andy Wright 6.175 TA http://csg.csail.mit.edu/6.175
Constructive Computer Architecture Sequential Circuits - 2 Arvind Computer Science & Artificial Intelligence Lab. Massachusetts Institute of Technology http://csg.csail.mit.edu/6.175
Sequential Circuit for Multiply Reg#(Bit#(32)) a <- mkRegU(); Reg#(Bit#(32)) b <- mkRegU(); Reg#(Bit#(32)) prod <-mkRegU();Reg#(Bit#(32)) tp <- mkReg(0); Reg#(Bit#(6)) i <- mkReg(32); rule mulStep if (i < 32); Bit#(32) m = (a[i]==0)? 0 : b; Bit#(33) sum = add32(m,tp,0); prod[i] <= sum[0];tp <= sum[32:1]; i <= i+1;endrule http://csg.csail.mit.edu/6.175
Sequential Circuit for Multiply Reg#(Bit#(32)) a <- mkRegU(); Reg#(Bit#(32)) b <- mkRegU(); Reg#(Bit#(32)) prod <-mkRegU();Reg#(Bit#(32)) tp <- mkReg(0); Reg#(Bit#(6)) i <- mkReg(32); rule mulStep if (i < 32); Bit#(32) m = (a[i]==0)? 0 : b; Bit#(33) sum = add32(m,tp,0); prod[i] <= sum[0];tp <= sum[32:1]; i <= i+1;endrule Dynamic selection http://csg.csail.mit.edu/6.175
Dynamic selection requires a mux i when the selection indices are regular then it is better to use a shift operator (no gates!) a[i] a >> a a[0],a[1],a[2],… 0 http://csg.csail.mit.edu/6.175
Replacing repeated selections by shifts Reg#(Bit#(32)) a <- mkRegU(); Reg#(Bit#(32)) b <- mkRegU(); Reg#(Bit#(32)) prod <-mkRegU();Reg#(Bit#(32)) tp <- mkReg(0); Reg#(Bit#(6)) i <- mkReg(32); rule mulStep if (i < 32); Bit#(32) m = (a[0]==0)? 0 : b; a <= a >> 1; Bit#(33) sum = add32(m,tp,0); prod <= {sum[0], prod[31:1]};tp <= sum[32:1]; i <= i+1;endrule http://csg.csail.mit.edu/6.175
Replacing repeated selections by shifts Reg#(Bit#(32)) a <- mkRegU(); Reg#(Bit#(32)) b <- mkRegU(); Reg#(Bit#(32)) prod <-mkRegU();Reg#(Bit#(32)) tp <- mkReg(0); Reg#(Bit#(6)) i <- mkReg(32); rule mulStep if (i < 32); Bit#(32) m = (a[0]==0)? 0 : b; a <= a >> 1; Bit#(33) sum = add32(m,tp,0);prod <= {sum[0], prod[31:1]};tp <= sum[32:1]; i <= i+1;endrule Just like dynamic selection optimization, but with dynamic insertion instead http://csg.csail.mit.edu/6.175
Circuit for Sequential Multiply bIn aIn s1 b 0 0 << 0 s1 +1 add << s1 s1 0 32:1 [30:0] 31 prod a i tp s2 s2 s2 s2 31:0 0 == 32 done result (high) result (low) s1 = start_en s2 = start_en | !done http://csg.csail.mit.edu/6.175
Circuit analysis • Number of add32 circuits has been reduced from 31 to one, though some registers and muxes have been added • The longest combinational path has been reduced from 62 FAs to to one add32 plus a few muxes • The sequential circuit will take 31 clock cycles to compute an answer http://csg.csail.mit.edu/6.175
Observations • These programs are not very complex and yet it would have been tedious to express these programs in a state table or as a circuit directly • BSV method calls are not available in Verilog/VHDL, and thus such programs sometimes require tedious programming • Even the meaning of double-write errors is not standardized across tool implementations in Verilog http://csg.csail.mit.edu/6.175
A subtle problem while(!isDone(x)) { x = doStep(x); } doStep workQ done ? doneQ let x = workQ.first; workQ.deq; if (isDone(x)) begin doneQ.enq(x); end else begin workQ.enq(doStep(x)); end Double write problem for 1-element Fifo stay tuned! http://csg.csail.mit.edu/6.175
Constructive Computer Architecture Tutorial 1 BSV Types Andy Wright 6.175 TA http://csg.csail.mit.edu/6.175
Bit#(numeric type n) • The most important type in BSV • We’ll go into the details later http://csg.csail.mit.edu/6.175
Bit#(numeric type n) • Literal values: • Decimal: 0, 1, 2, … (each have type Bit#(n) • Binary: 5’b01101 (13 with type Bit#(5)),2’b11 (3 with type Bit#(2)) • Hex: 5’hD, 2’h3, 16’h1FF0 • Common functions: • Bitwise Logic: |, &, ^, ~, etc. • Arithmetic: +, -, *, %, etc. • Indexing: a[i] • Concatenation: {a, b} http://csg.csail.mit.edu/6.175
Bool • Literal values: • True, False • Common functions: • Boolean Logic: ||, &&, !, ==, !=, etc. • All comparison operators (==, !=, >, <, >=, <=) return Bools http://csg.csail.mit.edu/6.175
Int#(n), UInt#(n) • Literal values: • Decimal: • 0, 1, 2, … (Int#(n) and UInt#(n)) • -1, -2, … (Int#(n)) • Common functions: • Arithmetic: +, -, *, %, etc. (Int#(n) performs signed operations, UInt#(n) performs unsigned operations) • Comparison: >, <, >=, <=, ==, !=, etc. http://csg.csail.mit.edu/6.175
Constructing new types • Renaming types: • typedef • Enumeration types: • enum • Compound types: • struct • vector • maybe • tagged union http://csg.csail.mit.edu/6.175
typedef • Syntax: • typedef <type> <new_type_name>; • Basic: • typedef 8 BitsPerWord; • typedef Bit#(BitsPerWord) Word; • Can’t be used with parameter: Word#(n) • Parameterized: • typedef Bit#(TMul#(BitsPerWord,n)) Word#(n); • Can’t be used withoutparameter: Word http://csg.csail.mit.edu/6.175
enum typedefenum{red, blue} Color deriving (Bits, Eq); • Creates the type Color with values red and blue • Can create registers containing colors • Reg#(Color) • Values can be compared with == and != http://csg.csail.mit.edu/6.175
struct typedefstruct { Bit#(12) address; Bit#(8) data; Boolwrite_en; } MemReq deriving (Bits, Eq); • Elements from MemReq x can be accessed with x.address,x.data,x.write_en http://csg.csail.mit.edu/6.175
Tuples • Types: • Tuple2#(type t1, type t2) • Tuple3#(type t1, type t2, type t3) • up to Tuple8 • Values: • tuple2( x, y ), tuple3( x, y, z ), … • Accessing an element: • tpl_1( tuple2(x, y) ) = x • tpl_2( tuple3(x, y, z) ) = y • … http://csg.csail.mit.edu/6.175
Vector • Type: • Vector#(numeric type size, type data_type) • Values: • newVector(), replicate(val) • Functions: • Access an element: [] • Rotate functions • Advanced functions: zip, map, fold • Can contain registers or modules • Must have ‘import Vector::*;’ in BSV file http://csg.csail.mit.edu/6.175
Maybe#(t) • Type: • Maybe#(type t) • Values: • tagged Invalid • tagged Valid x (where x is a value of type t) • Functions: • isValid(x) • Returns true if x is valid • fromMaybe(default, m) • If m is valid, returns the valid value of m if m is valid, otherwise returns default • Commonly used fromMaybe(?, m) http://csg.csail.mit.edu/6.175
tagged union • Maybe is a special type of tagged union typedefunion tagged { void Invalid; t Valid; } Maybe#(type t) deriving (Eq, Bits); • Tagged unions are collections of types and tags. The type contained in the union depends on the tag of the union. • If tagged Valid, this type contains a value of type t http://csg.csail.mit.edu/6.175
tagged union – Continued • Values: • tagged <tag> value • Pattern matching to get values: case (x) matches tagged Valid .a : return a; tagged Invalid : return 0; endcase • See BSV Reference Guide (on course website) for more examples of pattern matching http://csg.csail.mit.edu/6.175
Reg#(t)State element of BSV • Main state element in BSV • Type: Reg#(type data_type) • Instantiated differently from normal variables • Uses <- notation • Written to differently from normal variables • Uses <= notation • Can only be done inside of rules and methods Reg#(Bit#(32)) a_reg <- mkReg(0) // value set to 0 Reg#(Bit#(32)) b_reg <- mkRegU() // uninitialized // write to b_reg (needs to be done inside rule) b_reg <= 7; http://csg.csail.mit.edu/6.175
Reg and Vector • Register of Vectors • Reg#( Vector#(32, Bit#(32) ) ) rfile; • rfile <- mkReg( replicate(0) ); • Vector of Registers • Vector#( 32, Reg#(Bit#(32)) ) rfile; • rfile <- replicateM( mkReg(0) ); • Each has its own advantages and disadvantages http://csg.csail.mit.edu/6.175
Partial Writes • Reg#(Bit#(8)) r; • r[0] <= 0 counts as a read and write to the entire register r • let r_new = r; r_new[0] = 0; r <= r_new • Reg#(Vector#(8, Bit#(1))) r • Same problem, r[0] <= 0 counts as a read and write to the entire register • r[0] <= 0; r[1] <= 1 counts as two writes to register r – double write problem • Vector#(8,Reg#(Bit#(1))) r • r is 8 different registers • r[0] <= 0 is only a write to register r[0] • r[0] <= 0 ; r[1] <= 1 is not a double write problem http://csg.csail.mit.edu/6.175
Modules • Modules are building blocks for larger systems • Modules contain other modules and rules • Modules are accessed through their interface • module mkAdder( Adder#(32) ); • Adder#(32) is the interface http://csg.csail.mit.edu/6.175
Interfaces • Interfaces contain methods for other modules to interact with the given module • Interfaces can also contain other interfaces interface MyInterface#(numeric type n); method ActionValue#(Bit#(b)) f(); interface SubInterfaces; endinterface http://csg.csail.mit.edu/6.175
Interface Methods • Method • Returns value, doesn’t change state • method Bit#(32) peek_at_front(); • Action • Changes state, doesn’t return value • method Action enqueue(); • ActionValue • Changes state, returns value • method ActionValue#(Bit#(32)) dequeue_front() http://csg.csail.mit.edu/6.175
Strong Typing • The Bluespec Compiler throws errors if it can’t figure out a type • Which of the following lines work? Bit#(32) a = 7; Bit#(8) small_b = 3; let b = zeroExtend( small_b ); let a_plus_b = a + b; Bit#(8) b_plus_fifty_truncated = truncate( b + 50 ); http://csg.csail.mit.edu/6.175
Quiz http://csg.csail.mit.edu/6.175
Question 1 • What is the type of a? Bit#(n) x = 1; Bit#(m) y = 3; let a = {x,y}; Bit#(TAdd#(n,m)) http://csg.csail.mit.edu/6.175
Question 2 • What is the type of b? Bit#(n) x = 1; Bit#(m) y = 3; let a = {x,y}; let b = x + y; Type Error! + expects inputs and outputs to all have the same type http://csg.csail.mit.edu/6.175
Question 2 – BSC Error Error: “File.bsv”, line 10, column 9: … Type error at: y Expected type: Bit#(n) Inferred type: Bit#(m) http://csg.csail.mit.edu/6.175
Question 3 • What is the type of c? Bit#(8) x = 9; let c = x[0]; Bit#(1) http://csg.csail.mit.edu/6.175
Question 4 • What is the type of d? Bit#(8) x = 9; let d = zeroExtend(x); Can’t tell, so the compiler gives a type error http://csg.csail.mit.edu/6.175
Question 5 • What does this function do? How does it work? function Bit#(m) resize(Bit#(n) x) Bit#(m) y = truncate(zeroExtend(x)); return y; endfunction Produces a compiler error! zeroExtend(x) has an unknown type http://csg.csail.mit.edu/6.175
Question 5 – Fixed function Bit#(m) resize(Bit#(n) x) Bit#(TMax#(m,n)) x_ext; x_ext = zeroExtend(x); Bit#(m) y = truncate(x_ext); return y; endfunction http://csg.csail.mit.edu/6.175
Question 6 • What does this code do? // mainQ, redQ, blueQare FIFOs // redC, blueC let x = mainQ.first; mainQ.deq; if( isRed(x) ) redQ.enq(x); redC <= redC + 1; if( isBlue(x) ) blueQ.enq(x); blueC <= blueC + 1; Not what it looks like http://csg.csail.mit.edu/6.175
Question 6 – Rewritten let x = mainQ.first; mainQ.deq; if( isRed(x) ) redQ.enq(x); redC <= redC + 1; if( isBlue(x) ) blueQ.enq(x); blueC <= blueC + 1; Only the first action/expression after the if is done, that’s why we have begin/end http://csg.csail.mit.edu/6.175
Question 6 – Fixed let x = mainQ.first; mainQ.deq; if( isRed(x) ) begin redQ.enq(x); redC <= redC + 1; end if( isBlue(x) ) begin blueQ.enq(x); blueC <= blueC + 1; end http://csg.csail.mit.edu/6.175
Why is Bit#(n) so important? • Bit#(n) is the only type that can be synthesized as a set of wires • Other types are synthesizable only if they can be converted to Bit#(n) • How do you keep track of types that can be converted to Bit#(n)? • Typeclasses! (specifically the Bits#(t) typeclass) http://csg.csail.mit.edu/6.175
Bits#(a,n) typeclass typeclass Bits#(type a, type n); function Bit#(n) pack(a x); function a unpack(Bit#(n) y); endtypeclass If there is an instance of the typeclassBits#(mytype, n), then mytype can be converted to Bits#(n) using pack. Furthermore, mytype can be stored in a register of type Reg#(mytype) http://csg.csail.mit.edu/6.175
Bits#(a,n) instance typedefenum { red, green, blue } Color deriving (Eq); // but not bits instance Bits#(Color, 2); function Bit#(2) pack(a x); if( x == red ) return 0; else if( x == green ) return 1; else return 2; function Color unpack(Bit#(2) y) if( x == 0 ) return red; else if( x == 1 ) return green; else return blue; endfunction endinstance http://csg.csail.mit.edu/6.175
Typeclasses • Typeclasses allow polymorphism across types • Examples: • Eq: contains == and != • Ord: contains <, >, <=, >=, etc. • Bits: contains pack and unpack • Arith: contains arithmetic functions • Bitwise: contains bitwise logic http://csg.csail.mit.edu/6.175