1 / 57

Balsa: A Language Tutorial

Balsa: A Language Tutorial. Dr. Doug Edwards doug@cs.man.ac.uk. Structural Iteration. constant n = 8 procedure buffer_n (input i : word; output o : word) is local array 1 .. n-1 of channel c : word begin buffer (i, c[1]) || -- first buffer buffer (c[n-1], o) || -- last buffer

wynona
Télécharger la présentation

Balsa: A Language Tutorial

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Balsa: A Language Tutorial Dr. Doug Edwards doug@cs.man.ac.uk

  2. Structural Iteration constant n = 8 procedure buffer_n (input i : word; output o : word) is local array 1 .. n-1 of channel c : word begin buffer (i, c[1]) || -- first buffer buffer (c[n-1], o) || -- last buffer for || i in 1 .. n-2 then -- i’th buffer buffer (c[i], c[i+1]) end end declare constant internal arrayed channels compose n-2 internal buffers parallel structural iteration

  3. Micropipeline Buffer procedure buffer (input i : byte; output o : byte) is local variable x : byte begin loop select i then x := i -- store the data end; o <- x end end select “chooses” a single input resulting in input “i” being passive select encloses assignment select statement has enclosed semantics

  4. Examples: Simple Counters • Circuits count handshakes on their I/Ps and produce an O/P count bundle • They illustrate: • strong data typing • data types • arrays, records, enumeration • control structures • if, case • shared procedures

  5. Modulo-16 binary counter procedure count16 (sync aclk; output count : nibble) is local variable count_reg : nibble begin loop sync aclk ; count <- count_reg ; count_reg := ( count_reg + 1 as nibble) end end handshake only input 4-bit output await h/s on input then output count from internal register inc internal register assign result back to internal variable cast result back to correct size

  6. Passive Input Counter procedure count16 (sync aclk; output count : nibble) is local variable count_reg : nibble begin loop count <- count_reg ; select aclk then continue end ; count_reg := ( count_reg + 1 as nibble) end end using select makes aclk a passive i/p

  7. Modulo-10 counter procedure count10(sync aclk; output count: C_size) is local variable count_reg : C_size variable tmp : C_size begin loop sync aclk ; if count_reg /= max_count then tmp := (count_reg + 1 as C_size) else tmp := 0 end || count <- count_reg ; count_reg := tmp end -- loop end end C_size and max_count previously declared temp variable updated in parallel with O/P assignment if  then  else construct

  8. Nested if Statements • Balsa does not have an elseif keyword if condition1 then procA else if condition2 then procB end else procC end • Note the explicit sequencing

  9. Parallel Guard Evaluation • If the guards are mutually exclusive, conditions may be tested in parallel: if condition1 then procA | condition2 then procB else procC end

  10. Loadable Decade Counter -1 • Illustrates record data type: -- count10b.balsa: an aysnchronous loadable decade counter import [balsa.types.basic] public type C_size is nibble constant max_count = 9 type In_bundle is record ld_data : C_size ; ld_ctrl : bit end in-line comment record data-structure definition

  11. Loadable Decade Counter -2 procedure updown10 (input in_sigs: In_bundle; output count: C_size) is local variable count_reg : C_size variable tmp : C_size begin loop -- main procedure body end end body in next slide

  12. Recordselector Recordselector Loadable Decade Counter -3 select in_sigs then if in_sigs.ld_ctrl = 0 then count_reg := in_sigs.ld_data else if count_reg /= max_count then tmp := (count_reg + 1 as C_size) else tmp := 0 end || count <- count_reg ; count_reg := tmp end -- end if end -- complete select H/S load counter enclosed select allows multiple reads from I/P bundlewithout latches increment count or wrap round

  13. Padding Record Structures • Records can be coerced to a fixed length: type Flags is record carry, overflow, zero, negative, int_en: bit over byte Flags is padded to 8 bits

  14. Up/Down Counter • Add another bit to control direction of counting: type C_size is nibble constant max_count = 9 type In_bundle is record ld_data : C_size ; ld_ctrl : bit; dir : bit end direction bit

  15. Up/Down Counter case in_sigs.dir of 0 then -- counting down if count_reg /= 0 then tmp := (count_reg - 1 as C_size) else tmp := max_count end || count <- count_reg | 1 then -- counting up if count_reg /= max_count then tmp := (count_reg + 1 as C_size) else tmp := 0 end || count <- count_reg end ; -- end case statement case statement count down or count up

  16. Enumeration • Up/down control signal could be defined as: type dir is enumeration down, up end • Values may be aliased type opcode is enumeration ADD, ADC, SUB, SBC, AND, OR, LD, ST=LD, BR over 3 bits aliased values

  17. Shared Procedures -1 type inc is 2 signed bits procedure updown10 (input in_sigs: In_bundle; output count: C_size) is local variable count_reg : C_size variable tmp : C_size variable inc : inc -- define shared procedure shared update_ctr is begin tmp := (count_reg + inc as C_size) end -- procedure body inc takes values -1 and +1 use shared hardware for counting up and down shared procedure cast result to correct size inc can be +/- 1

  18. Shared Procedures -2 loop select in_sigs then begin if in_sigs.load_l = 0 then count_reg := in_sigs.ld_data else case in_sigs.dir of down then -- counting down inc := ( -1 as inc); if count_reg /= 0 then update_ctr() else tmp := max_count similar code for count up counting down: set inc to -1 cast required call shared procedure

  19. Arrays • Numerically indexed compositions of the same type • Typical use is in the specification of register banks type RegData is 16 bits variable RegBank : array 0..7 of RegData

  20. Register Bank Definition bundle containing Control info type RegCtrl is record Read0 : RegNo ; Read1 : RegNo ; Write : RegNo ; DoRead0 : bit ; -- if true read port 0 DoRead1 : bit ; -- if true read port 1 DoWrite : bit -- if true write data end procedure RegBank ( input RegCtrl : RegCtrl; input WritePort : RegData ; output ReadPort0, ReadPort1 : RegData ) is local variable RegBank : array 0..7 of RegData Register identifiers read/write control bits Control word write data read data internal registers

  21. Register Bank Control write signalled- await data, then update register await control word loop select RegCtrl then if RegCtrl.DoWrite then select WritePort then RegBank[RegCtrl.Write] := WritePort end else if RegCtrl.DoRead0 then ReadPort0 <- RegBank[RegCtrl.Read0] end || if RegCtrl.DoRead1 then ReadPort1 <- RegBank[RegCtrl.Read1] end end end end two reads can occur together can’t read and write simultaneously read register & output to channel

  22. Array Operations • Arrays can be concatenated variable a, b : byte variable c: array 4 of byte variable d : array 6 of byte c:= {a,b,a,b} -- tuple construction c:= {a,b} @ {a,b} -- array concatenation d:= c @ {a,b}

  23. Array Operations • arrays can be sliced variable x : array 0 ..7 of 4 bits variable y : array 0.. 1 of 4 bits y:= x[1..2] -- returns a slice of x of type-- array 0 .. 1 of 4 bits

  24. Instruction Decoder type Word is 16 signed bits type Imm5 is 5 signed bits variable ICtrl is 8 signed bits -- bottom 5 bits contain an immediate value variable Imm16 : word Im16:= (((ICtrl as array 0..7 of bit)[0..4] as Imm5) as Word) Word and Imm5 are signed bits 5-bit field is extracted & sign-extended to 16 bits

  25. Instruction Decoder type Word is 16 signed bits type Imm5 is 5 signed bits variable ICtrl is 8 signed bits -- bottom 5 bits contain an immediate value variable Imm16 : word Im16:= (ICtrl as array 0..7 of bit) casts Ictrl into an array of bits for slicing

  26. Instruction Decoder type Word is 16 signed bits type Imm5 is 5 signed bits variable ICtrl is 8 signed bits -- bottom 5 bits contain an immediate value variable Imm16 : word Im16:= (ICtrl as array 0..7 of bit)[0..4] extract bottom 5 bits

  27. Instruction Decoder type Word is 16 signed bits type Imm5 is 5 signed bits variable ICtrl is 8 signed bits -- bottom 5 bits contain an immediate value variable Imm16 : word Im16:= ((ICtrl as array 0..7 of bit)[0..4] as Imm5) cast the extracted bits into a 5-bit signed number

  28. Instruction Decoder type Word is 16 signed bits type Imm5 is 5 signed bits variable ICtrl is 8 signed bits -- bottom 5 bits contain an immediate value variable Imm16 : word Im16:= (((ICtrl as array 0..7 of bit)[0..4] as Imm5) as Word) sign-extend the 5-bit number to 16 bits

  29. The Select Statement • MUX: • Illustrates unbuffered choice • Inputs assumed mutually exclusive • No internal latches procedure mux (input a, b :byte; output c :byte) is begin loop select a then c <- a -- channel behaves like a variable | b then c <- b -- ditto end end end select gives choice

  30. Arbitrated Choice public procedure mux (input a, b :byte; output c :byte) is begin loop arbitrate a then c <- a | b then c <- b end end end arbitrated choice

  31. Parameterised Procedures • Facilitates libraries • Ex: buffer with parameterised width procedure Buffer ( parameter X : type ; input i : X; output o : X) is local variable x : X begin loop i -> x ; o <- x end end X is of type type vars defined in terms of parameterised type

  32. Using Parameterised Modules -- pbuffer1a.balsa - calling parameterised a procedure import [balsa.types.basic] import [pbuffer1] public -- instantiate a byte-wide single place buffer procedure test (input a :byte ; output b : byte) is begin Buffer over type byte of a,b end invoke a buffer of width byte Buffer defined previously

  33. Multiple Parameters -1 • Consider a pipeline • with parameterised width • with parameterised depth -- BufferN: a n-place parameterised, variable width buffer procedure BufferN( parameter n : cardinal ; parameter X : type ; input i : X ; output o : X) is local procedure buffer is Buffer over type X begin -- body of procedure end type cardinal ranges over natural numbers

  34. test for special cases test for special cases Multiple Parameters -2 if n = 1 then -- single place pipeline buffer(i, o) | n >= 2 then local array 1 .. n-1 of channel c : X begin buffer(i, c[1]) || -- first buffer buffer(c[n-1], o) || -- last buffer for || i in 1 ..n-2 then buffer(c[i], c[i+1]) end end else print error, “zero length pipeline specified” end Procedure Buffer8 is BufferN over 4, type byte body of procedure define a 4-deep byte-wide pipeline

  35. Recursive Procedures • Adding recursion to Balsa allows elegant specifications of many circuits • Consider circuit to generate n handshakes for each call • Divide circuit into odd and even cases • even case: call itself twice • odd case : issue preliminary h/s and then call itself twice

  36. Handshake Generator -1 procedure Repeat (parameter n : cardinal; sync o ) is begin if n = 0 then print error, “Repeat n must not be 0” | n = 1 then sync o | n = 2 then sync o ; sync o else -- main body of procedure end procedure name “repeat” base cases recursive definition here

  37. Handshake Generator -2 local shared doNext is begin Repeat over n/2 of (o) end begin if (n as bit) then -- n is odd sync o end ; doNext () ; doNext () end end Procedure Gen5 is Repeat over 5 define local shared procedure recursive call of “repeat” call shared procedure twice define a 5x generator

  38. Handshake Multiplier -- MultHS: repeat: handshake on `o’ `n’ times for each input import [balsa.types.basic] import [GenHS] public procedure MultHS (parameter n : cardinal; sync i ; sync o ) is begin loop select i then continue end ; Repeat over n of (o) end end -- Here is a x5 gnerator procedure MultHS5 is MultHS over 5 procedure repeat defined earlier

  39. An n-way multiplexer • Decompose MUX:

  40. An n-way multiplexer -1 -- Pmux1.balsa: A recursive parameterised MUX definition import [balsa.types.basic] public procedure PMux ( parameter X : type; parameter n : cardinal; array n of input inp : X; output out : X ) is begin -- procedure body width of input number of inputs each input is a channel output channel

  41. An n-way multiplexer -2 if n = 0 then print error,”Parameter n should not be zero” | n = 1 then loop select inp[0] -> inp then out <- inp end end | n = 2 then loop select inp[0] -> inp then out <- inp | inp[1] -> inp then out <- inp end end when data arrives on either i/p, pass it to o/p base cases

  42. An n-way multiplexer -3 else local channel out0, out1 : X constant mid = n/2 begin PMux over type X, mid of inp[0..mid-1],out0 || PMux over type X, n-mid of inp[mid..n-1],out1 || PMux over type X, 2 of {out0,out1},out end end end 2 internal channels two half-size muxs & one 2:1 mux

  43. Systolic Counters -1 • Kees van Berkel’s design: • Recursively split counter into a head cell & a n/2 tail cell • Head cells may be be odd or even counts

  44. Systolic Counters -2 • Example: • A modulo-11 counter may be constructed 11 = 1 + 2 * 5 11 = 1 + 2 * (1 + 2 * 2) 11 = 1 + 2 * (1 + 2 * (2 * 1))

  45. Systolic Counters -3 • Count even cell: procedure c_even(sync a_left, a_right, b_left, b_right) is begin loop select a_right then sync a_left ; sync a_left | b_right then sync b_left end end end Choose between a or b h/s on right if a then double else pass b from right to left

  46. Systolic Counters -4 • Count odd cell procedure c_odd(sync a_left, a_right, b_left, b_right) is begin loop sync a_left; select a_right then sync a_left | b_right then sync b_left end end end first h/s on left then choose bewteen a & b and pass on

  47. Systolic Counters -5 • Base case: count 1 cell procedure c_1(sync a, b) is begin loop sync a; sync b end end copy handshake from a to b

  48. Systolic Counters -6 procedure countN (parameter N : cardinal ; sync a, b) is local sync a_int, b_int begin if N = 0 then print error, “Parameter n should not be zero” | N = 1 then c_1(a, b) else if (N as bit) then -- Odd c_odd(a, a_int, b, b_int) else c_even(a, a_int, b, b_int) end || countN over N/2 of a_int, b_int end end -- OK instantiate an arbitrary counter procedure Ctest is countN over 53 2 internal sync- only channels plant either an odd or even channel this is how we use use the counter definition and compose with remainder of counter

  49. Systolic Counters -7 • The count even cell chooses between a and b with a handshake on its right

  50. Count-Even cell • Count even cell: procedure c_even(sync a_left, a_right, b_left, b_right) is begin loop select a_right then sync a_left ; sync a_left | b_right then sync b_left end end end handshake right encloses rest of handshakes

More Related