128
Bluespec TM SystemVerilog Version 3.8 Reference Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. Copyright c 2004 Bluespec, Inc. Revision: April 5, 2004 L A T E X’d April 5, 2004 1

BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

  • Upload
    lengoc

  • View
    218

  • Download
    0

Embed Size (px)

Citation preview

Page 1: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

BluespecTM SystemVerilog

Version 3.8

Reference Guide

Preliminary Draft

Please do not circulate without permission from Bluespec, Inc.

Copyright c© 2004 Bluespec, Inc.

Revision: April 5, 2004LATEX’d April 5, 2004

1

Page 2: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Trademarks and copyrights

Verilog is a trademark of IEEE (the Institute of Electrical and Electronics Engineers). The Verilogstandard is copyrighted, owned and maintained by IEEE.

VHDL is a trademark of IEEE (the Institute of Electrical and Electronics Engineers). The VHDLstandard is copyrighted, owned and maintained by IEEE.

SystemVerilog is a trademark of Accellera, Inc. The SystemVerilog standard is owned and maintainedby Accellera.

Glurph is a trademark of Foobar Bric-a-brac, Inc., Purveyors of Fine Programming Curiosities since1976, by Appointment to His Boundless Computation Count F = Y F (“yuffy” to His Auxiliaries).

2

Page 3: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Contents

1 Introduction 9

1.1 Meta notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2 Lexical elements 9

2.1 Whitespace and comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.2 Identifiers and keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.3 Integer literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.3.1 Type conversion of integer literals . . . . . . . . . . . . . . . . . . . . . . . . 11

2.4 Real literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.5 String literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.6 “Don’t care” values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.7 Compiler directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3 Packages and the outermost structure of a BSV design 12

3.1 Name clashes and qualified identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2 The Standard Prelude . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4 Types 13

4.1 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4.2 Provisos (brief intro) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4.3 deriving clauses (brief intro) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5 Modules and interfaces and their instances 16

5.1 Explicit state via module instantiation, not variables . . . . . . . . . . . . . . . . . . 17

5.2 Interface declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.3 Module declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5.4 Module and interface instantiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5.5 Interface definition (definition of methods) . . . . . . . . . . . . . . . . . . . . . . . . 20

5.6 Rules in module definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.7 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

6 Static and dynamic semantics 24

6.1 Static semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

6.1.1 Type checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

6.1.2 Proviso checking and bit-width constraints . . . . . . . . . . . . . . . . . . . 25

6.1.3 Static elaboration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6.2 Dynamic semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6.2.1 Reference semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

6.2.2 Mapping into efficient parallel clocked synchronous hardware . . . . . . . . . 27

3

Page 4: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

7 User-defined types (type definitions) 29

7.1 Type synonyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

7.2 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

7.3 Structures and tagged unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

8 Variable declarations and statements 32

8.1 Register reads and writes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

8.2 Variable and array declaration, initialization and assignment . . . . . . . . . . . . . 33

8.3 begin-end statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

8.4 Conditional and loop statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

8.5 Function definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

9 Expressions 36

9.1 Don’t-care expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

9.2 Conditional operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

9.3 Unary and binary operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

9.4 Bit concatenation and selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

9.5 begin-end expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

9.6 Action blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

9.7 ActionValue blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

9.8 Function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

9.9 Static type assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

9.10 Structure and union expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

9.10.1 Structure expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

9.10.2 Structure member selection and update . . . . . . . . . . . . . . . . . . . . . 43

9.10.3 Tagged union expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

9.10.4 Union member selection and update . . . . . . . . . . . . . . . . . . . . . . . 44

9.11 Interface expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

9.11.1 Differences between interfaces and structures . . . . . . . . . . . . . . . . . . 46

9.12 Rule expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

9.12.1 Aggregating and prioritizing rules . . . . . . . . . . . . . . . . . . . . . . . . 47

10 Pattern matching 47

10.1 Case statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4

Page 5: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

11 Important Primitives 49

11.1 The types bit and Bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

11.1.1 Bit-width compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

11.2 UInt, Int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

11.3 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

11.4 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

11.5 FIFOs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

11.6 FIFOFs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

11.7 System tasks and functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

11.7.1 System tasks for displaying information . . . . . . . . . . . . . . . . . . . . . 53

11.7.2 System tasks for stopping simulation . . . . . . . . . . . . . . . . . . . . . . . 54

11.7.3 System tasks for VCD dumping . . . . . . . . . . . . . . . . . . . . . . . . . . 54

11.7.4 System functions returning the current time . . . . . . . . . . . . . . . . . . . 54

12 Guiding The Compiler With Pragmas And Assertions 54

12.1 Pragmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.1 Pragma synthesize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.2 Pragma RSTN= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.3 Pragma CLK= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.4 Pragma bit_blast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.5 Pragma scan_insert= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

12.1.6 Pragma always_enabled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.1.7 Pragma always_ready . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.1.8 Pragma RDY= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.1.9 Pragma EN= . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.1.10Pragma noinline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.2 Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

12.2.1 Assertion fire_when_enabled . . . . . . . . . . . . . . . . . . . . . . . . . . 57

12.2.2 Assertion no_implicit_conditions . . . . . . . . . . . . . . . . . . . . . . . 57

13 Advanced topics 57

13.1 Type classes (overloading groups) and provisos . . . . . . . . . . . . . . . . . . . . . 57

13.1.1 Provisos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

13.1.2 Type class declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

13.1.3 Declarations of type class instances . . . . . . . . . . . . . . . . . . . . . . . . 60

13.1.4 The Bits type class (overloading group) . . . . . . . . . . . . . . . . . . . . . 60

13.1.5 Deriving Bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

13.1.6 Deriving Eq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

5

Page 6: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

13.1.7 Deriving Bounded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

13.1.8 Deriving for isomorphic types . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

13.2 Higher-order functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

13.3 Calling foreign functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

14 Interfacing to Verilog 65

15 Interfacing to C 65

A Keywords 67

B The standard Prelude 68

B.1 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

B.2 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

B.2.1 Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

B.2.2 Bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

B.2.3 Bool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

B.2.4 Empty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

B.2.5 Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

B.2.6 Maybe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

B.2.7 Nat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

B.2.8 Either . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

B.2.9 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

B.2.10 Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

B.2.11 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

B.2.12 Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

B.3 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

C Libraries 77

C.1 ActionSeq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

C.2 Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

C.3 ArrayFile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

C.4 Assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

C.5 BGetPut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

C.6 BitonicSort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

C.7 Boolify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

C.8 ClientServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

C.9 CGetPut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

C.10 ClockConv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

6

Page 7: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.11 CompletionBuffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

C.12 ConfigReg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

C.13 Connectable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

C.14 Enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

C.15 Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

C.16 EqFunction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

C.17 FIFO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

C.18 FIFOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

C.19 FileIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

C.20 Fork . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

C.21 GetPut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

C.22 IVec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

C.23 LFSR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

C.24 List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

C.25 ListFIFO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

C.26 ListN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

C.27 ListReg . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

C.28 LocalBus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

C.28.1 Creating registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

C.28.2 Collecting registers together . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

C.29 Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

C.30 ModuleCollect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

C.31 Monad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

C.32 OInt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

C.33 Once . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

C.34 PopCount . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

C.35 Pull . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

C.36 Push . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

C.37 RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

C.37.1 RAM and TRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

C.37.2 SyncSRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

C.37.3 SRAM and TSRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

C.37.4 SPSRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

C.37.5 DPSRAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

C.37.6 SRAMFile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

C.38 Reserved . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

C.39 RPush . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

7

Page 8: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.40 RWire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

C.41 Stmts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

C.41.1 Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

C.41.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

C.41.3 Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

C.41.4 State machine interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

C.41.5 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

C.42 Tabulate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

C.43 UIntRange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

C.44 Wallace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

8

Page 9: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

1 Introduction

Bluespec SystemVerilog (BSV) is aimed at hardware designers who are using or expect to use Verilog[IEE01], VHDL [IEE02], or SystemVerilog [Acc04] to design ASICs or FPGAs. BSV uses a syn-thesizable subset of SystemVerilog, including SystemVerilog types, modules, module instantiation,interfaces, interface instantiation, parameterization, static elaboration, and “generate” elaboration.BSV can significantly improve the hardware designer’s productivity with some key innovations:

• Synthesizable behavior is expressed with Rules (also called Design Assertions) instead of syn-chronous always blocks. Rules are powerful concepts for achieving correct concurrency andeliminating race conditions. Each rule can be viewed as a declarative assertion expressing apotential atomic state transition. Although rules are expressed in a modular fashion, a rulemay span multiple modules, i.e., it can test and affect the state in multiple modules. Rulesneed not be disjoint, i.e., two rules can read and write common state elements. The BSV com-piler produces efficient RTL code that manages all the potential interactions between rules byinserting appropriate arbitration and scheduling logic, logic that would otherwise have to bedesigned and coded manually. The atomicity of rules gives a scalable way to avoid unwantedconcurrency (races) in large designs.

• More powerful“generate”-like elaboration, because actions, rules, modules, interfaces and func-tions are all first-class objects, and because BSV has more general type parameterization(polymorphism). These enable the designer to “compute with design fragments”, i.e., to re-usedesigns and to glue them together in much more flexible ways. This leads to much greatersuccinctness and correctness.

• Formal semantics, enabling formal verification and formal design-by-refinement. BSV rulesare based on Term Rewriting Systems, a clean formalism supported by decades of theoreticalresearch in the Computer Science community [Ter03]. This, together with a judicious choiceof a design subset of SystemVerilog, make programs in BSV amenable to formal reasoning.

This manual is meant to be a stand-alone reference for BSV, i.e., it fully describes the subset ofVerilog and SystemVerilog used in BSV. It is not intended to be a tutorial for the beginner. A readerwith a working knowledge of Verilog 1995 or Verilog 2001 should be able to read this manual easily.Prior knowledge of SystemVerilog is not required.

1.1 Meta notation

The grammar in this document is given using an extended BNF (Backus-Naur Form). Grammaralternatives are separated by “|” (vertical bar). Items enclosed in [ ] (square brackets) are optional.Items enclosed in { } (braces) can be repeated zero or more times.

Another grammar extension is parameterization. For example, a moduleStmt can be a moduleIf,and an actionStmt can be an actionIf. A moduleIf and an actionIf are almost identical; the onlydifference is that the former can contain (recursively) moduleStmts whereas the latter can containactionStmts. Instead of tediously repeating the grammar for moduleIf and actionIf, we parameter-ize it by giving a single grammar for <ctxt>If, where <ctxt> is either module or action. In theproductions for <ctxt>If, we call for <ctxt>Stmt which, therefore, either represents a moduleStmt

or an actionStmt, depending on the context in which it is used.

2 Lexical elements

BSV has the same basic lexical elements as Verilog.

9

Page 10: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

2.1 Whitespace and comments

Spaces, tabs, newlines, formfeeds, and carriage returns all constitute whitespace. They may be usedfreely between all lexical tokens.

A comment is treated as whitespace (it can only occur between, and never within, any lexical token).A one-line comment starts with // and ends with a newline. A block comment begins with /* andends with */ and may span any number of lines.

Comments do not nest. In a one-line comment, the character sequences //, /* and */ have no specialsignificance. In a block comment, the character sequences // and /* have no special significance.

2.2 Identifiers and keywords

An identifier in BSV consists of any sequence of letters, digits, dollar signs ($) and underscore char-acters (_). Identifiers are case-sensitive: glurph, gluRph and Glurph are three distinct identifiers.The first character cannot be a digit.

BSV currently requires a certain capitalization convention for the first letter in an identifier (thisconvention may be relaxed in future versions of BSV). Identifiers used for package names, type namesand type classes must begin with a capital letter. In the syntax, we use the non-terminal Identifier

to refer to these. Other identifiers (including names of variables, modules, interfaces, etc.) mustbegin with a lower-case letter, and in the syntax, we use the non-terminal identifier to refer tothese.

As in Verilog, identifiers whose first character is $ (dollar) are reserved for so-called system tasks

and functions (see Section 11.7).

There are a number of keywords that are essentially reserved identifiers; these are listed in AppendixA. Keywords never use uppercase letters.

2.3 Integer literals

Integer literals are written with the usual Verilog and C notations:

intLiteral ::= decLiteral | hexLiteral | octLiteral | binLiteral

decLiteral ::= decDigits

| [ bitWidth ] ( ’d | ’D ) decDigits

hexLiteral ::= [ bitWidth ] ( ’h | ’H ) hexDigits

octLiteral ::= [ bitWidth ] ( ’o | ’O ) octDigits

binLiteral ::= [ bitWidth ] ( ’b | ’B ) binDigits

bitWidth ::= decDigits

decDigits ::= 1 or more consecutive characters from the set 0...9hexDigits ::= 1 or more consecutive characters from the sets 0...9, a...f, A...FoctDigits ::= 1 or more consecutive characters from the set 0...7binDigits ::= 1 or more consecutive characters from the set 0...1

Note that there is no leading + or - in the syntax for integer literals. Instead, we provide unaryprefix + or - operators that can be used in front of any integer expression, including literals (seeSection 9). Examples:

125

’h48454a

32’h48454a

8’o255

12’b101010

10

Page 11: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

2.3.1 Type conversion of integer literals

Integer literals can be used to specify values for various integer types and even for user-defined types.BSV uses a systematic mechanism to perform these type conversions.

In an integer literal, if a specific width w is given (e.g., 8’o255), the literal is assumed to be of typebit [w − 1:0].

When a specific width is not given, BSV uses its more general-purpose overloading resolution mecha-nism to coerce the integer value into the type required by its context. A numeric literal i without anexplicit width is treated as a shorthand for fromInteger(i), where fromInteger is the overloadedfunction to convert integers into various specific types. Overloading resolution is described in moredetail in Section 13.1.

2.4 Real literals

Support for real (Verilog 2001) and shortreal (SystemVerilog) will be added to BSV in the future.

2.5 String literals

String literals are written enclosed in double quotes " and must be contained on a single source line.

stringLiteral ::= " · · · string characters · · · "

Special characters may be inserted in string literals with the following backslash escape sequences:

�n newline�t tab���

backslash�" double quote�v vertical tab�f form feed�a bell�OOO up to 3 octal digits (8-bit character code)�xHH up to 2 hexadecimal digits (8-bit character code)

If fewer that 3 octal digits are used in the octal character code escape sequence, they must be followedby a non-octal digit or by the end of the string.

If fewer that 2 hexadecimal digits are used in the hexadecimal character code escape sequence, theymust be followed by a non-hexadecimal digit or by the end of the string.

2.6 “Don’t care” values

A lone question mark (?), is treated as a special “don’t care” value. For example, one may return ?

from an arm of a case statement that is known to be unreachable.

2.7 Compiler directives

This section is still to be written. These are the standard Verilog directives like ‘define, ‘include,

‘ifdef and so on.

11

Page 12: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

3 Packages and the outermost structure of a BSV design

A BSV program consists of one or more outermost constructs called packages. All BSV code mustbe inside packages. Further, the BSV compiler and other tools assume that there is one packageper file, and uses the package name to derive the file name. For example, a package called Foo isassumed to be located in a file Foo.bsv.

A BSV package is purely a linguistic namespace-management mechanism and is particularly usefulfor programming-in-the-large, so that the author of a package can choose identifiers for the packagecomponents freely without worrying about choices made by authors of other packages. Packagestructure is usually uncorrelated with hardware structure, which is specified by the module construct.

A package contains a collection of top-level statements which include specifications of what it importsfrom other packages, what it exports to other packages, and its definitions of types, interfaces,functions, variables, and modules. BSV tools ensure that when a package is compiled, all thepackages that it imports have already been compiled.

package ::= package packageIde ;

{ exportDecl }{ importDecl }{ packageStmt }endpackage [ : packageIde ]

exportDecl ::= export exportItem { , exportItem } ;

exportItem ::= identifier [ (..) ]| Identifier [ (..) ]

importDecl ::= import importItem { , importItem } ;

importItem ::= packageIde :: *

| packageIde :: identifier

| packageIde :: Identifier

packageStmt ::= [ attributeInstance ] moduleDef

| [ attributeInstance ] interfaceDecl

| typeDef

| varDecl | varAssign | varDeclAssign

| [ attributeInstance ] functionDef

| typeclassDef

| typeclassInstanceDef

| externModuleImport

packageIde ::= Identifier

The name of the package is the identifier following the package keyword. This name can optionallybe repeated after the endpackage keyword (and a colon). We recommend using an uppercase firstletter in package names.

Each export item specifies an identifier defined elsewhere within this package, optionally followedby (..). The identifier then becomes accessible outside this package. If there are any exportstatements, then only those items are exported. If there are no export statements, by default allidentifiers defined in this package are exported.

If the exported identifier is the name of a structure or union type definition, then the members ofthat type will be visible only if (..) is used. By omitting the (..) suffix, only the type, but notits members, are visible outside the package. This is a way to define abstract data types, i.e., typeswhose internal structure is hidden.

Each import item specifies a package from which to import identifiers, i.e., to make them visiblelocally within this package. Either a specific identifier can be imported or, using the * form, allidentifiers from the package can be imported.

12

Page 13: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Example:

package Foo;

export x;

export y;

import Bar::*;

import Glurph::z;

... top level definition ...

... top level definition ...

... top level definition ...

endpackage: Foo

Here, Foo is the name of this package. x and y, which must be defined by the top level definitions inthis package are names exported from this package. From package Bar we import all its definitions.From package Glurph we import just the identifier z.

3.1 Name clashes and qualified identifiers

When used in any scope, an identifier must have an unambiguous meaning. If there is name clashfor an identifier x because it is defined in the current package and/or it is available from one or moreimported packages, then the ambiguity can be resolved by using a qualified name of the form P :: xto refer to the version of x contained in package P .

3.2 The Standard Prelude

The Standard Prelude is a predefined package that is imported implicitly into every BSV package,i.e., it does not need an explicit import statement. It contains a number of useful predefinedentities (types, values, functions, modules, etc.). The Standard Prelude is described in more detailin appendix B.

4 Types

Every variable and every expression in BSV has a type. Almost all variables must be declared withtheir type.

The syntax of types (type expressions) is given below:

type ::= typeIde [ # ( type [ , type ] ) ]| typeNat

| bit [ typeNat : typeNat ]

typeIde ::= Identifier

typeNat ::= decDigits

Examples of simple types:

integer

Bool

String

Action

13

Page 14: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Type expressions of the form X#(t1,· · ·,tN) are called parameterized types. X is called a type

constructor and the types t1,· · ·,tN are the parameters of X . Examples:

Tuple2#(int,Bool) // pair of items, an int and a Bool

Tuple3#(int,Bool,String) // triple of items, an int, a Bool and a String

List#(Bool) // list containing booleans

List#(List #(Bool)) // list containing lists of booleans

Array#(integer, String) // array indexed by integers, containing strings

Type parameters can be natural numbers (also known as size types). These usually indicate someaspect of the size of the type, such as a bit-width or a table capacity. Example:

Bit#(16) // 16-bit vector

bit [15:0] // synonym for Bit #(16)

UInt#(32) // unsigned integers, 32-bits wide

ListN#(16,Bool) // lists of length 16 containing booleans

Currently the second index n in a bit[m:n] type must be 0. This restriction may be relaxed infuture versions of BSV. The type bit[m:0] represents the type of bit vectors, with bits indexed fromm (msb/left) down through 0 (lsb/right), for m ≥ 0.

4.1 Polymorphism

A type can be polymorphic. This is indicated by using type variables as parameters. Examples:

List#(a) // lists containing items of some type ’a’

List#(List#(b)) // lists containing lists of items of some type ’a’

Array#(i, List#(x)) // arrays indexed by some type ’i’, containing

// lists which contain items of some type ’x’

The type variables represent unknown (but specific) types. In other words, List#(a) representsthe type of a list containing items all of which have some type a. It does not mean that differentelements of a list can have different types.

4.2 Provisos (brief intro)

Provisos are described in detail in Section 13.1.1, and the general facility of type classes (overload-ing groups), of which provisos form a part, is described in Section 13.1. Here we provide a briefdescription which is adequate for most uses and for continuity in a serial reading of this manual.

A proviso is a static condition attached to certain constructs, to impose certain restrictions on thetypes involved in the construct. The restrictions are of two kinds:

• Require instance of a type class (overloading group): this kind of proviso states that certaintypes must be instances of certain type classes, i.e., that certain overloaded functions aredefined on this type.

• Require size relationships: this kind of proviso expresses certain constraints between the sizesof certain types.

The most common overloading provisos are:

14

Page 15: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Bits#(t,n) // Type class (overloading group) ’Bits’

// Meaning: overloaded operators ’pack’/’unpack’ are defined

// on type t to convert to/from Bit#(n)

Eq#(t) // Type class (overloading group) ’Eq’

// Meaning: overloaded operators ’==’ and ’!=’ are defined on type t

Literal#(t) // Type class (overloading group) ’Literal’

// Meaning: Overloaded function ’fromInteger()’ defined on type t

// to convert an integer literal to type t

Ord#(t) // Type class (overloading group) ’Ord’

// Meaning: Overloaded order-comparison operators ’<’, ’<=’,

// ’>’ and ’>=’ are defined on type t

Bounded#(t) // Type class (overloading group) ’Bounded’

// Meaning: Overloaded identifiers ’minBound’ and ’maxBound’

// are defined for type t

Bitwise#(t) // Type class (overloading group) ’Bitwise’

// Meaning: Overloaded operators ’&’, ’|’, ’^’, ’<<’ and ’>>’ and

// overloaded function ’invert’ are defined on type t

Arith#(t) // Type class (overloading group) ’Arith’

// Meaning: Overloaded operators ’+’, ’-’, and ’*’ and

// overloaded function ’negate’ are defined on type t

The most common size relationship provisos are:

Add#(n1,n2,n3) // Meaning: assert n1 + n2 = n3

Max#(n1,n2,n3) // Meaning: assert max(n1,n2) = n3

Log#(n1,n2) // Meaning: assert ceiling(log(n1)) = n2

// The logarithm is base 2

Example:

function Bit#(m) pad0101 (Bit#(n) x)

provisos (Add#(n,4,m));

pad0101 = { x, 0b0101 };

endfunction: pad0101

This defines a function pad0101 that takes a bit vector x and pads it to the right with the 4 bits“0101” using the standard bit-concatenation notation. The types and proviso express the idea thatthe function takes a bit vector of length n and returns a bit vector of length m, where n + 4 = m.These provisos permit the BSV compiler to statically verify that entities (values, variables, registers,memories, FIFOs, and so on) have the correct bit-width.

To get the value that corresponds to a size type, there is a special pseudo-function, valueOf, thattakes a size type and gives the corresponding Integer value. In other words, it converts from atype expression into an ordinary value. These mechanisms can be used to do arithmetic to derivedependent sizes. Example:

15

Page 16: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function ... foo (ListN#(n,int) xs) provisos (Log#(n,k));

Int#(k) index;

index = valueOf(n) - 1;

...

endfunction

This function takes a list of length n as an argument. The proviso fixes k to be the (ceiling of the)logarithm of n. The variable index has bit-width k, which will be adequate to hold an index intothe list. The variable is initialized to the maximum index.

Note that this function may be invoked in multiple contexts, each with a different list length. Thecompiler will statically verify that each use is correct (e.g., the index has the correct width).

4.3 deriving clauses (brief intro)

The deriving clause is a part of the general facility of type classes (overloading groups), which isdescribed in detail in Section 13.1. Here we provide a brief description which is adequate for mostuses and for continuity in a serial reading of this manual.

It is possible to attach a deriving clause to a type definition (Section 7) thereby directing thecompiler to define automatically certain overloaded functions for that type. The most commonforms of these clauses are:

deriving(Eq) // Meaning: automatically define ’==’ and ’!=’

// for equality and inequality comparisons

deriving(Bits) // Meaning: automatically define ’pack’ and ’unpack’

// for converting to/from bits

deriving(Ord) // Meaning: automatically define ’<’, ’<=’, ’>’ and ’>=’

// for ordering comparisons

deriving(Bounded) // Meaning: automatically define ’minBound’ and ’maxBound’

5 Modules and interfaces and their instances

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 facilitiesof m. We often refer to these other modules as clients of m.

In SystemVerilog and BSV we separate the declaration of an interface from module declarations.There was no such separation in Verilog 1995 and Verilog 2001, where a module’s interface wasrepresented by its port list, which was part of the module definition itself. By separating theinterface declaration, we can express the idea of a common interface that may be offered by severalmodules, without having to repeat that declaration in each of the implementation modules.

As in Verilog and SystemVerilog, it is important to distinguish between a module declaration anda module instantiation. A module declaration can be regarded as specifying a scheme that can beinstantiated multiple times. For example, we may have a single module declaration for a FIFO, anda particular design may instantiate it multiple times for all the FIFOs it contains.

Similarly, we also distinguish interface declarations and instances, i.e., a design will contain interfacedeclarations, and each of these may have multiple instances. For example an interface declarationI may have one instance i1 for communication between module instances a1 and b1, and anotherinstance i2 for communication between module instances a2 and b2.

16

Page 17: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Module instances form a pure hierarchy. Inside a module declaration mkM , one can specify instan-tiations of other modules. When mkM is used to instantiate a module m, it creates the specifiedinner module instances. Thus, every module instance other than the top of the hierarchy unambigu-ously has a single parent module instance. We refer to the top of the hierarchy as the root module.Every module instance has a unique set (possibly empty) of child module instances. If there are nochildren, we refer to it as a leaf module.

A module consists of three things: state, rules that operate on that state, and the module’s interfaceto the outside world (surrounding hierarchy). The state conceptually consists of all state in the sub-hierarchy headed by this module; ultimately, it consists of all the lower leaf module instances (see nextsection on state and module instantiation). Rules are the fundamental means to express behaviorin BSV (instead of traditional Verilog’s always blocks). In BSV an interface consists of methods

which encapsulate the possible transactions that clients can perform, i.e., the micro-protocols withwhich clients interact with the module. When compiled into RTL, an interface becomes a collectionof wires.

5.1 Explicit state via module instantiation, not variables

In Verilog and SystemVerilog RTL, one just declares variables, and a synthesis tool “infers” howthese variables actually map into state elements in hardware, e.g., based on their lifetimes relativeto events. A variable may map into a bus, a latch, a flip-flop, or even nothing at all. This ambiguityis acknowledged in the Verilog 2001 and SystemVerilog LRMs.1

BSV removes this ambiguity and places control over state instantiation explicitly in the hands ofthe designer. From the smallest state elements (such as registers) to the largest (such as memories),all state instances are specified explicitly using module instantiation.

Conversely, an ordinary declared variable in BSV never implies state, i.e., it never holds a valueover time. Ordinary declared variables are always just convenient names for intermediate values ina computation. Ordinary declared variables include variables declared in blocks, formal parameters,pattern variables, loop iterators, and so on. Another way to think about this is that ordinaryvariables only play a role in static elaboration, not in the dynamic semantics. This is one of theaspects of BSV style that may initially appear unusual to the Verilog or SystemVerilog programmer.

5.2 Interface declaration

In BSV an interface contains members that are called methods. (Currently in BSV an interfacecontains methods only; future versions of BSV may relax this to allow other types of members.) Tofirst order, a method can be regarded exactly like a function, i.e., it is a procedure that takes zeroor more arguments and returns a result. Thus, method declarations inside interface declarationslook just like function prototypes, the only difference being the use of the keyword method insteadof the keyword function. Each method represents one kind of transaction between a module andits clients. When translated into RTL, each method becomes a bundle of wires.

The fundamental difference between a method and a function is that a method also carries with it aso-called implicit condition. These will be described later along with method definitions and rules.

An interface declaration also looks similar to a struct declaration. One can think of an interfacedeclaration as declaring a new type similar to a struct type, where the members all happen to bemethod prototypes. A method prototype is essentially the header of a method definition (Section5.5). Each method prototype can be preceded by a pragma, which is described in Section 12.1.

1In the Verilog 2001 LRM, Section 3.2.2 (Variable declarations) says: “ A variable is an abstraction of a datastorage element. · · · NOTE In previous versions of the Verilog standard, the term register was used to encompassboth the reg, integer, time, real and realtime types; but that term is no longer used as a Verilog data type.”

In the SystemVerilog LRM, Section 5.1 says: “Since the keyword reg no longer describes the users intent in manycases, · · · Verilog-2001 has already deprecated the use of the term register in favor of variable.”

17

Page 18: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

interfaceDecl ::= interface typeDefType ;

{ methodProto }endinterface [ : typeIde ]

typeDefType ::= typeIde [ # ( type typeIde [ , type typeIde ] ) ]

methodProto ::= [ pragma ] method type identifier ( [ methodProtoFormals ] ) [provisos ] ;

methodProtoFormals ::= methodProtoFormal { , methodProtoFormal }

methodProtoFormal ::= type identifier

Example:

interface IntStack;

method Action push (int x);

method Action pop;

method int top;

endinterface: IntStack

This describes an interface to a circuit that implements a stack (LIFO) of integers. The push

method takes an int argument, the item to be pushed onto the stack. Its output type is Action,namely it returns an enable wire which, when asserted, will carry out the pushing action.2 The pop

method takes no arguments, and simply returns an enable-wire which, when asserted, will discardthe element from the top of the stack. The top method takes no arguments, and returns a value oftype int, i.e., the element at the top of the stack.

What if the stack is empty? In that state, it should be illegal to use the pop and top methods.This is exactly where the difference between methods and functions arises. Each method has animplicit ready wire which governs when it is legal to use it, and these wires for the pop and top

methods will presumably be de-asserted if the stack is empty. Exactly how this is accomplished isan internal detail of the module, and is therefore not visible as part of the interface declaration. (Wecan similarly discuss the case where the stack has a fixed, finite depth; in this situation, it shouldbe illegal to use the push method.)

One of the major advantages of BSV is that the compiler automatically generates all the controlcircuitry needed to ensure that a method (transaction) is only used when it is legal to use it.

Interface types can be polymorphic, i.e., parameterized by other types. For example, the followingdeclaration describes an interface for a stack containing an arbitrary but fixed type:

interface Stack #(type a);

method Action push (a x);

method Action pop;

method a top;

endinterface: Stack

We have replaced the previous specific type int with a type variable a. (The reason for the type

keyword is that, in the future, BSV may allow other kinds of parameters, including values of othertypes.) By “arbitrary but fixed” we mean that a particular stack will specify a particular type for a,and all items in that stack stack will have that type. It does not mean that a particular stack cancontain items of different types.

For example, using this more general definition, we can also define the IntStack type as follows:

typedef Stack #(int) IntStack;

i.e., we simply specialize the more general type with the particular type int. All items in a stack ofthis type will have the int type.

2The type Action is discussed in more detail in Section 9.6

18

Page 19: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

5.3 Module declaration

A module declaration begins with a module header containing the module keyword, the modulename, parameters, interface type and provisos. The header is followed by zero or more modulestatements. Finally we have the closing endmodule keyword, optionally labelled again with themodule name.

moduleDef ::= module identifier [ moduleParams ] ( [ type ] ) [ provisos ] ;{ moduleStmt }

endmodule [ : identifier ]

moduleParams ::= # ( moduleParam { , moduleParam } )

moduleParam ::= type identifier

As a stylistic convention, many BSV examples use module names like mkFoo, i.e., beginning withthe letters mk, suggesting the word “make”. This serves as a reminder that a module definition is nota module instance. When the module is instantiated, one invokes mkFoo to actually make a moduleinstance.

The optional moduleParams are exactly as in Verilog and SystemVerilog, i.e., they represent moduleparameters that must be supplied at each instantiation of this module, and are used at elaborationtime. After the module name and parameters, one specifies a single interface type in parentheses,instead of Verilog’s port list. The interpretation is that this module will define and offer an interfaceof that type to its clients. Omitting the interface type is equivalent to using the pre-defined Empty

interface type, which is a trivial interface containing no methods.

Provisos, which are optional, come next. These are part of an advanced feature called type classes(overloading groups), and are discussed in more detail in Section 13.1.

The body of the module consists of a sequence of moduleStmts:

moduleStmt ::= moduleInst

| methodDef

| rule

| <module>If | <module>Case

| <module>BeginEndStmt

| varDecl | varAssign | varDeclAssign

| varDo | varDeclDo

| functionDef

| functionCall

| systemTaskCall

| ( expression )

| returnStmt

Most of these are discussed elsewhere since they can also occur in other contexts (e.g., in packages,function bodies, and method bodies). Below, we focus on just those statements that are only foundin module bodies or are treated specially in module bodies.

5.4 Module and interface instantiation

A module definition can contain specifications for instantiating other modules, and in the process,instantiating their interfaces.

moduleInst ::= type identifier ( ) ;

moduleApp identifier ( identifier ) ;

moduleApp ::= identifier [ # ( moduleActualParam { , moduleActualParam } ) ]

moduleActualParam ::= expression

19

Page 20: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

A module instantiation is typically written on two consecutive lines. The first line declares anidentifier with an interface type. The second line actually instantiates the module and defines theinterface. The varExpr is the module (definition) name, possibly applied to parameters (if it hadbeen defined to have parameters). The first identifier names the new module instance. The secondidentifier (in parentheses) refers to the previously declared interface identifier.

The following skeleton illustrates the structure and relationships between interface and moduledefinition and instantiation.

interface ArithIO #(type a);

method Action input (a x, a y);

method a output;

endinterface: ArithIO

module mkGCD #(int N) (ArithIO #(bit [31:0]));

...

...

endmodule: mkGCD

module mkTest ();

...

ArithIO #(bit [31:0]) gcdIfc();

mkGCD #(5) a_GCD (gcdIfc);

...

endmodule: mkTest;

The interface construct declares an interface type called ArithIO that is parameterized by anothertype a and contains two methods input and output.

The first module construct declares a module definition called mkGCD that has one parameter, aninteger N, and presents an interface of type ArithIO #(bit [31:0]).

The second module construct declares a module definition called mkTest. Inside that module, thetwo lines shown make a module instance using mkGCD. The first line declares the interface instance,called gcdIfc and having type ArithIO #(bit [31:0]). The second line instantiates the module,giving it parameter 5, naming the module instance a_GCD and defining the interface instance gcdIfc.

5.5 Interface definition (definition of methods)

A module definition contains a definition of its interface. Typically this takes the form of a collectionof definitions, one for each method in its interface. Each method definition begins with the keywordmethod, followed optionally by the return-type of the method, then the method name, its formalparameters, an optional implicit condition, and optional provisos. After this comes the method bodywhich is exactly like a function body. It ends with the keyword endmethod, optionally labelled againwith the method name.

moduleStmt ::= methodDef

methodDef ::= method [ type ] identifier ( methodFormals ) [ implicitCond ] ;functionBody

endmethod [ : identifier ]

methodFormals ::= methodFormal { , methodFormal }

methodFormal ::= [ type ] identifier

implicitCond ::= if ( expression )

20

Page 21: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

The method name must be one of the methods in the interface whose type is specified in the moduleheader. Each of the module’s interface methods must be declared exactly once in the module body.

The return-type of the method and the types of its formal arguments are optional, and are presentfor readability and documentation purposes only. The compiler knows these types from the methodprototypes in the interface declaration. If specified here, they must match exactly the correspondingtypes in the method prototype.

The expression in the optional implicit condition must be a Boolean expression. This expression canutilize any of the variables in scope surrounding the method definition, i.e., visible in the modulebody; it cannot use the formal parameters of the method itself.3 Omitting the implicit condition isequivalent to saying if (True). The semantics of implicit conditions are discussed in Section 9.12on Rules.

Every method is ultimately invoked from a rule (a method m1 may be invoked from another methodm2 which, in turn, may be invoked from another method m3, and so on, but if you follow the chain,it will end in a method invocation inside a rule). A method’s implicit condition controls whetherthe invoking rule is enabled. Using implicit conditions, it is possible to write client code that is notcluttered with conditionals that test whether the method is applicable. For example, a client of aFIFO module can just call the enqueue or the dequeue method without having explicitly to testwhether the FIFO is full or empty, respectively; those predicates are usually specified as implicitconditions attached to the FIFO methods.

Please note carefully that the implicit condition precedes the semicolon that terminates the methoddefinition header. There is a very big semantic difference between the following:

method ... foo (...) if (expr);

...

endmethod

and

method ... foo (...); if (expr)

...

endmethod

In the former example, if (expr) is an implicit condition on the method. In the latter example, itstarts a conditional statement inside the method, and there is no implicit condition.

The method body is exactly like a function body, which is discussed in Section 8.5 on functiondefinitions.

See also Section 9.11 for the more general concepts of interface expressions and expressions as first-class objects.

5.6 Rules in module definitions

The internal behavior of a module is described using zero or more rules.

moduleStmt ::= rule

rule ::= [ ruleAssertion ] rule identifier [ ruleCond ] ;ruleBody

endrule [ : identifier ]

3The restriction that a method’s implicit condition may not use the method’s own formal parameters may beremoved in the future. It is present for certain technical reasons because it can result in combinational cycles.

21

Page 22: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

ruleCond ::= ( expression )

ruleBody ::= actionBlock

| { actionStmt }

actionBlock ::= action [ : identifier ]{ actionStmt }

endaction [ : identifier ]

A rule is optionally preceded by a ruleAssertion; these are described in Section 12.2. Every rulemust have a unique name (the identifier).4 If the closing endrule is labelled with an identifier, itmust be the same name.

The ruleCond, if present, must be a Boolean expression. It can use any identifiers from the scopesurrounding the rule, i.e., visible in the module body.5

The ruleBody must be of type Action. Formally, this is an actionBlock, which is a special kind oflabelled block containing a sequence of zero or more actionStmts. For convenience, however, theruleBody can directly contain the sequence of actionStmts, omitting the action and endaction

keyword brackets.

We discuss actionStmts in Section 9.6 on Actions, but here we make a key observation. Actionsinclude updates to state elements (including register writes). There are no restrictions on multi-ple rules updating the same state elements. The BSV compiler will generate all the control logicnecessary for such shared update, including multiplexing, arbitration, and resource control. Thegenerated control logic will ensure rule atomicity, discussed briefly in the next paragraphs.

A more detailed discussion of rule semantics is given in Section 6.2 on Dynamic Semantics, but weoutline the key point briefly here. The ruleCond is called the explicit condition of the rule. Withinthe ruleCond and ruleBody, there may be calls to various methods of various interfaces. Each suchmethod call has an associated implicit condition. The rule is enabled when its explicit condition andall its implicit conditions are true. A rule can fire, i.e., execute the actions in its ruleBody, when therule is enabled and when the actions cannot “interfere”with the actions in the bodies of other rules.Non-interference is described more precisely in Section 6.2 but, roughly speaking, it means that therule execution can be viewed as an atomic state transition, i.e., there cannot be any race conditionsbetween this rule and other rules.

This atomicity and the automatic generation of control logic to guarantee atomicity is a key benefit ofBSV. Note that because of method calls in the rule and, transitively, method calls in those methods,a rule can touch (read/write) state that is distributed in several modules. Thus, a rule can expressa major state change in the design. The fact that it has atomic semantics guarantees the absence ofa whole class of race conditions that might otherwise bedevil the designer. Further, changes in thedesign, whether in this module or in other modules, cannot introduce races, because the compilerwill verify atomicity.

See also Section 9.12 for the more general concepts of rule expressions and rules as first-class objects.

5.7 Examples

A register is primitive module with the following pre-defined interface:

interface Reg #(type a);

method Action _write (a x1);

method a _read ();

endinterface: Reg

4In BSV 3.8 the rule name is just an identifier. In future versions the rule name will be statically computable,making it more useful for generated rule names.

5In future versions of BSV, rule conditions will also allow pattern matching.

22

Page 23: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

It is polymorphic, i.e., it can contain values of any type a. It has two methods. The _write()

method takes an argument x1 of type a and returns an Action, i.e., an enable-wire that, whenasserted, will deposit the value into the register. The _read() method takes no arguments andreturns the value that is in the register.

The principal pre-defined module definition for a register has the following header:

// takes an initial value for the register

module mkReg #(a v) (Reg #(a)) provisos (Bits#(a, sa));

The module parameter v of type a is specified when instantiating the module (creating the register),and represents the initial value of the register. The module defines an interface of type Reg #(a).The proviso specifies that the type a must be convertible into an sa-bit value, and provisos arediscussed in more detail in Sections 4.2 and 13.1.

Here is a module to compute the GCD (Greatest Common Divisor) of two numbers using Euclid’salgorithm.

interface ArithIO #(type a);

method Action input (a x, a y);

method a output;

endinterface: ArithIO

typedef bit [31:0] Int;

module mkGCD (ArithIO #(Int));

Reg #(Int) x(); // declare Reg interface x

mkReg #(0) the_x (x); // instantiate reg the_x, intialized to 0

Reg #(Int) y(); // declare Reg interface y

mkReg #(0) the_y (y); // instantiate reg the_y, intialized to 0

rule flip (x > y && y != 0);

x <= y;

y <= x;

endrule

rule sub (x <= y && y != 0);

y <= y - x;

endrule

method Action input (Int ix, Int iy) if (y == 0);

action

x <= ix;

y <= iy;

endaction

endmethod: input

method Int output() if (y == 0);

output = x;

endmethod: output

endmodule: mkGCD

The interface type is called ArithIO because it expresses the interactions of modules that do any kindof two-input, one-output arithmetic. Computing the GCD is just one example of such arithmetic.We could define other modules with the same interface that do other kinds of arithmetic.

23

Page 24: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

The module contains two rules, flip and sub that implement Euclid’s algorithm, i.e., assumingthe registers x and y have been initialized with the input values, the rules repeatedly update theregisters with transformed values, terminating when the register y contains zero. At that point, therules stop firing, and the GCD result is in register x. Rule flip uses standard Verilog non-blockingassignments to express an exchange of values between the two registers. As in Verilog, the symbol<= is used both for non-blocking assignment as well as for the “less-than-or-equal”operator (e.g., inrule sub’s explicit condition), and as usual these are disambiguated by context.

The input method takes two arguments ix and iy representing the numbers whose GCD is sought,and loads them into the registers x and y, respectively. The output method returns the result valuefrom the x register. Both methods have an implicit condition (y == 0) that prevents them frombeing used while the module is busy computing a GCD result.

A testbench for this module might look like this:

module mkTest ();

ArithIO #(Int) gcd; // declare ArithIO interface gcd

mkGCD the_gcd (gcd); // instantiate gcd module the_gcd

rule getInputs;

... read next ix and iy from file ...

the_gcd.input (ix, iy); // start the GCD computation

endrule

rule putOutput;

$display("Output is %d", the_gcd.output); // print result

endrule

endmodule: mkTest

The first two lines instantiate a GCD module. The getInputs rule gets the next two inputs froma file, and then initiates the GCD computation by calling the input method. The putOutput ruleprints the result. Note that because of the semantics of implicit conditions and enabling of rules,the getInputs rule will not fire until the GCD module is ready to accept input. Similarly, theputOutput rule will not fire until the output method is ready to deliver a result.6

The mkGCD module is trivial in that the rule conditions ((x > y) and (x <= y)) are mutuallyexclusive, so they can never fire together. Nevertheless, since they both write to register y, thecompiler will insert the appropriate muxes and mux control logic.

Similarly, getInputs rule (which calls the input method) can never fire together with the mkGCD

rules because the implicit condition of getInputs, i.e., (y == 0) is mutually exclusive with theexplicit condition (y != 0) in flip and sub. Nevertheless, since getInputs writes into the_gcd’sregisters via the input method, the compiler will insert the appropriate muxes and mux controllogic.

In general, many rules may be enabled simultaneously, and subsets of rules that are simultaneouslyenabled may read and write common state. The BSV compiler will insert appropriate scheduling,datapath muxing and control to ensure that when rules fire in parallel, the net state change isconsistent with the atomic semantics of rules.

6 Static and dynamic semantics

What is a legal BSV source text, and what are its legal behaviors? These questions are addressed bythe static and dynamic semantics of BSV. The BSV compiler checks that the design is legal according

6The astute reader will recognize that in this small example, since the output method is initially ready, thetestbench will first output a result of 0 before initiating the first computation. Let us overlook this by imagining thatEuclid is clearing his throat before launching into his discourse.

24

Page 25: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

to the static semantics, and produces RTL hardware that exhibits legal behaviors according to thedynamic semantics.

Conceptually, there are three phases in processing a BSV design, just like in Verilog and SystemVer-ilog:

• Static checking: this includes syntactic correctness, type checking and proviso checking.

• Static elaboration: actual instantiation of the design and propagation of parameters, producingthe module instance hierarchy.

• Execution: execution of the design, either in a simulator or as real hardware.

We refer to the first two as the static phase (i.e., pre-execution), and to the third as the dynamicphase. Dynamic semantics are about the temporal behavior of the statically elaborated design, i.e.,describing the dynamic execution of rules and methods and their mapping into clocked synchronoushardware.

A BSV program can also contain assertions; assertion checking can occur in all three phases, de-pending on the kind of assertion.

6.1 Static semantics

The static semantics of BSV are about syntactic correctness, type checking, proviso checking, staticelaboration and static assertion checking. Syntactic correctness of a BSV design is checked by theparser in the BSV compiler, according to the grammar described thoughout this document.

6.1.1 Type checking

BSV is statically typed, just like Verilog, SystemVerilog, C, C++, and Java. This means the usualthings: every variable and every expression has a type; variables must be assigned values that havecompatible types; actual and formal parameters/arguments must have compatible types, etc. Allthis checking is done on the original source code, before any elaboration or execution.

BSV uses SystemVerilog’s new tagged union mechanism instead of the older ordinary unions, therebyclosing off a certain kind of type loophole. BSV also allows more type parameterization (polymor-phism), without compromising full static type checking.

6.1.2 Proviso checking and bit-width constraints

In BSV, overloading constraints and bit-width constraints are expressed using provisos (Sections 4.2and 13.1.1). Overloading constraints provide an extensible mechanism for overloading.

BSV is stricter about bit-width constraints than Verilog and SystemVerilog by avoiding implicitzero-extension, sign-extension and truncation of bit-vectors. These operations must be performedconsciously by the designer using library functions, thereby avoiding another source of potentialerrors.

Note: provisos may evolve into SystemVerilog assertion syntax in future versions of BSV.

25

Page 26: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

6.1.3 Static elaboration

As in Verilog and SystemVerilog, static elaboration is the phase in which the design is instantiated,starting with a top-level module instance, instantiating its immediate children, instantiating theirchildren, and so on to produce the complete instance hierarchy.

BSV has powerful generate-like facilities for expressing regular structures in designs succinctly. Forexample, the structure of a linear pipeline may be expressed using a loop, and the structure of atree-structured reduction circuit may be expressed using a recursive function. All these are alsounfolded and instantiated during static elaboration. In fact, the BSV compiler unfolds all structuralloops and functions during static elaboration.

A fully elaborated BSV design consists of just the following components:

• A module instance hierarchy. There is a single top-level module instance, and each moduleinstance contains zero or more module instances as children.

• Each module instance presents an interface (an interface instance) to its clients, and may itselfbe a client of zero or more interfaces of other module instances.

• Each interface instance consists of zero or more defined methods.

A method’s body may contain zero or more invocations of methods in other interfaces.

Every method has an implicit condition, which can be regarded as a single output wire thatis asserted only when the method is ready to be invoked. The implicit condition may directlytest state internal to its module, and may indirectly test state of other modules by invokingtheir interface methods.

• Each module instance contains zero or more rules, each of which contains a condition andan action. The condition is a Boolean expression. Both the condition and the action maycontain invocations of interface methods of other modules. Since those interface methods canthemselves contain invocations of other interface methods, the conditions and actions of a rulemay span many modules.

6.2 Dynamic semantics

The dynamic semantics of BSV specify the temporal behavior of rules and methods and their map-ping into clocked synchronous hardware.

Every rule has a syntactically explicit condition and action. Both of these may contain invocationsof interface methods, each of which has an implicit condition. A rule’s composite condition consistsof its syntactically explicit condition AND’ed with the implicit conditions of all the methods invokedin the rule. A rule is said to be enabled if its composite condition is true.

6.2.1 Reference semantics

The reference semantics is the simplest way to specify the dynamic semantics, and is completelysequential (but please do not equate this with slow execution; the execution steps below are not thesame as clocks; we will see in the next section that many steps can be mapped into each clock):

Repeat the following forever:

• Step: Pick any one enabled rule, and perform its action.(We say that the rule is fired or executed.)

26

Page 27: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Note that after each step, a different set of rules may be enabled, since the current rule’s action willtypically update some state elements in the system which, in turn, may change the value of ruleconditions and implicit conditions.

The choice of a rule to execute at each step is non-deterministic. Thus, the semantics specify a set

of legal behaviors, not just a single unique behavior.

The simple reference semantics makes it very easy for the designer to reason about invariants (cor-rectness conditions). Because only one rule is executed in each step, we only have to look at (theactions of) each rule in isolation to check how it maintains or transforms invariants. In particular,we do not have to consider simultaneous execution of multiple rules.

Another way of saying this is: each rule execution can be viewed as an atomic state transition.7 Raceconditions, the bane of the hardware designer, can generally be explained as an atomicity violation;BSV’s rules are a powerful way to avoid most races.

The reference semantics is based on Term Rewriting Systems (TRSs), a formalism supported bydecades of research in the Computer Science community [Ter03]. For this reason, we also refer tothe reference semantics as the TRS semantics of BSV.

6.2.2 Mapping into efficient parallel clocked synchronous hardware

A BSV design is mapped by the BSV compiler into efficient parallel clocked synchronous hardware.In particular, the mapping permits multiple rules to be executed in each clock cycle. This is donein a manner that is consistent with the reference TRS semantics, so that any correctness propertiesascertained using the TRS semantics continue to hold in the hardware.

Standard clocked synchronous hardware imposes the following restrictions:

• The state is updated only once per clock cycle (usually at a clock edge). And, during a clockcycle, values read from state elements are the ones that came through from the last cycle.

• Clock-speed requirements place a limit on the amount of combinational computation that canbe performed between state elements, because of propagation delay.

The composite condition of each rule is mapped into a combinational circuit whose (possibly multiple)inputs sense the current state and whose 1-bit output specifies whether this rule is enabled or not.

The action of each rule is mapped into a combinational circuit that represents the state transitionfunction of the action. It can have multiple inputs and multiple outputs, the latter being thecomputed next-state values.

Figure 1 illustrates a general scheme to compose rule components when mapping the design to clockedsynchronous hardware. The State box lumps together all the state elements in the BSV design (asdescribed earlier, state elements are explicitly specified in BSV). The BSV compiler produces arule-control circuit which conceptually takes all the enable (cond) signals and all the data (action)outputs and controls which of the data outputs are actually captured at the next clock in the stateelements. The enable signals feed a scheduler circuit that decides which of the rules will actuallyfire. The scheduler, in turn, controls data multiplexers that select which data outputs reach thedata inputs of state elements, and controls which state elements are enabled to capture the newdata values. Firing a rule simply means that the scheduler selects its data output and clocks it intothe next state.

At each clock, the scheduler selects a subset of rules to fire. Not all subsets are legal. A subset islegal if and only if the rules in the subset can be ordered such that:

7We use the term atomic as it is used in concurrency theory (and in operating systems and databases), i.e., tomean indivisible.

27

Page 28: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Figure 1: A general scheme for mapping an N-rule system into clocked synchronous hardware.

• A hypothetical sequential execution of the ordered subset of rules is legal at this point, ac-cording to the TRS semantics. In particular, the first rule in the ordered subset is currentlyenabled, and each subsequent rule would indeed be enabled when execution reaches it in thehypothetical sequence.

A special case is where all rules in the subset are already currently enabled, and no rule wouldbe disabled by execution of prior rules in the order.

• The hardware execution produces the same net effect on the state as the hypothetical sequentialexecution, even though the hardware execution performs reads and writes in a different orderfrom the hypothetical sequential execution.

The BSV compiler performs a very sophisticated analysis of the rules in a design and synthesizes anefficient hardware scheduler that controls execution in this manner.

Note: The scheme in Figure 1 is for illustrative purposes only. First, it lumps together all the state,shows a single rule-control box, etc., whereas in the real hardware generated by the BSV compilerthese are distributed, localized and modular. Second, it is not the only way to map the design intoclocked synchronous hardware. For example, any two enabled rules can also be executed in a singleclock by feeding the action outputs of the first rule into the action inputs of the second rule, or bysynthesizing hardware for a composite circuit that computes the same function as the composition ofthe two actions, and so on. In general, these alternative schemes may be more complex to analyze,or may increase total propagation delay, but the compiler may use them in special circumstances.

In summary, the BSV compiler performs a detailed and sophisticated analysis of rules and theirinteractions, and maps the design into very efficient, highly parallel, clocked synchronous hardwareincluding a scheduler that allows many rules to fire in parallel in each clock, but always in a mannerthat is consistent with the reference TRS semantics. The designer can use the simple referencesemantics to reason about correctness properties and be confident that the synthesized parallelhardware will preserve those properties.

This automatic maintenance of atomicity (avoidance of races) is something that the designer wouldotherwise have to do manually, when coding in other HDLs, including the management of data pathsand synchronization. The BSV compiler automates this, and is capable of producing RTL that iscompetitive with hand-coded RTL.

28

Page 29: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

7 User-defined types (type definitions)

User-defined types may appear at the top level of packages.

typeDef ::= typedefSynonym

| typedefEnum

| typedefStruct

| typedefTaggedUnion

As a matter of style, BSV requires that all enumerations, structures and unions be used only viatypedef, i.e., it is not possible directly to declare a variable, formal parameter or formal argumentas an enum, struct or union without first giving that type a name using a typedef.

Each typedef of an enum, struct or union introduces a new type that is different from all other types.For example, even if two typedefs give names to struct types with exactly the same correspondingmember names and types, they define two distinct types.

Other typedefs, i.e., not involving an enum, struct or union, merely introduce type synonyms forexisting types.

7.1 Type synonyms

Type synonyms are just for convenience and readability, allowing one to define shorter or moremeaningful names for existing types. The new type and the original type can be used interchangeablyanywhere.

typedefSynonym ::= typedef type typeDefType ;

typeDefType ::= typeIde [ # ( type typeIde [ , type typeIde ] ) ]

Examples: Defining names for bit vectors of certain lengths.

typedef bit [7:0] Byte;

typedef bit [31:0] Word;

typedef bit [63:0] LongWord;

7.2 Enumerations

typedefEnum ::= enum { identifier { , identifier } } Identifier [ derives ] ;

Enumerations provide a way to define a set of unique symbolic constants, also called labels or member

names. Each enumeration definition creates a new type different from all other types. The newlydefined labels must be unique (within a package), i.e., two different enumerations cannot use commonlabels.8

The optional derives clause is discussed in more detail in Sections 4.3 and 13.1. One common form isderiving (Bits) which tells the compiler to pick a default bit-representation for this enumeration:pick the smallest number of bits necessary to represent all the labels, and give the values 0, 1, 2, · · ·to the labels in the order that they are listed. Another common form of the clause is deriving (Eq),which tells the compiler to pick a default equality operation for these labels, so they can also betested for equality and inequality. A third common form is deriving (Ord), which tell the compilerto pick a default ordering for the labels, with each label < (less than) the next one in the listingorder. These specifications can be combined, e.g., deriving (Bits, Eq, Ord). All these defaultchoices for representation, equality and ordering can be overridden (see Section 13.1).

8The restriction that two enumerations cannot define common member names may be removed in the future.

29

Page 30: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Note: future versions of BSV may assume deriving (Bits,Eq,Ord) for all enums unless specificallyoverridden.

Example:

typedef { False, True } Bool deriving (Bits, Eq);

The compiler will pick a 1-bit representation, with 1’b0 and 1’b1 as the representations for False

and True, respectively. It will define the == and != operators to also work on Bool values.

Example: in the specification of a processor:

typedef enum { R0, R1, ..., R31 } RegName deriving (Bits);

typedef RegName Rdest;

typedef RegName Rsrc;

The first line defines an enumeration type with 32 register names. The second and third lines definetype synonyms for RegName that may be more informative in certain contexts (“destination” and“source” registers). Because of the deriving clause, the compiler will pick a five-bit representation,with values 5’h00 through 5’h1F for R0 through R31.

7.3 Structures and tagged unions

A structure definition introduces a new record type.

SystemVerilog has (ordinary) unions as well as tagged unions, but in BSV we only use taggedunions, for several reasons. The principal benefit is safety (verification)– ordinary unions open aserious type-checking loophole, whereas tagged unions are completely type-safe. Other reasons arethat, in conjunction with pattern matching (Section 10), tagged unions yield much more succinctand readable code (which also improves correctness). In the text below, we may just say “union” forbrevity, but it always means “tagged union”.

typedefStruct ::= typedef struct [ typeFormals ] {{ structMember }

} Identifier [ derives ] ;

typedefTaggedUnion ::= typedef union tagged [ typeFormals ] {{ unionMember }

} Identifier [ derives ] ;

structMember ::= type identifier ;

| subTagged

unionMember ::= type identifier ;

| void identifier ;

| subStruct

| subTagged

subStruct ::= struct {

{ structMember }} Identifier ;

subTagged ::= union tagged {

{ unionMember }} Identifier ;

typeFormals ::= # ( identifier { , identifier } )

30

Page 31: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

All types can of course be mutually nested if mediated by typedefs, but struct and unions can also bemutually nested directly as described in the syntax above. Structures and unions contain members.All the member names in a particular structure or union must be unique, but the same names canbe used in other structures and members; the compiler will try to disambiguate based on type.

A structure value contains the first member and the second member and the third member, andso on. A union value contains just the first member or just the second member or just the thirdmember, and so on.

In a tagged union, the member names are also called tags. Tags play a very important safety role.Suppose we had the following:

typedef union tagged { int tagi; oneHot tagoh; } u deriving (Bits);

u x;

The variable x not only contains the bits corresponding to one of its member types int or oneHot,but also some extra bits (in this case just one bit) that remember the tag, 0 for tagi and 1 fortagoh. When the tag is tagi, it is impossible to read it as a oneHot member, and when the tag istagoh it is impossible to read it as an int member, i.e., the syntax and type-checking ensure this.Thus, it is impossible accidentally to mis-read what is in a union value.

The optional derives clause is discussed in more detail in Section 13.1. One common form is deriving(Bits) which tells the compiler to pick a default bit-representation for the structure or union. Forstructures it is simply a concatenation of the representations of the members. For unions, therepresentation consists of t + m bits, where t is the minimum number of bits to code for the tagsin this union and m is the number of bits for the largest member. Every union value has a codein the t- bit field that identifies the tag, concatenated with the bits of the corresponding member,right-justified in the m-bit field. If the member needs fewer than m bits, the remaining bits (betweenthe tag and the member bits) are undefined.

Structure and union typedefs can define new, polymorphic types, signalled by the presence of typeparameters in #(...).

Section 9.10 on structure and union expressions describes how to construct structure and union valuesand to access and update members. Section 10 on pattern matching describes a more high-level wayto access members from structures and unions and to test union tags.

Example: these are ordinary, traditional record structures.

typedef struct { Int x; Int y; } Coord;

typedef struct { Addr pc; RegFile rf; Memory mem; } Proc;

Example: encoding instruction operands in a processor:

typedef union tagged {

bit [4:0] Register;

bit [21:0] Literal;

struct {

bit [4:0] RegAddr;

bit [4:0] RegIndex;

} Indexed;

} InstrOperand;

An instruction operand is either a 5-bit register specifier, a 22-bit a literal value, or an indexedmemory specifier, consisting of two 5-bit register specifiers.

Example: encoding instructions in a processor:

31

Page 32: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef union tagged {

struct {

Op op; Reg rs; CPUReg rt; UInt16 imm;

} Immediate;

struct {

Op op; UInt26 target;

} Jump;

} Instruction

deriving (Bits);

An Instruction is either an Immediate or a Jump. In the former case, it contains a field calledop containing a value of type Op, a field called rs containing a value of type Reg, a field called rt

containing a value of type CPUReg, and a field called imm containing a value of type UInt16. Inthe latter case, it contains a field called op containing a value of type Op, and a field called target

containing a value of type UInt26.

Example:

typedef union tagged {

void Invalid;

int Valid;

} MaybeInt

deriving (Bits);

A MaybeInt is either invalid, or is valid and contains an int. The representation of this type will be33 bits, a valid/invalid bit plus 32 bits for an int. When it carries an invalid value, the remaining32 bits are undefined. It will be impossible to read/interpret those 32 bits when the tag bit says itis Invalid.

This type is so useful, and not just for integers, that we generalize it into a polymorphic type:

typedef union tagged {

void Invalid;

a Valid;

} Maybe #(a)

deriving (Bits);

i.e., it can be used with any type a. Consider a function that, given a key, looks up a table andreturns some value associated with that key. Such a function can return either an invalid result, ifthe table does not contain an entry for the given key, or a valid result v if that is associated with thekey in the table. The type is polymorphic (type parameter a) because it may be used with lookupfunctions for integer tables, string tables, IP address tables, etc., i.e., we do not want to over-specifythe type of the value v at which it may be used.

See Section 11.3 for an important, predefined set of structure types called Tuples for ad-hoc structuresof from 2 to 7 members.

8 Variable declarations and statements

Statements can occur in various contexts: in packages, modules, function bodies, rule bodies, actionblocks and actionvalue blocks. Some kinds of statements have been described earlier because theywere specific to certain contexts: module definitions (moduleDef ) and instantiation (moduleInst),

32

Page 33: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

interface declarations (interfaceDecl), type definitions (typeDef ), method definitions (methodDef )inside modules, rules (rule) inside modules, and action blocks (actionBlock) inside modules.

Here we describe register assignments, variable declarations, variable assignments, loops, and func-tion definitions. These can be used in all statement contexts.

8.1 Register reads and writes

Register writes occur primarily inside rules and methods.

regWrite ::= identifier <= expression

| ( expression ) <= expression

The left-hand side must have a register interface type, i.e., Reg#(t) for some type t that has arepresentation in bits. It is either an identifier or a parenthesized expression (e.g., the registerinterface could be selected from an array of register interfaces). The right-hand side must have thesame type t, i.e., it is an expression that evaluates to a value of type t. BSV allows only the so-callednon-blocking assignments of Verilog, i.e., the statement specifies that the register gets the new valueat the end of the current cycle, and is only available in the next cycle.

Following BSV’s position that all state elements (including registers) are module instances, andall interaction with a module happens through its interface, a register assignment r<=e is just aconvenient alternative notation for a method call:

r. write (e)

Similarly, if r is an expression of type Reg#(t), then mentioning r in an expression is just a convenientalternative notation for a method call:

r. read ()

Example:

Reg #(int) r; // create a register interface

mkReg #(0) the_r (r); // create a register the_r with interface r

...

...

rule ...

r <= r + 1; // Convenient notation for: r._write (r._read() + 1)

endrule

8.2 Variable and array declaration, initialization and assignment

Variables in BSV are used to name intermediate values. Unlike Verilog and SystemVerilog, variablesnever represent state, i.e., they do not hold values over time. Every variable’s type must be declared,after which it can be bound to a value one or more times.

A variable can be declared by giving its type, followed by the identifier:

varDecl ::= type identifier [ arrayDims ] ;

arrayDims ::= [ expression { , expression } ]

The declared identifier can be an array (when arrayDims is present). The expressions represent thearray dimensions, and must be constant expressions (i.e., computable during static elaboration).

A variable declaration can be combined with an initialization:

33

Page 34: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

varDeclAssign ::= type identifier [ arrayDims ] = expression ;

Currently, this initialization is only possible for non-array variables. (In the future, this restrictionwill be removed.)

(In the future, the above forms may generalize to allow multiple identifiers to be declared an intializedin one statement.)

A variable can be bound to a value:

varAssign ::= lValue = expression ;

lValue ::= identifier

| lValue . identifier

| lValue [ expression { , expression } ]

The left-hand side (lValue) in its simplest form is a simple variable (identifier). In general it can be aseries of index- and field-selections from an identifier representing a nesting of arrays and structures.The array-indexing expressions must be computable during static elaboration.

Example: declare an variable wordSize to have type integer and assign it the value 16.

integer wordSize;

wordSize = 16;

Example: declare an array identifier a of 32 elements containing int values.

int a[32];

Multiple assignments to the same variable are just a shorthand for a cascaded computation. Example:

int x;

x = 23;

// Here, x represents the value 23

x = x + 1;

// Here, x represents the value 24

Example:

int x;

x = 23;

// Here, x represents the value 23

x = ifc.meth (34);

// Here, x represents the value returned by the method call

x = x + 1;

// Here, x represents the value returned by the method call, plus 1

8.3 begin-end statements

A begin-end statement is a block that allows one to collect multiple statements into a single state-ment, which can then be used in any context where a statement is required.

<ctxt>BeginEndStmt ::= begin [ : identifier ]{ <ctxt>Stmt }

end [ : identifier ]

The optional identifier label is currently used for documentation purposes only; in the future theymay be used for hierarchical references. The statements contained in the block can contain localvariable declarations and all the other kinds of statements.

34

Page 35: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

8.4 Conditional and loop statements

Conditional statements include if statements and case statements. An if statement containsa Boolean expression, a statement representing the true arm, the keyword else, and a statementrepresenting the false arm. (Note: in the future, the else and the false arm will be optional.)

<ctxt>If ::= if ( expression )

<ctxt>Stmt

else

<ctxt>Stmt

BSV does not have the ordinary case statements of Verilog and SystemVerilog. BSV only has thepattern matching case statement of SystemVerilog. (Future versions of BSV may have both.) Casestatements are described in Section 10 on pattern matching.

BSV currently has while (and will have for loops in the future).

<ctxt>While ::= while ( expression )

<ctxt>Stmt

It is important to note that in BSV, loops do not express (time-based) behavior. Instead, they areused purely as a means to express zero-time iterative computations, i.e., they are statically unrolledand express the concatenation of multiple instances of the loop body statements. In particular, theloop condition must be evaluable during static elaboration. For example, the loop condition cannever depend on a value in a register, or a value returned in a method call, which are only knownduring execution and not during static elaboration.

Example: sum the values in an array

int a[32];

int x = 0;

int j = 0;

...

... // define the values in the array

...

while (j < 32)

x = x + a[j];

8.5 Function definitions

A function definition is introduced by the function keyword. This is followed by the type of thefunction return-value, the name of the function being defined, the formal arguments, and optionalprovisos (provisos are discussed in more detail in Section 13.1). After this is the function body andfinally,the endfunction keyword that is optionally labelled again with the function name. Eachformal argument declares an identifier and its type.

functionDef ::= functionProto functionBody

endfunction [ : identifier ]

functionProto ::= function type identifier ( [ functionFormals ] ) [ provisos ] ;

functionFormals ::= functionFormal { , functionFormal }

functionFormal ::= type identifier

The function body can contain the usual repertoire of statements: functionBody ::=action

| actionValue

| { functionBodyStmt }

35

Page 36: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

functionBodyStmt ::= <functionBody>If | <functionBody>Case

| <functionBody>BeginEndStmt

| varDecl | varAssign | varDeclAssign

| varDo | varDeclDo

| functionDef

| functionCall

| systemTaskCall

| ( expression )

| returnStmt

returnStmt ::= return expression ;

The value returned from a function can be specified in two ways, as in SystemVerilog. The firstmethod is to assign a value to the function name used as an ordinary variable. This “variable” canbe bound multiple times in the function body, including in different arms of conditionals, in loopbodies, and so on. The function body is viewed as a traditional sequential program, and value inthe special variable at the end of the body is the value returned. Alternatively, one can use anreturn statement anywhere in the function body to return a value immediately without any furthercomputation. If the value is not explicitly returned nor bound, the returned value is undefined.

Example: the boolean negation function.

function Bool not (Bool x);

if (x) not = False;

else not = True;

endfunction: not

Example: same, but using return instead.

function Bool not (Bool x);

if (x) return False;

else return True;

endfunction: not

Example: the factorial function, using a loop.

function int factorial (int n);

factorial = 1;

int j = 0;

while (j < n)

factorial = factorial * j;

endfunction: factorial

Example: the factorial function, using recursion.

function int factorial (int n);

if (n <= 1) return 1;

else return n * factorial (n - 1);

endfunction: factorial

9 Expressions

Expressions occur on the right-hand sides of variable assignments, on the left-hand and right-handside of register assignments, as actual parameters and arguments in module instantiation, functioncalls, method calls, array indexing, and so on.

36

Page 37: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

There are many kinds of primary expressions. More complex expressions are built using the condi-tional operator and unary and binary operators.

expression ::= condExpr

| operatorExpr

| exprPrimary

exprPrimary ::= identifier

| intLiteral

| stringLiteral

| systemFunctionCall

| ( expression )

| · · · see other productions · · ·

9.1 Don’t-care expressions

When the value of an expression does not matter a don’t-care expression can be used. It is writtenwith just a question mark and can be used at any type. The compiler will pick a suitable value.

exprPrimary ::= ?

A don’t-care expression is similar, but not identical to the x value in Verilog, which represents anunknown value. A don’t-care expression is unknown to the programmer, but represents a particularfixed value chosen statically by the compiler.

The programmer is encouraged to use don’t-care values where possible, both because it is usefuldocumentation and because the compiler can often choosing values that lead to better circuits.

9.2 Conditional operator

The conditional operator has the usual syntax:

condExpr ::= expression ? expression : expression

Conditional expressions have the usual semantics. In an expression e1:e2:e3, e1 must be a booleanexpression. If it evaluates to True, then the value of e2 is returned, otherwise the value of e3 isreturned.

9.3 Unary and binary operators

operatorExpr ::= unop expression

| expression binop expression

Binary operator expressions are built using the unop and binop operators listed in the followingtable, which are a subset of the operators in SystemVerilog (in the future the repertoire will growto include all the operators in SystemVerilog). The operators are listed here in order of decreasingprecedence.

37

Page 38: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

operator associativity comments+ - ! ~ n/a Unary: plus, minus, logical not, bitwise invert

* / Left multiplication, division* - Left addition, subtraction

<< >> Left left and right shift<= >= < > Left comparison ops

== != Left equality, inequality& Left bitwise and^ Left bitwise xor| Left bitwise or&& Left logical and|| Left logical or

Constructs that do not have any closing token, such as conditional statements and expressions, havelowest precedence so that, for example,

e1 ? e2 : e3 + e4

is parsed as follows:

e1 ? e2 : (e3 + e4)

and not as follows:

(e1 ? e2 : e3) + e4

9.4 Bit concatenation and selection

Bit concatenation and selection are expressed in the usual notation:

exprPrimary ::= bitConcat | bitSelect

bitConcat ::= { expression { , expression } }

bitSelect ::= exprPrimary [ expression [ : expression ] ]

In a bit concatenation each component must have the type bit[m:0] (width m + 1). The resulthas type bit[n:0] where n + 1 is the sum of the individual bit-widths.

In a bit selection, the exprPrimary must have type bit[m:0]. The indexes are inclusive, i.e., thebits selected go from the low index to the high index, inclusive. The selection has type bit[k:0]where k + 1 is the width of the selection. Since the index expressions can in general be dynamicvalues, the type-checker may not be able to figure out this type, in which case it may be necessaryto use a type cast to tell the compiler the desired result type. The type-cast specified type need notagree with width specified by the indexes– the system will truncate from the left (most-significantbits) or pad with zeros to the left as necessary.

9.5 begin-end expressions

A begin-end expression is like an “inline” function, i.e., it allows one to express a computation usinglocal variables and multiple variable assignments and then finally to return a value. A begin-endexpression is analogous to a “let-block” commonly found in functional programming languages. Itcan be used in any context where an expression is required.

38

Page 39: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

exprPrimary ::= beginEndExpr

beginEndExpr ::= begin [ : identifier ]{ beginEndExprStmt }expression

end [ : identifier ]

The optional identifier label is currently used for documentation purposes only; in the future theymay be used for hierarchical references. The statements contained in the block can contain localvariable declarations and all the other kinds of statements.

beginEndExprStmt ::= varDecl | varAssign | varDeclAssign

| functionDef

| functionCall

| systemTaskCall

| ( expression )

Example:

begin

int x2 = x * x; // x2 is local, x from surrounding scope

int y2 = y * y; // y2 is local, y from surrounding scope

x2 + y2; // returned value (sum of squares)

end

9.6 Action blocks

Any expression which is intended to act on state is called an action and has type Action.

Primitive actions are provided as methods in interfaces to predefined objects (such as registers orarrays). For example, the predefined interface for registers includes a ._write() method of typeAction:

interface Reg #(type a);

method Action _write (a x);

method a _read ();

endinterface: Reg

Section 8.1 describes special syntax for register reads and writes using non-blocking assignment sothat most of the time one never needs to mention these methods explicitly.

The programmer can create new actions only by building on these primitives, or by using Verilogmodules. Actions are combined by using action blocks:

exprPrimary ::= actionBlock

actionBlock ::= action [ : identifier ]{ actionStmt }

endaction [ : identifier ]

actionStmt ::= <action>If | <action>Case

| <action>BeginEndStmt

| regWrite

| varDecl | varAssign | varDeclAssign

| varDo | varDeclDo

| functionCall

| systemTaskCall

| ( expression )

39

Page 40: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

The action block can be labelled with an identifier, and the endaction keyword can optionally belabelled again with this identifier. Currently this is just for documentation purposes (in the future,these may be used, e.g., for hierarchical references to variables declared in the block).

Example:

action

x <= x+1;

y <= z;

endaction

The Standard Prelude defines the trivial action that does nothing:

Action noAction;

which is equivalent to the expression:

action

endaction

The Action type is actually a special case of the more general type ActionValue, described in thenext section:

typedef ActionValue #(void) Action;

9.7 ActionValue blocks

Note: this is an advanced topic and can be skipped on first reading.

Actionvalue blocks express the concept of performing an action and simultaneously returning a value.For example, the pop() method of a stack interface may both pop a value from a stack (the action)and return what was at the top of the stack (the value). ActionValue is a predefined abstract type:

ActionValue #(a)

The type parameter a represents the type of the returned value.

Actionvalues are created using actionvalue blocks. The statements in the block contain the actionsto be performed, and a return statement specifies the value to be returned.

exprPrimary ::= actionValueBlock

actionValueBlock ::= actionvalue [ : identifier ]{ actionValueStmt }

endactionvalue [ : identifier ]

actionValueStmt ::= <actionValue>If | <actionValue>Case

| <actionValue>BeginEndStmt

| regWrite

| varDecl | varAssign | varDeclAssign

| varDo | varDeclDo

| functionCall

| systemTaskCall

| ( expression )

| returnStmt

40

Page 41: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Given an actionvalue av, we use a special notation to perform the action and yield the value:

varDeclDo ::= type identifier <- expression ;

varDo ::= identifier <- expression ;

The first rule above declares the identifier, performs the action value represented by the expression,and assigns the returned value to the identifier. The second rule is similar and just assumes theidentifier has previously been declared.

Example:

interface IntStack;

method Action push (int x);

method ActionValue #(int) pop();

endinterface: IntStack

...

IntStack s1;

...

IntStack s2;

...

action

int x <- s1.pop; -- A

s2.push (x+1); -- B

endaction

In line A, we perform a pop action on stack s1, and the returned value is bound to x. If we wantedto discard the returned value, we could have omitted the “x <-” part. In line B, we perform a push

action on s2.

Note the difference between this statement:

x <- s1.pop;

and this statement:

z = s1.pop;

In the former, x must be of type int; the statement performs the pop action and x is bound tothe returned value. In the latter, z must be of type Method#(ActionValue#(int)) and z is simplybound to the method s1.pop. Later, we could say:

x <- z;

to perform the action and assign the returned value to x. Thus, the = notation simply assigns theleft-hand side to the right-hand side. The <- notation, which is only used with actionvalue right-handsides, performs the action and assigns the returned value to the left-hand side.

9.8 Function calls

Function calls are expressed in the usual notation, i.e., a function applied to its arguments, listed inparentheses:

41

Page 42: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

exprPrimary ::= functionCall

functionCall ::= exprPrimary ( expression { , expression } )

Note that the function position is specified as exprPrimary, of which identifier is just one specialcase. This is because in BSV functions are first-class objects, and so the function position can bean expression that evaluates to a function value. Function values and higher-order functions aredescribed in Section 13.2.

9.9 Static type assertions

We can assert that an expression must have a given type by using Verilog’s “type cast” notation:

exprPrimary ::= typeAssertion

typeAssertion ::= type ’ bitConcat

| type ’ ( expression )

bitConcat ::= { expression { , expression } }

In most cases such assertions are used optionally just for documentation purposes. Such assertionsare necessary in a few places where the compiler cannot work out the type of the expression (anexample is a bit-selection with run-time indexes).

In BSV although type assertions use Verilog’s type cast notation, they are never used to change anexpression’s type. They are used either to supply a type that the compiler is unable to determine byitself, or for documentation (to make the type of an expression apparent to the reader of the sourcecode).

9.10 Structure and union expressions

Section 7.3 describes how to define struct and union types. Section 8.2 describes how to declarevariables of such types.

9.10.1 Structure expressions

To create a structure value, e.g., to assign it to a structure variable or to pass it an actual argumentfor a structure formal argument, we use the following notation:

exprPrimary ::= structExpr

structExpr ::= Identifier { memberBind { , memberBind } }

| Identifier ( expression { , expression } )

memberBind ::= identifier : expression

The leading Identifier is the type name to which the structure type was typedef’d. (In futureversions of BSV, this leading Identifier will be omitted.)

In the first form of structExpr each memberBind specifies a member name (identifier) and the value(expression) it should be bound to. The members do not need to be listed in the same order as inthe original typeDef . If any member name is missing, that member’s value is undefined.

The second form of structExpr is positional, i.e., one just lists expressions representing the values ofthe members in the order they were defined in the original typeDef . In this notation, values for allthe members must be given.

Semantically, a structExpr creates a structure value, which can then be bound to a variable, passedas an argument, stored in a register, etc.

Example:

42

Page 43: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef struct { Addr pc; RegFile rf; Memory mem; } Proc;

...

Proc r;

r = Proc { pc : 0, cc : EQ };

9.10.2 Structure member selection and update

A member of a structure value can be selected with dot notation.

exprPrimary ::= exprPrimary . identifier

Example

cpu.pc

Note: Since the same member-name can occur in multiple types, the compiler uses type informationto resolve which member-name you mean when you do a member selection. Occasionally, you mayneed to add a type assertion to help the compiler resolve this.

By using it on the left-hand side of an assignment, a member selection can be used to update a fieldof a structure. Example:

cpu.pc = cpu.pc + 4;

Semantically, this can be seen as an abbreviation for:

cpu = Proc { pc: cpu.pc + 4, cc: cpu.cc };

i.e., it re-assigns the structure variable to contain a new structure value in which all members otherthan the updated member have the same value as in the old structure.

9.10.3 Tagged union expressions

To create a tagged union value, e.g., to assign it to a tagged union variable or to pass it an actualargument for a tagged union formal argument, we use the following notation:

exprPrimary ::= taggedUnionExpr

taggedUnionExpr ::= tagged identifier { memberBind { , memberBind } }

| tagged identifier expression

memberBind ::= identifier : expression

The leading identifier is a member name of a union type, i.e., it specifies which variant of the unionis being constructed.

The first form of taggedUnionExpr can be used when the corresponding member type is a structure.In this case, one directly lists the structure member bindings, enclosed in braces. Each memberBind

specifies a member name (identifier) and the value (expression) it should be bound to. The membersdo not need to be listed in the same order as in the original structure definition. If any membername is missing, that member’s value is undefined.

Otherwise, one can use the second form of taggedUnionExpr , which is the more general notation,where expression is directly an expression of the required member type.

Semantically, a taggedUnionExpr creates a tagged union value, which can then be bound to a variable,passed as an argument, stored in a register, etc.

Example:

43

Page 44: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef union tagged { int tagi; oneHot tagoh; } u deriving (Bits);

...

u x;

...

u = tagged tagi 23;

...

u = tagged tagoh (encodeOneHot (23));

Example:

typedef union tagged {

bit [4:0] Register;

bit [21:0] Literal;

struct {

bit [4:0] RegAddr;

bit [4:0] RegIndex;

} Indexed;

} InstrOperand;

...

InstrOperand orand;

...

orand = tagged Indexed { RegAddr:3, RegIndex:4 };

9.10.4 Union member selection and update

Update of tagged union variables is done using the normal assignment notation, i.e., one replacesthe current value in a tagged union variable by an entirely new tagged union value (in a structure itmakes sense to update a single member and leave the others unchanged, but in a union, one memberreplaces another).

Example:

InstrOperand orand;

...

orand = tagged Indexed { RegAddr:3, RegIndex:4 };

...

orand = tagged Register 23;

Selection of tagged union members is usually done with pattern matching, which is discussed inSection 10.

9.11 Interface expressions

Note: this is an advanced topic that may be skipped on first reading.

Section 5.2 described top-level interface declarations. Section 5.5 described definition of the interfaceoffered by a module, by defining each of the methods in the interface, using methodDef s. That isthe most common way of defining interfaces, but it is actually just a convenient alternative notationfor the more general mechanism described in this section. In particular, method definitions in amodule are a convenient alternative notation for a return statement that returns an interface valuespecified by an interface expression.

moduleStmt ::= · · ·| returnStmt

44

Page 45: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

returnStmt ::= return expression ;

expression ::= · · · see other productions · · ·| exprPrimary

exprPrimary ::= interfaceExpr

interfaceExpr ::= interface Identifier ;

{ interfaceStmt }endinterface [ : Identifier ]

interfaceStmt ::= varDecl | varDeclAssign | varAssign

| methodDef

An interface expression defines a value of an interface type. The Identifier must be an interface typein an existing interface type definition.

Example: a stack of depth 1 (using a register for storage).

interface Stack;

method push (x) if (r == tagged Invalid);

r <= tagged Valid x;

endmethod: push

method pop if (r != Invalid);

r <= tagged Invalid

endmethod: pop

method top if (r != Invalid);

return validVal (r); // discard Valid tag, return embedded value

endmethod: top

endinterface: Stack

Note that an interface expression looks similar to an interface declaration (Section 5.2) except that (a)it does not list type parameters and (b) it contains method definitions instead of method prototypes.

Interface values are first-class objects. For example, this makes it possible to write interface trans-

formers that convert one form of interface into another. Example:

interface FIFO #(a); // define interface type FIFO

method Action enq (a x);

method Action deq;

method a first;

endinterface: FIFO

interface Get #(a); // define interface type Get

ActionValue #(a) get;

endinterface: Get

// Function to transform a FIFO interface into a Get interface

function Get #(a) fifoToGet (FIFO #(a) f);

return interface Get

method get();

actionValue

f.deq();

return f.first();

45

Page 46: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

endactionValue

endmethod: get

endinterface

endfunction: fifoToGet

9.11.1 Differences between interfaces and structures

Interfaces are similar to structures in the sense that both contain a set of named items— members instructures, methods in interfaces. Both are first-class values— structures are created with structureexpressions, and interfaces are created with interface expressions. A named item is selected fromboth using the same notation— stuct.member or interface.method.

However, they are different in the following ways:

• Structures cannot contain methods. Interfaces can contain nothing but methods.9

• Structure members can be updated; interface methods cannot.

• Structure members can be selected; interface methods cannot be selected, they can only beinvoked (inside rules or other interface methods).

• Structures can be used in pattern matching; interfaces cannot.

9.12 Rule expressions

Note: This is an advanced topic that may be skipped on first reading.

Section 5.6 described definition of rules in a module. That is the most common way to define rules,but it is actually just a convenient alternative notatoin for the more general mechanism describedin this section. In particular, rule definitions in a module are a convenient alternative notation fora call to the built-in addRules() function passing it an agrument value of type Rules. Such a valueis in general created using a rule expression. A rule expression has type Rules and consists of acollection of individual rule constructs.

exprPrimary ::= rulesExpr

rulesExpr ::= rules [ : identifier ]rulesStmt

endrules [ : identifier ]

rulesStmt ::= varDecl | varAssign | varDeclAssign

| rule

A rule expression is a block, bracketed by the rules and endrules keywords, optionally labelledwith an identifier. Currently the identifier is used only for documentation, but in future versionsof BSV it may be used for hierarchical references. The individual rule construct is described inSection 5.6.

Example:

rules

Word instr = mem[pc]

rule instrExec;

case (instr)

tagged Add { r1, r2, r3 } : action

9The restriction the interfaces can contain nothing but methods may be removed in future versions of BSV.

46

Page 47: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

pc <= pc+1;

rf[r1] <= rf[r2] + rf[r3]

endaction;

tagged Jz {r1, r2} : if (r1 == 0)

action

pc <= r2;

endaction

else

noAction;

endcase

endrule

endrules

9.12.1 Aggregating and prioritizing rules

(This discussion is about a capability not currently in BSV, but which will be added in the future.)

When two (or more) rules are enabled simultaneously, it may still not be legal to fire them in thesame clock because the net state change would violate atomicity semantics. The BSV compilerproduces arbitration circuitry to maintain atomicity, i.e., hardware that will ensure that they donot fire together. The arbitration circuitry encodes a choice made by the compiler as to which ruleswill fire when multiple rules are enabled. It is often useful for the designer to be able to controlthis choice, i.e., to prioritize rules (and methods, since methods are ultimately invoked from rules).Future versions of BSV will have notations for this purpose.

10 Pattern matching

Pattern matching provides a visual and succinct notation to compare a value against structures,tagged unions and constants, and to access members of structures and tagged unions.

In BSV, pattern matching can currently be used in case statements. In future versions of BSV,pattern matching may also be used in if statements, conditional expressions, and rule conditions.

pattern ::= identifier Pattern variable| expression Constant| . expression Constant| .* Wildcard| tagged identifier [ structPattern ] Tagged union| tuplePattern Structure

structPattern ::= tuplePattern

| { identifier : pattern { , identifier : pattern } }

tuplePattern ::= { pattern { , pattern } }

A pattern is a nesting of tagged union and structure patterns with identifiers, constant expressions(expression and . expression), and the wildcard pattern .* at the leaves. For tagged union patterns,the identifier following the tagged keyword is a union member name. For tagged union patternswith void members, the nested member pattern is omitted.

Note that the first and second grammar productions overlap, since an expression can be an identifier.The first production has priority, i.e., if we encounter a naked identifier, it is interpreted as a patternvariable. Thus, an identifier used as a constant must use the third production (i.e., preceded by aperiod). All other constant expressions can omit the leading period.

If a tagged union member has a structure type, the nested pattern can be structPattern. The firstform of structPattern is a tuplePattern which just lists, recursively, a pattern for each member of the

47

Page 48: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

struct, in the definition order of the members. The second form of structPattern lists, recursively,the member names of the structure each with a pattern for that member. In this form, the membersdo not need to be given in the definition order of the structure, nor do they have to be exhaustive(members can be omitted).

A tuplePattern may be used directly for tuple types, which are described in Section 11.3.

In a future version of BSV, structPatterns can be used directly for matching against structure valueseven if they are not directly nested inside tagged unions.

A pattern always occurs in a context of known type because it is matched against an expression ofknown type. Recursively, its nested patterns also have known type. Thus a pattern can always bestatically type-checked.

Each pattern introduces a new scope; the extent of this scope is described separately for case

statements, if statements, conditional expressions and rule conditions. Each pattern variable isimplicitly declared as a new variable within the pattern’s scope. Its type is uniquely determined byits position in the pattern. Pattern variables must be unique in the pattern, i.e., the same patternvariable cannot be used in more than one position in a single pattern.

In pattern-matching, the value V of an expression is always matched against a pattern. Note thatstatic type-checking ensures that V and the pattern have the same type. The result of a patternmatch is:

• A boolean value True, if the pattern match succeeds, or False, if the pattern match fails.

• If the match succeeds, the pattern variables are bound to the corresponding members from V ,using ordinary assignment.

Each pattern is matched using the following simple recursive rule:

• A pattern variable always succeeds (matches any value), and the variable is bound to thatvalue (using ordinary procedural assignment).

• The wildcard pattern .* always succeeds.

• A constant expression pattern succeeds if V is equal to its value.

• A tagged union pattern succeeds if the value has the same tag and, recursively, if the nestedpattern matches the member value of the tagged union.

• A structure or tuple pattern succeeds if, recursively, each of the nested member patternsmatches the corresponding member values in V . In structure patterns with named mem-bers, the textual order of members does not matter, and members may be omitted. Omittedmembers are ignored.

Conceptually, if the value V is seen as a flattened vector of bits, the pattern specifies which bitsto match, with what values they should be matched and, if the match is successful, which bits toextract and bind to the pattern identifiers.

10.1 Case statements

Case statements can occur in various contexts, such as in modules, function bodies, action andactionValue blocks, and so on.

<ctxt>Case ::= case ( expression ) matches

{ <ctxt>CaseArm }

48

Page 49: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

default : <ctxt>Stmt

endcase

<ctxt>CaseArm ::= pattern : <ctxt>Stmt

The value of the expression is matched against the patterns in the case arms in the order given.At each case arm, if the pattern match succeeds, the pattern identifiers are bound to the respectivecomponents and the right-hand side statement is executed. If none of the case arms succeed, theresult is unspecified.

Example (uses the Maybe type definition of section 7.3):

case (f(a)) matches

tagged Valid x : return x;

tagged Invalid : return 0;

endcase

First, the expression f(a) is evaluated. In the first arm, the value is checked to see if it has the formtagged Valid x, in which case x is assigned the component value. If so, then the case arm succeedsand we execute return x. Otherwise, we fall through to the second case arm, and so on.

Example:

typedef union tagged {

bit [4:0] Register;

bit [21:0] Literal;

struct {

bit [4:0] RegAddr;

bit [4:0] RegIndex;

} Indexed;

} InstrOperand;

...

InstrOperand orand;

...

case (orand) matches

tagged Register r : x = rf [r];

tagged Literal n : x = n;

tagged Indexed { ra, ri } : x = mem[ra+ri];

endcase

11 Important Primitives

These primitives are available via the Standard Prelude and other standard libraries. See alsoAppendix C for more useful libraries.

11.1 The types bit and Bit

The type bit[m:0] and its synonym Bit#(m + 1) represents bit-vectors of width m + 1. thecurrent version of BSV, the lower (lsb) index must be zero. (future versions of BSV may relax thisconstraint.)

Example:

49

Page 50: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

bit [15:0] zero;

zero = 0

typedef bit [50:0] BurroughsWord;

Syntax for bit concatenation and selection is described in Section 9.4.

There is also a useful function to split a bit-vector into two sub-vectors:

function Tuple2#(bit [m:0], bit [n:0]) split (bit [mn:0] xy)

provisos (Add#(m,n,k), Add#(k,1, mn));

i.e., it takes a bit vector of size mn + 1 and returns a 2-tuple (a pair, see Section 11.3) of bit vectorsof size m + 1 and n + 1, respectively. The provisos are a somewhat complicated way of expressingthe size constraints using the built-in Add type class (in future versions of BSV you will be able tojust assert m + n + 1 = mn).

The function split is polymorphic, i.e, m and n may be different in different applications of the func-tion, but each use is fully type-checked statically, i.e., the compiler verifies the proviso, performingany calculations necessary to do so.

11.1.1 Bit-width compatibility

BSV is currently very strict about bit-width compatibility compared to Verilog and SystemVerilog,in order to reduce the possibility of unintentional errors. In BSV, the types bit[m:0] and bit[n:0]are compatible only if m = n. For example, an attempt to assign from one type to the other, whenm6=n, will be reported by the compiler as a type-checking error— there is no automatic paddingor truncation. The Standard Prelude (see Section B) contains functions such as zeroExtend()

and truncate() that may be used explicitly and conveniently to extend or truncate to a requiredbit-width.

11.2 UInt, Int

The types UInt#(n) and Int#(n) represent unsigned and signed integer data types of width n bits,respectively.

These types have all the operations from the type classes (overloading groups) Bits, Literal, Eq,Arith, Ord, Bounded, and Bitwise (see Appendix B for the specifications of these type classes andtheir associated operations).

Note: the UInt and Int types are not really primitive; they are defined completely in BSV.

11.3 Tuples

It is frequently necessary to group a small number of values together, e.g., when returning multipleresults from a function. Of course, one could define a special structure type for this purpose, butBSV predefines a number of structures called tuples that are convenient:

typedef struct { a m1; b m2; } Tuple2 #(a, b) deriving (Bits, Eq, Bounded);

typedef ... Tuple3 #(a, b, c) ...;

typedef ... ... ...;

typedef ... Tuple7 #(a, b, c, d, e, f, g) ...;

Values of these types can be created by applying a predefined family of constructor functions:

50

Page 51: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

tuple2 (e1, e2)

tuple3 (e1, e2, e3)

...

tuple7 (e1, e2, e3, ..., e7)

where the expressions eJ evaluate to the component values of the tuples.

Components of tuples can be extracted using a predefined family of selector functions:

tpl_1 (e)

tpl_2 (e)

...

tpl_7 (e)

where the expression e evaluates to tuple value. Of course, only the first two are applicable toTuple2 types, only the first three are applicable to Tuple3 types, and so on.

In using a tuple component selector, it is sometimes necessary to use a static type assertion to helpthe compiler work out the type of the result. Example:

UInt#(6)’(tpl_2 (e))

Tuple components are more conveniently selected using pattern matching. Example:

Tuple2 #(int, Bool) xy;

...

case (xy) matches

{ x, y } : ... use x and y ...

endcase

11.4 Registers

The most elementary module available in BSV is the register, which have a Reg interface. Registersare instantiated using the mkReg module, whose single parameter is the initial value of the register.Registers can also be instantiated using the mkRegU module, which takes no parameters (don’t-careinitial value).

interface Reg#(type a);

Action _write (a x);

a _read;

endinterface: Reg

module mkReg #(a initVal) (Reg#(a))

provisos

(Bits#(a, sa));

module mkRegU (Reg#(a))

provisos

(Bits#(a, sa));

Registers are polymorphic, i.e., in principle they can hold a value of any type but, of course, ulti-mately registers store bits. Thus, the provisos on the modules indicate that the type must be in theBits type class (overloading group), i.e., the operations pack() and unpack() must be defined onthis type to convert it to bits and back.

51

Page 52: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Section 8.1 describes special notation whereby one rarely uses the _write() and _read methodsexplicitly. Instead, one more commonly uses the traditional non-blocking assignment notation forwrites, and one just mentions the register interface in an expression, for reads.

Since mentioning the register interface in an expression is shorthand for applying the _read method,BSV also provides a notation for overriding this implicit read, producing an expression representingthe register interface itself:

asReg (r)

11.5 FIFOs

Package FIFO defines several useful interfaces and modules for FIFOs.

interface FIFO#(type a);

Action enq (a x);

Action deq;

a first;

Action clear;

endinterface: FIFO

module mkFIFO (FIFO#(a))

provisos (Bits#(a, as));

module mkSizedFIFO #(integer depth) (FIFO#(a))

provisos (Bits#(a, as));

The FIFO interface type is polymorphic, i.e., the FIFO contents can be of any type a. However,since FIFOs ultimately store bits, the content type a must be in the Bits type class (overloadinggroup); this is specified in the provisos for the modules.

The module mkFIFO leaves the capacity of the FIFO unspecified (the number of entries in the FIFObefore it becomes full).

The module mkSizedFIFO takes the desired capacity of the FIFO explicitly as a parameter.

Of course, when compiled, mkFIFO will pick a particular capacity, but for formal verification purposesit is useful to leave this undetermined. It is often useful to be able to prove the correctness of a designwithout relying on the capacity of the FIFO. Then, the choice of FIFO depth can only affect circuitperformance (speed, area) and cannot affect functional correctness, so it enables one to separate thequestions of correctness and “performance tuning”. Thus, it is good design practice initially to usemkFIFO and address all functional correctness questions. Then, if performance tuning is necessary,it can be replaced with mkSizedFIFO.

11.6 FIFOFs

Package FIFOF defines several useful interfaces and modules for FIFOs. The FIFOF interface is likea FIFO, but it also has methods to test if the FIFO is full or empty.

interface FIFOF a =

Action enq (a x);

Action deq;

a first;

Action clear;

52

Page 53: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Bool notFull;

Bool notEmpty;

endinterface

module mkFIFOF (FIFOF#(a))

provisos (Bits#(a, as));

module mkSizedFIFOF #(integer depth) (FIFOF#(a))

provisos (Bits#(a, as));

The module mkFIFOF leaves the capacity of the FIFO unspecified (the number of entries in the FIFObefore it becomes full). The module mkSizedFIFOF takes the desired capacity of the FIFO as anargument.

11.7 System tasks and functions

BSV supports a number of Verilog’s system tasks and functions.

11.7.1 System tasks for displaying information

systemTaskCall ::= displayTaskName ( [ expression [ , expression ] ] )| $printtimescale

displayTaskName ::= $display | $displayb | $displayo | $displayh| $write | $writeb | $writeo | $writeh

These system task calls are conceptually function calls of type Action, and can be used in any contextwhere an Action is expected.

The only difference between the $display family and the $write family is that members of theformer always output a newline after displaying the arguments, whereas members of the latter donot.

The only difference between the ordinary, b, o and h variants of each family is the format in whichnumeric expressions are displayed if there is no explicit format specifier. The ordinary $display

and $write will output, by default, in decimal format, whereas the b, o and h variants will outputin binary, octal and hexadecimal formats, respectively.

There can be any number of argument expressions between the parentheses. The arguments aredisplayed in the order given. If there are no arguments, $display just outputs a newline, whereas$write outputs nothing.

The argument expressions can be of type String, Bit#(n) (i.e., of type bit[n-1:0]), Integer, orany type that is a member of the overloading group Bits. Arguments can also be literals. Integersand literals are limited to 32 bits.

Arguments of type String are interpreted as they are displayed. The characters in the string areoutput literally, except for certain special character sequences beginning with a % character, whichare interpreted as format-specifiers for subsequent arguments. The following format specifiers aresupported:

%d Output in decimal format%b Output in binary format%o Output in octal format%h Output in hexadecimal format

53

Page 54: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

%c Output a character with given ASCII code

%s Output a string (argument must be a string)

%t Output in time format

The $printtimescale system task outputs the time unit and precision of the module in which it iscalled.

11.7.2 System tasks for stopping simulation

systemTaskCall ::= $finish [ ( expression ) ]| $stop [ ( expression ) ]

These system task calls are conceptually function calls of type Action, and can be used in any contextwhere an Action is expected.

The $finish task causes simulation to stop immediately and exit back to the operating system. The$stop task causes simulation to suspend immediately and enter an interactive mode. The optionalargument expresions can be 0, 1 or 2, and control the verbosity of the diagnostic messages printedby the simulator. the default (if there is no argument expression) is 1.

11.7.3 System tasks for VCD dumping

systemTaskCall ::= $dumpvars | $dumpon | $dumpoff

These system task calls are conceptually function calls of type Action, and can be used in any contextwhere an Action is expected.

A call to $dumpvars starts dumping all the state elements in the design to the VCD file.

Subsequently, a call to $dumpoff stops dumping, and a call to $dumpon resumes dumping.

11.7.4 System functions returning the current time

systemFunctionCall ::= $time | $stime

These system function calls can be used in any context where an expression is expected.

The $time function returns a 64-bit integer representing time, scaled to the timescale unit of themodule that invoked it.

The $stime function returns a 32-bit integer representing time, scaled to the timescale unit of themodule that invoked it. If the actual simulation time does not fit in 32 bits, the lower-order 32 bitsare returned.

12 Guiding The Compiler With Pragmas And Assertions

This section describes how to guide the compiler in some of its decisions using pragmas and assertions,which are expressed with Verilog’s attribute syntax.

attributeInstance ::= (* attrSpec { , attrSpec } *)

attrSpec ::= attrName [ = expression ]

attrName ::= identifier |Identifier

54

Page 55: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

12.1 Pragmas

In addition to compiler flags on the command line, it is possible to guide the compiler with pragmasthat are included in the BSV source code.

pragma ::= attributeInstance

Pragmas can be associated with a number of different language constructs such as module, interfaceand function definitions. A given pragma declaration is applied to the first language construct thatfollows the declaration. The following table summarizes the available pragmas and the languageconstructs to which they may be applied.

Pragma Name Pragma Description Methods Interfaces Functions Rules Modules

synthesize synthesize to Verilog/C XRSTN= rename reset signal XCLK= rename clock signal X

bit blast bit blast the ports Xscan insert= insert scan chain ports Xalways ready no ready signals X X X

always enabled execute on every cycle X X XRDY= rename ready signal X

EN= rename enable signal Xnoinline don’t inline the function X

12.1.1 Pragma synthesize

When the compiler generates code for a module it normally tries to integrate all definitions into onebig module. If this is not desirable for some reason you can use the synthesize pragma to instructthe compiler to generate Verilog/C modules for only parts of the design.

12.1.2 Pragma RSTN=

By default, the BSV compiler names the asserted low reset signal associated with each module RST_N.The RST_N= pragma is used to specify an alternate name for the reset signal.

12.1.3 Pragma CLK=

By default, the BSV compiler names the clock signal associated with each module CLK. The CLK=

pragma is used to specify an alternate name for the clock signal.

12.1.4 Pragma bit_blast

Do“bit blasting”of the generated ports, i.e., split ports that consist of multiple bits into the individualbits, and also make all port names upper case.

12.1.5 Pragma scan_insert=

Put extra ports used for scan insertion into the generated Verilog code. The number specifices thenumber of scan chains to insert.

55

Page 56: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

12.1.6 Pragma always_enabled

This pragma can be applied either to an interface or to an individual interface method. If it isapplied to an interface, it affects all the methods included in that inerface. This pragma specifiesthat there should be no enable signal for the associated interface methods. The methods will beexecuted on every clock cycle, and the compiler verifies that the caller does this.

12.1.7 Pragma always_ready

This pragma can be applied either to an interface or to an individual interface method. If it is appliedto an interface, it affects all the methods included in that inerface. This pragma specifies that noready signals should be generated. The compiler verifies that the associated interface methods arepermanently ready.

12.1.8 Pragma RDY=

By default, the BSV compiler names the ready signal associated with each interface method method-

name RDY. The RDY= pragma is used to specify an alternate name for a ready signal.

12.1.9 Pragma EN=

By default, the BSV compiler names the enable signal associated with each interface method method-

name EN. The EN= pragma is used to specify an alternate name for a enable signal.

12.1.10 Pragma noinline

The noinline pragma is applied to functions. It tells the compiler not to inline the function, but togenerate code for it directly. The function has same type restrictions as for interface methods thatare involved in code generation. The noinline pragma can only be applied to functions that aredefined at the top level. The following example illustrates its use.

(* noinline *)

function Bit#(LogK) popCK(Bit#(K) x);

return (popCountTable(x));

endfunction: popCK

12.2 Assertions

Assertions instruct the compiler to report an error unless it can verify that the generated codesatisfies a particular condition. An assertion associated with a rule affects the rule that immediatelyfollows it and all rules nested within that rule. The syntax for assertions is the same as that forattributes.

ruleAssertion ::= attributeInstance

Rule assertions are not triggered until the generation of Verilog or C code for the module thatincludes them. The available assertions and the language constructs to which they may be appliedare summarized in the following table.

56

Page 57: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Asertion Name Assertion Description Methods Interfaces Functions Rules Modules

fire when enabled rule should always Xfire when enabled

no implicit conditions rule should not have Ximplicit conditions

12.2.1 Assertion fire_when_enabled

This asserts that a rule is scheduled to fire whenever its predicate and its implicit conditions aretrue, i.e., when they are true, there are no scheduling conflicts that will prevent it from firing.

12.2.2 Assertion no_implicit_conditions

This asserts that interface methods called within the rule do not have implicit conditions thatcontribute to its enabling, i.e., only the explicit rule predicate controls whether it is enabled or not.

13 Advanced topics

This section can be skipped on a first reading.

13.1 Type classes (overloading groups) and provisos

Note: For most BSV programming, one just needs to know about a few predefined type classes suchas Bits and Eq, about provisos, and about the automatic mechanism for defining the overloadedfunctions in those type classes using a deriving clause. The brief introduction in Sections 4.2 and4.3 should suffice.

This section is intended for the advanced programmer who may wish to define new type classes(using a typeclass declaration), or explicitly to define overloaded functions using an instance

declaration.

In programming languages, the term overloading refers to the use of a common function name oroperator symbol to represent some number (usually finite) of functions with distinct types. Forexample, it is common to overload the operator symbol + to represent integer addition, floatingpoint addition, complex number addition, matrix addition, and so on.

Note that overloading is distinct from polymorphism, which is used to describe a single functionor operator that can operate at an infinity of types. For example, in many languages, a singlepolymorphic function arraySize() may be used to determine the number of elements in any array,not matter what the type of the contents of the array.

A type class (or overloading group) further recognizes the fact that overloading is often performedwith related groups of function names or operators, giving the group of related functions and opera-tors a name. For example, the type class Ord contains the overloaded operators for order-comparison:<, <=, >, and >=.

If we specify the functions represented by these operator symbols for the types int, Bool, bit[m:0],and so on, we say that those types are instances of the Ord type class.

A proviso is a (static) condition attached to some constructs. A proviso requires that certain typesinvolved in the construct must be instances of certain type classes. For example, a generic sort

57

Page 58: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function for sorting lists of type List#(t) will have a proviso (condition) that t must be an instanceof the Ord type class, because the generic function uses an overloaded comparison operator fromthat type class, such as < or >.

Type classes are created explicitly using a typeclass declaration (Section 13.1.2). Further, a typeclass is explicitly populated with a new instance type t using an instance declaration (Section13.1.3), in which one provides the specifications for the overloaded functions for the type t.

13.1.1 Provisos

Consider the following function prototype:

function List#(t) sort (List#(t) xs)

provisos (Ord#(t));

It expresses the idea that the sorting function takes an input list xs of items of type t (presumablyunsorted), and produces an output list of type t (presumably sorted). In order to perform itsfunction it needs to compare elements of the list against each other using an overloaded comparisonoperator such as <. This, in turn, requires that the overloaded operator be defined on objects oftype t. This is exactly what is expressed in the proviso, i.e., that t must be an instance of the typeclass (overloading group) Ord which contains the overloaded operator <.

Thus, it is ok to apply sort to lists of Integers or lists of Bools, because those types are instancesof Ord, but it is not ok to apply sort to a list of, say, some interface type Ifc (assuming Ifc is notan instance of the Ord type class).

The syntax of provisos is the following:

provisos ::= provisos ( proviso { , proviso } )

proviso ::= Identifier type { , type }

In each proviso, the Identifier is the name of type class (overloading group). In most provisos,the type class name T is followed by a single type t, and can be read as a simple assertion that tis an instance of T , i.e., that the overloaded functions of type class T are defined for the type t. Insome provisos the type class name T may be followed by more than one type t1, ..., tn and theseexpress more general relationships. For example, a proviso like this:

provisos (Bits#(MacAddress, 48))

can be read literally as saying that the types MacAddress and 48 are in the Bits type class, orcan be read more generally as saying that values of type MacAddress can be converted to and fromvalues of the type bit[47:0] using the pack and unpack overloaded functions of type class Bits.

We sometimes also refer to provisos as contexts, i.e., they constrain the types that may be usedwithin the construct to which the provisos are attached.

Occasionally the compiler may be unable to figure out how to resolve an overloading (the context istoo weak). Usually the compiler’s error message is a strong hint about what information is missing.In these situations it may be necessary for the programmer to guide the compiler by adding moretype information to the program, in either or both of the following ways:

• Add a static type assertion (Section 9.9) to some expression that narrows down its type.

• Add a proviso to the surrounding construct.

58

Page 59: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

13.1.2 Type class declarations

A new class is declared using the following syntax:

typeclassDef ::= typeclass typeclassIde typeFormals [ provisos ] ;{ overloadedDef }

endtypeclass [ : ] Identifier

typeclassIde ::= Identifier

overloadedDef ::= functionProto

| varDecl

The typeclassIde is the newly declared class name. The typeFormals represent the types that will beinstances of this class. These typeFormals may themselves be constrained by provisos , in which casethe classes named in provisos are called the“super type classes”of this type class. The overloadedDef sdeclare the overloaded variables or function names, and their types.

Example (from the Prelude):

typeclass Literal #(type a);

function a fromInteger (Integer x);

endtypeclass: Literal

This defines the type class Literal. Any type a that is an instance of Literal must have anoverloaded function called fromInteger that converts an Integer value into the type a. In fact,this is the mechanism the BSV uses to interpret integer literal constants, e.g., to resolve whether aliteral like 6847 is to be interpreted as a signed integer, an unsigned integer, a floating point number,a bit value of 10 bits, a bit value of 8 bits, etc. (This is described in more detail in Section 2.3.1.

Example (from a predefined type class in BSV):

typeclass Bounded #(type a);

a minBound;

a maxBound;

endtypeclass

This defines the type class Bounded. Any type a that is an instance of Bounded will have two valuedcalled minBound and maxBound which represent the minimum and maximum of all values of thistype, respectively.

Example (from a predefined type class in BSV): 10

typeclass Arith #(type a) provisos (Literal#(a));

function a \+ (a x1, a x2);

function a \- (a x1, a x2);

function a negate (a x1);

function a \* (a x1, a x2);

endtypeclass

This defines the type class Arith with super type class Literal, i.e., the proviso states that in orderfor a type a to be an instance of Arith it must also be an instance of the typeclass Literal. Further,it has four overloaded functions with the given names and types. Said another way, a type that isan instance of the Arith type class must have a way to convert integer literals into that type, andit must have addition, subtraction, negation and multiplication defined on it.

10We are using Verilog’s notation for escaped identifiers to treat operator symbols as ordinary identifiers. Thenotation allows an identifier to be constructed from arbitrary characters beginning with a backslash and ending witha whitespace (the backslash and whitespace are not part of the identifier.)

59

Page 60: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

13.1.3 Declarations of type class instances

A type can be declared to be an instance of a class in two ways, with a general mechanism or witha convenient shortcut. The general mechanism of instance declarations is the following:

typeclassInstanceDef ::= instance Identifier # ( type { , type } ) provisos ;

{ varAssign | varDeclAssign | functionDef }endinstance [ : identifier ]

This says that the types are an instance of type class Identifier with the given provisos. The varAs-

signs, varDeclAssigns and functionDef s specify the implementation of the overloaded identifiers ofthe type class.

The shortcut mechanism is to attach a deriving clause to an enum, struct or tagged union typedef

declaration and let the compiler do the work. In this case the compiler chooses the “obvious”implementation of the overloaded functions (details in the following sections). The only type classesfor which deriving can be used for general types are Bits, Eq , Ord and Bounded. Furthermore,deriving can be used for any class if the type is a data type that is isomorphic to a type that hasan instance for the derived class.

derives ::= deriving ( typeclassIde { , typeclassIde } )

13.1.4 The Bits type class (overloading group)

The type class Bits contains the types that are convertible to bit strings of a certain size. Manyconstructs have membership in the Bits class as a proviso, such as putting a value into a register,array, or FIFO.

Example: the Bits typeclass definition (which is actually predefined in BSV) looks something likethis:

typeclass Bits#(a, n);

function Bit#(n) pack (a x);

function a unpack (Bit#(n) y);

endtypeclass

Here, a represents the type that can be converted to/from bits, and n is always instantiated by asize type (Section 4) representing the number of bits needed to represent it. Implementations ofmodules such as registers and FIFOs use these functions to convert between values of other typesand the bit representations that are really stored in those elements.

Example: the most trivial instance declaration states that a bit vector can be converted to a bitvector:

instance Bits# (Bit#(k), k);

function Bit#(k) pack (Bit#(k) x);

return x;

endfunction: pack

function Bit#(k) unpack (Bit#(k) x);

return x;

endfunction: unpack

endinstance

Both the pack() and unpack() functions are defined to be identity functions.

Example:

60

Page 61: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef enum { Red, Green, Blue } Color deriving (Eq);

instance Bits #(Color, 2);

function Bits#(2) pack (Color c);

if (c == Red) return 3;

else if (c == Green) return 2;

else return 1; // (c == Blue)

endfunction: pack

function Color unpack (Bits#(2) x);

if (x == 3) return Red;

else if (x == 2) return Green;

else if (x == 1) return Blue;

else $error("Illegal code 0 for unpacking a Color’’);

endfunction: unpack

endinstance

Note, the deriving (Eq) permits us to use the equality operator == on Color types in the pack

function. Red, Green and Blue are coded as 3, 2 and 1, respectively.

The SizeOf pseudo-function

The pseudo-function SizeOf(t), that can be applied to a type t to get its corresponding bit size.

13.1.5 Deriving Bits

When attaching a deriving(Bits) clause to a user-defined type, the instance derived for the Bits

type class can be described as follows:

• For an enum type it is simply an integer code, starting with 0 for the first enum constantand incrementing by 1 for each subsequent enum constant. The number of bits used is theminimum number of bits needed to represent distinct codes for all the enum constants.

• For a struct type it is simply the the concatenation of the bits for all the members. The firstmember is in the leftmost bits (most significant) and the last member is in the rightmost bits(least significant).

• For a tagged union type, all values of the type occupy the same number of bits, regardless ofwhich member it belongs to. The bit representation consists of two parts— a tag on the left(most significant) and a member value on the right (least significant).

The tag part uses the minimum number of bits needed to code for all the member names. Thefirst member name is given code 0, the next member name is given code 1, and so on.

The size of the member value part is always the size of the largest member. The member valueis stored in this field, right-justified (i.e., flush with the least-significant end). If the membervalue requires fewer bits than the size of the field, the intermediate bits are “don’t care” bits.

Example:

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

This is the same type as in the previous section except that Red, Green and Blue are now coded as0, 1 and 2, instead of 3, 2, and 1, respectively, because the canonical choice made by the compiler isto code consecutive labels incrementing from 0.

Example:

61

Page 62: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef enum { False, True} Bool deriving (Bits);

The type Bool is represented with 1 bit. False is represented by 0 and True by 1.

Example:

typedef struct { Bit#(8) foo; Bit#(16) bar } Glurph deriving (Bits);

The type Glurph is represented in 24 bits, with foo in the upper 8 bits and bar in the lower 16 bits.

Example:

typedef struct{ x :: int; y :: int } Coord deriving (Bits);

The type Coord is represented in 64 bits, with x in the upper 32 bits and y in the lower 32 bits.

typedef union tagged {

void Invalid;

a Valid;

} Maybe #(a)

deriving (Bits);

is represented in 1 + n bits, where n bits are needed to represent values of type a. If the leftmostbit is 0 (for Invalid) the remaining n bits are unspecified (“don’t care”). If the leftmost bit is 1 (forValid) then the remaining n bits will contain a value of type a.

13.1.6 Deriving Eq

The Eq typeclass contains the overloaded operators == (logical equality) and != (logical inequality):

typeclass Eq #(type a);

function Bool \== (a x1, a x2);

function Bool \!= (a x1, a x2);

endtypeclass: Eq

When deriving(Eq) is present on a a user-defined type definition t, the compiler defines theseequality/inequality operators for values of type t. It is the natural recursive definition of theseoperators, i.e.,

• If t is an enum type, two values of type t are equal if they represent the same enum constant.

• If t is a struct type, two values of type t are equal if the corresponding members are pairwiseequal.

• If t is a tagged union type, two values of type t are equal if they have the same tag (membername) and the two corresponding member values are equal.

62

Page 63: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

13.1.7 Deriving Bounded

The predefined type class Bounded contains two overloaded identifiers minBound and maxBound rep-resenting the minimum and maximum values of a type a:

typeclass Bounded #(type a);

a minBound;

a maxBound;

endtypeclass

The clause deriving(Bounded) can be attached to any user-defined enum definition t, and thecompiler will define the values minBound and maxBound for values of type t as the first and last enumconstants, respectively.

The clause deriving(Bounded) can be attached to any user-defined struct definition t with theproviso that the type of each member is also an instance of Bounded. The compiler-defined minBound

(or maxBound) will be the struct with each member having its respective minBound (respectively,maxBound).

13.1.8 Deriving for isomorphic types

Generally speaking, the deriving(...) clause can only be used for certain predefined type classessuch as Bits, Eq and Bounded. However there is a special case where it can be used for any typeclass. When a user-defined type t is isomorphic to an existing type t′, then all the functions on t′

automatically work on t, and so the compiler can trivially derive a function on t by just using thecorresponding function on t′.

There are two situations where a newly defined type is isomorphic to an old type: a structure ortagged union with precisely one member, e.g.,

typedef struct { t′ x } t deriving (anyClass);typedef union tagged { t′ x } t deriving (anyClass);

One sometimes defines such a type precisely for type-safety reasons because the new type is distinctfrom the old type although isomorphic to it, so that it is impossible to accidentally use a t value ina t′ context and vice versa.

Example:

typedef struct Apple#(UInt#(32)) x Apples deriving (Literal, Arith);

...

Apples five;

...

five = 5; // ok, since RHS applies ’fromInteger()’ from Literal

// class to Integer 5 to create an Apples value

function Apples eatApple (Apples n);

return n - 1; // ’1’ is converted to Apples by fromInteger()

// ’-’ is available on Apples from Arith class

endfunction: eatApple

13.2 Higher-order functions

In BSV it is possible to write an expression whose value is a function value. These function valuescan be passed as arguments to other functions, returned as results from functions, and even carriedin data structures.

63

Page 64: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Example:

function Arr#(n,b) mapArr (function b f (a x),

Arr#(n,a) xs);

Arr#(n,b) ys;

for (j=0; j < n; j=j+1)

ys [j] = f (xs [j]);

return ys;

endfunction: mapArr

function int sqr (int x);

return x * x;

endfunction: sqr

Arr#(100,int) as = ...; // initialize array as

Arr#(100,int) bs = mapArr (sqr, as);

The function mapArr is polymorphic, i.e., is defined for any size type n and value types a and b. Ittakes two arguments:

• A function f with input of type a and output of type b.

• An array xs of size n containing values of type a.

and its result is a new array ys that is also of size n and containing values of type b, such thatys[j]=f(xs[j]). In the last line, we call mapArr passing it the sqr function and the array as toproduce an array bs which contains the squared versions of all the elements of array as.

Observe that in the last line, the expression sqr is a function-valued expression, representing thesquaring function. Similarly inside mapArr, the identifier f is a function-valued identifier.

The same function mapArr could be called with a variety of arguments:

Arr#(100,int) = mapArr (shiftLeft, as);

or

Arr#(100,Bool) = mapArr (isEven, as);

i.e., mapArr captures, in one place, the generic idea of “applying some function to all elements of anarray and returning all the results in another array”.

This is a very powerful idea enabled by treating functions as first-class values. Here is anotherexample, of practical use in many hardware designs:

interface SearchableFIFO #(type a);

... usual enq() and deq() methods ...

method Bool search (a y);

endinterface: SearchableFIFO

64

Page 65: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

module mkSearchableFIFO #(type a, function Bool f(a x, a y))

(SearchableFIFO#(t));

...

method search (a y);

... apply f(x, y) to each element of the FIFO, ...

... return OR of all results ...

endmethod: search

endmodule: mkSearchableFIFO

The SearchableFIFO interface is like a normal FIFO interface (contains usual enq() and deq()

methods), but it has an additional bit of functionality. It has a search() method to which you canpass a search-key y, and it searches the FIFO using that key returning True if the search succeeds.

Inside the mkSearchableFIFOmodule, the method applies some element-test f to the search key andeach element of the FIFO and OR’s all the results. The particular element-test function f to be usedis passed in as a parameter to mkSearchableFIFO. In one instantiation of mkSearchableFIFO wemight pass in the equality function for this parameter (“search this FIFO for this particular element”).In another instantiation of mkSearchableFIFOwe might pass in the “greater-than”function (“searchthis FIFO for any element greater than the search key”). Thus, a single FIFO definition capturesthe general idea of being able to search a FIFO, and can be customized for different applications bypassing in different search functions to the module constructor.

A final important point is that all this is perfectly synthesizable in BSV, i.e., the compiler can produceRTL hardware for such descriptions.

13.3 Calling foreign functions

This section describes how to encapsulate a Verilog function inside a BSV wrapper.

TBD: This section needs to be updated.

14 Interfacing to Verilog

This section describes two (related) mechanisms:

• How to embed a Verilog module in a BSV module, i.e., how to encapsulate an a Verilog moduleinside a BSV shim. All BSV primitives (registers, FIFOs, ...) are implemented this way.

• How to embed a BSV module in a Verilog module, i.e., how a surrounding Verilog module canuse a BSV module as a client.

TBD: This section needs to be updated.

externModuleImport ::= ... to be filled in ...

15 Interfacing to C

The BSV compiler can produce two kinds of output: RTL-level Verilog, and C. When producingVerilog, the code can be run on standard Verilog simulators and interfaced to other Verilog code.When producing C, the output can be run under Bluespec, Inc.’s C-based simulator which onlyrequires a standard workstation environment with a standard C compiler. The C-based simulatoris often used during early debugging, offering several advantages such as simulation speed, moresource-level debugging, and so on.

65

Page 66: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

This section describes how to connect user-written C code to the C output from the BSV compiler,for custom testbenches and for user-defined models.

TBD: This section needs to be updated.

References

[Acc04] Accellera. SystemVerilog 3.1a Language Reference Manual: Accellera’s Extensions to Ver-ilog (R), 2004. See: www.accelera.org, www.systemverilog.org.

[IEE01] IEEE. IEEE Standard Verilog (R) Hardware Description Language, March 2001. IEEE Std1364-2001.

[IEE02] IEEE. IEEE Standard VHDL Language Reference Manual, IEEE Std 1076-1993, 2002.

[Ter03] Terese. Term Rewriting Systems. Cambridge University Press, 2003.

66

Page 67: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

A Keywords

All keywords use lowercase letters only.

A

F

a

action endaction

actionvalue endactionvalue

begin

bit

case endcase

default

deriving

else

end

enum

export

f

function endfunction

if

import

instance endinstance

interface endinterface

matches

method endmethod

module endmodule

package endpackage

provisos

return

rule endrule

rules endrules

struct

tagged

type

typeclass endtypeclass

typedef

union

void

while

67

Page 68: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

B The standard Prelude

Note: this section is currently under revision to improve the documentation.

The listing in this section is useful for knowing what are the primitive types, classes, instances, etc.

In the following, there are certain lines that look like type signatures of type identifiers, whereas itis more familiar to see type signatures of value identifiers. These are meant for internal use, andexpress the idea that, for example, certain type parameters can only be filled by size types (#) andother type parameters can only be filled by non-size types (*).

The symbols # and * represent “the type of types” and are traditionally called “kinds”.

The standard Prelude is automatically included in all packages, i.e., the programmer does not needto take any special action to use any of the facilities described here. Please see also Section C for anumber of useful libraries that must be explicitly imported into a package in order to use them.

The Prelude consists of the following parts.

B.1 Classes

These classes are wired in to the compiler.

class (Add :: # -> # -> # -> *) a b c | a b -> c, b c -> a, c a -> b where { }

class (Mul :: # -> # -> # -> *) a b c | a b -> c, b c -> a, c a -> b where { }

class (Div :: # -> # -> # -> *) a b c | a b -> c where { }

class (Max :: # -> # -> # -> *) a b c | a b -> c where { }

typeclass Monad #(type m);

function m#(b) bind(m#(a) x1, function m#(b) x2(a x1));

function m#(a) return(a x1);

endtypeclass

The class of monads that admit recursion.

typeclass MonadFix #(type m)

provisos (Monad#(m));

function m#(a) mfix(function m#(a) x1(a x1));

endtypeclass

The class of types that can be converted to bit vectors and back.

typeclass Bits #(type a, type n)

dependencies a -> n;

function Bit#(n) pack(a x1);

function a unpack(Bit#(n) x1);

endtypeclass

The class of types on which equality is defined.

typeclass Eq #(type a);

function Bool (==)(a x1, a x2);

function Bool (/=)(a x1, a x2);

endtypeclass

68

Page 69: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

The class of types for which integer literals can be used.

typeclass Literal #(type a);

function a fromInteger(Integer x1);

endtypeclass

The class of types on which comparison operations are defined.

typeclass Ord #(type a);

function Bool (<)(a x1, a x2);

function Bool (<=)(a x1, a x2);

function Bool (>)(a x1, a x2);

function Bool (>=)(a x1, a x2);

endtypeclass

The class of types with a finite range.

typeclass Bounded #(type a);

a minBound;

a maxBound;

endtypeclass

The class of types on which bitwise operations are defined.

typeclass Bitwise #(type a);

function a (&)(a x1, a x2);

function a (|)(a x1, a x2);

function a (^)(a x1, a x2);

function a invert(a x1);

function a (<<)(a x1, Nat x2);

function a (>>)(a x1, Nat x2);

endtypeclass

The class of types on which arithmetic ops are defined.

typeclass Arith #(type a)

provisos (Literal#(a));

function a (+)(a x1, a x2);

function a (-)(a x1, a x2);

function a negate(a x1);

function a (*)(a x1, a x2);

endtypeclass

The class of types on which selection of elements may be done using square-bracket notation (inBSV).

typeclass PrimSelectable #(type a, type b, type c);

instance PrimSelectable #(Bit#(n), Nat, Bit#(1))

provisos (Add#(m, 1, n));

69

Page 70: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

B.2 Data Types

B.2.1 Action

The type for actions on the lowest level.

primitive type PrimAction :: *

interface ActionValue #(type a);

instance Monad #(ActionValue);

instance MonadFix #(ActionValue);

Extract the PrimAction part of an ActionValue.

function PrimAction toPrimAction(ActionValue#(a) a);

Construct an ActionValue (with a “don’t care” value) from a PrimAction.

function ActionValue#(a) fromPrimAction(PrimAction a);

typedef ActionValue#(void) Action;

An empty Action.

Action noAction;

Assign an ActionValue to a register.

function Action (:<-)(Reg#(a) r, ActionValue#(a) av);

B.2.2 Bit

primitive type Bit :: # -> *

instance Bits #(Bit#(k), k);

instance Eq #(Bit#(n));

instance Literal #(Bit#(n));

instance Ord #(Bit#(n));

instance Bounded #(Bit#(n));

instance Bitwise #(Bit#(n));

instance Arith #(Bit#(n));

Concatenate two bit vectors into one.

70

Page 71: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function Bit#(k) (++)(Bit#(n) x, Bit#(m) y)

provisos (Add#(n, m, k));

Split a bit vector into two bit vectors (higher-order bits, lower-order bits).

function Tuple2 #(Bit#(n), Bit#(m)) split(Bit#(k) x)

provisos (Add#(n, m, k));

function Bit#(m) zeroExtend(Bit#(n) x)

provisos (Add#(k, n, m));

function Bit#(m) signExtend(Bit#(n) x)

provisos (Add#(k, n, m));

Trucate by discarding higher-order bits.

function Bit#(m) truncate(Bit#(n) x)

provisos (Add#(k, m, n));

Comparisons and shifts, interpreting as signed values.

function Bool signedLT(Bit#(n) x, Bit#(n) y);

function Bool signedLE(Bit#(n) x, Bit#(n) y);

function Bool signedGT(Bit#(n) x, Bit#(n) y);

function Bool signedGE(Bit#(n) x, Bit#(n) y);

function Bit#(n) signedShiftRight(Bit#(n) x, Nat c);

B.2.3 Bool

typedef enum {False, True} Bool deriving (Eq, Bits, Bounded);

function Bool not(Bool x);

function Bool (&&)(Bool x, Bool y);

function Bool (||)(Bool x, Bool y);

B.2.4 Empty

An interface with no methods.

interface Empty;

endinterface: Empty

71

Page 72: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

B.2.5 Integer

The Integer type is a built-in type in the compiler.

primitive type Integer :: *

instance Literal #(Integer);

instance Eq #(Integer);

instance Ord #(Integer);

instance Arith #(Integer);

function Integer div(Integer x, Integer y);

function Integer mod(Integer x, Integer y);

exp :: Integer -> Integer -> Integer;

log2 :: Integer -> Integer;

B.2.6 Maybe

Used for “optional” values.

typedef union tagged {

void Nothing;

a Just;

} Maybe #(type a) deriving (Eq, Bits);

The Maybe type is a monad.

instance Monad #(Maybe);

Pick out the element of a Just.

unJust :: Maybe#(a) -> a;

Test for Just.

isJust :: Maybe#(a) -> Bool;

B.2.7 Nat

typedef Bit#(32) Nat;

72

Page 73: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

B.2.8 Either

Used for values that are either of type a or of type b.

typedef tagged union {

a Left;

b Right;

} Either #(type a, type b) deriving (Eq, Bits);

B.2.9 Registers

interface Reg #(type a);

method Action _write(a x1);

method a _read();

endinterface: Reg

Make a register with a given reset value. Reset logic is synchronous.

module mkReg#(a v)(Reg#(a))

provisos (Bits#(a, sa));

Make a register without any reset; initial simulation value is alternating 01 bits.

module mkRegU(Reg#(a))

provisos (Bits#(a, sa));

Make a register with a given reset value. Reset logic is asynchronous.

module mkRegA#(a v)(Reg#(a))

provisos (Bits#(a, sa));

Treat a register as a register, i.e., suppress the normal behavior where it implicitly represents thevalue that it contains.

function Reg#(a) asReg(Reg#(a) r);

B.2.10 Rules

The Rules type is a built-in type in the compiler.

primitive type Rules :: *

Symmetric union of two sets of rules.

function Rules (<+>)(Rules x, Rules y);

Union of two sets of rules, with rules on the left getting precedence.

function Rules (<+)(Rules x, Rules y);

Union of two sets of rules, with rules on the right getting precedence.

function Rules (+>)(Rules x, Rules y);

73

Page 74: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

B.2.11 String

The String type is a built-in type in the compiler.

primitive type String :: *

String concatenation.

function String (+++)(String x, String y);

instance Eq #(String);

B.2.12 Module

The Module type is a built-in type in the compiler.

primitive type Module :: * -> *

instance Monad #(Module);

instance MonadFix #(Module);

mfix = primModuleFix;

endinstance

B.3 Miscellaneous

Generate an error message and die.

function a error(String s);

Generate a warning; compilation continues.

function a warning(String s, a a);

Generate a compilation message.

function a message(String s, a a);

Generate a compilation message in a monad.

function m#(void) messageM(String s)

provisos (Monad#(m));

Absolute value.

function a abs(a x)

provisos (Arith#(a), Ord#(a));

Infix application. Basically for precedence-changing so that you can, for example, write f $ g y

instead of f (g y). Useful when g y is a big expression and you don’t want to parenthesize it.

74

Page 75: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function b ($)(function b f(a x1), a x);

return (f(x));

endfunction: $

($) :: (a -> b) -> a -> b

($) f x = f x

Function composition11

function (function c (a x0)) (·)(function c f(b x1), function b g(a x2));

function c h(a x);

return f(g(x));

endfunction: h

return (h);

endfunction: ·

Identity function

function a id(a x);

return (x);

endfunction: id

Make a function curried

curry :: ((a, b) -> c) -> (a -> b -> c)

Make a function uncurried

uncurry :: (a -> b -> c) -> ((a, b) -> c)

Constant function

function a const(a x, b y);

return (x);

endfunction: const

Argument flip

flip :: (a -> b -> c) -> (b -> a -> c)

Repeat a function while a predicate holds

function a while(function Bool p(a x1), function a f(a x1), a x);

return (p(x) ? while(p, f, f(x)) : x);

endfunction: while

Maximum of two values

function a max(a x, a y)

provisos (Ord#(a));

return (x >= y ? x : y);

endfunction: max

11You can get · by typing C-q 267 in (X)Emacs or C-k .M in Vim insert mode.

75

Page 76: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Minimum of two values

function a min(a x, a y)

provisos (Ord#(a));

return (x <= y ? x : y);

endfunction: min

Force the type of the first argument to be the same as the second.

function a asTypeOf(a x, a y);

return (x);

endfunction: asTypeOf

Any function can be lifted into a monadic version.

function m#(b) liftM(function b f(a x1), m#(a) x)

provisos (Monad#(m));

76

Page 77: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C Libraries

Note: this section is currently under revision to improve the documentation.

Section 11 defined some important primitives. Section B defined the standard Prelude, which isautomatically imported into every package. This section describes BSV’s large and continuouslygrowing collection of libraries that pre-package common and useful programming idioms and hard-ware idioms.

To use any of these libraries in a package, the programmer must explicitly import it into the packageusing an import clause.

Useful data structures:Array FIFO FIFOF IVec List ListN

Useful control structures (sequential state machines, loops, etc.):ActionSeq Loop Once

File I/O during execution in the C back-end:FileIO

Monad facilities:Monad ModuleCollect

Producing optimized boolean functions:Boolify Tabulate

Rigid synchronous pipelines:Pull Push RPush

Useful circuits:BitonicSort LFSR (Linear Feedback Shift Registers) PopCount Wallace

Connecting modules:Connectable GetPut ClientServer CGetPut BGetPut

Local bus access:LocalBus

Multiple clock domains:ClockConv

RAMs:RAM TRAM SyncSRAM SRAM STRAM SPSRAM DPSRAM SRAMFile

Miscellaneous:Assert EqFunction Enum Environment Fork OInt Reserved UIntRange

C.1 ActionSeq

ActionSeq allows you to simplify the description of a state machine. For example, suppose you hada module with an interface to load some data and, after loading, you simply wanted to sequencethrough 5 actions. Instead of explicitly coding the state and writing the (boring) rules to transitionfrom one state to the next, you could simply define the following in your module:

s :: ActionSeq

s <- actionSeq ( action1 |> · · · |> actionn )

and then call s.start to kick off the state sequence. The compiler will work out all the states foryou and prevent s.start from being called until it has sequenced through all the actions. The “|>”operator combines actions into a suitable list of actions for actionSeq.

The argument to actionSeq is an ActionList, which is simply a list of actions.

77

Page 78: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef ListN#(n, Action) ActionList #(type n);

The ActionSeq interface can be used to start the sequence and to test if it is done.

interface ActionSeq;

method Action start();

method Bool done();

endinterface: ActionSeq

The actionSeq function converts a list of actions to an ActionSeq.

module actionSeq#(ActionList#(n) as)(ActionSeq)

provisos (Add#(n, 1, i), Log#(i, k));

The function actionSeqBreak is similar to actionSeq, but it allows the sequence of actions to bestopped before it reaches the end. It is stopped by calling the argument supplied to the action list.E.g.,

s :: ActionSeq

s <- actionSeqBreak ( � break -> · · · |> { if cond then break else · · · } |> · · · )

module actionSeqBreak#(function ActionList#(n) as(Action x1))(ActionSeq)

provisos (Add#(n, 1, i), Log#(i, k));

A SeqList is simply a list of action sequences.

typedef ListN#(n, ActionSeq) SeqList #(type n);

The function seqOfActionSeq “glues” a number of action sequences together into a single actionsequence.

module seqOfActionSeq#(SeqList#(n) xs)(ActionSeq)

provisos (Add#(n, 1, j), Add#(1, n, j), Add#(j, 1, i), Log#(i, k));

C.2 Array

This package implements a 5-read-port 1-write-port array module. Arrays may be indexed by anytype in the Bits class: since the package uses a Verilog primitive module, the actual indexing isdone with the bit representations; thus the bit representation of the “lower” bound must be less (inthe sense of an unsigned bit-pattern) than that of the “upper” bound.

interface Array #(type i, type a);

method Action upd(i x1, a x2);

method a sub(i x1);

endinterface: Array

Arrays may be indexed using the “[]” notation.

module mkArray#(i l, i h)(Array#(i, a))

provisos (Bits#(i, si), Bits#(a, sa));

Module#(Array#(i, a)) mkArrayFull

provisos (Bounded#(i), Bits#(i, si), Bits#(a, sa));

An array which for which the reads and the write are conflict-free. For the implications of this, seethe documentation for ConfigReg.

module mkArrayWCF#(i l, i h)(Array#(i, a))

provisos (Bits#(i, si), Bits#(a, sa));

78

Page 79: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.3 ArrayFile

The ArrayFile package provides the same functionality as the Array package, but each constructorfunction takes an additional file name argument. The file contains the initial contents of the array.The file should use the Verilog hex memory file syntax.

The functions in this package cannot normally be used in synthesis.

module mkArrayFile#(String file, i l, i h)(Array#(i, a))

provisos (Bits#(i, si), Bits#(a, sa));

module mkArrayFullFile#(String file)(Array#(i, a))

provisos (Bounded#(i), Bits#(i, si), Bits#(a, sa));

module mkArrayWCFFile#(String file, i l, i h)(Array#(i, a))

provisos (Bits#(i, si), Bits#(a, sa));

C.4 Assert

The Assert package contains definitions to test assertions in the code.

Compile time assertion.

function a staticAssert(Bool b, a x);

C.5 BGetPut

The interfaces BGet and BPut are similar to Get and Put, but the interconnection of them (viaConnectable or in Verilog) is implemented with a simple protocol that allows all inputs and outputsto be directly connected. Furthermore, all wires go to registers and have no Bluespec SystemVeriloghandshaking. The protocol makes no assumptions about setup time and hold time for the registersat each end; so these interfaces may be used when the two ends have different clocks. In all othercircumstances, however, the CGetPut package will probably be preferable. In particular, the BGetPutprotocol is very slow.

The protocol consist of the sender putting the value to be sent on the pvalue output, and thentoggling the ppresent wire. The receiver acknowledges the receipt by toggling the gcredit wire.Both ppresent and gcredit start out low.

interfaceBGetS #(type sa);

method Bit#(sa) gvalue();

method Bool gpresent();

method Action gcredit(Bool x1);

endinterface: BGetS

interfaceBGetS #(type sa);

method Bit#(sa) gvalue();

method Bool gpresent();

method Action gcredit(Bool x1);

endinterface: BGetS

79

Page 80: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef BGetS#(SizeOf#(a)) BGet #(type a);

typedef BPutS#(SizeOf#(a)) BPut #(type a);

typedef Tuple2 #(BGet#(a), Put#(a)) BGetPut #(type a);

typedef Tuple2 #(Get#(a), BPut#(a)) GetBPut #(type a);

Create one end of the buffer. Access to it is via a Put interface.

module mkBGetPut(Tuple2 #(BGetS#(sa), Put#(a)))

provisos (Bits#(a, sa));

Create the other end of the buffer. Access to it is via a Get interface.

module mkGetBPut(Tuple2 #(Get#(a), BPutS#(sa)))

provisos (Bits#(a, sa));

The BGet and BPut interface are connectable.

instance Connectable #(BGetS#(sa), BPutS#(sa));

instance Connectable #(BPutS#(sa), BGetS#(sa));

The same idea may be extended to clients and servers.

typedef BClientS#(SizeOf#(a), SizeOf#(b)) BClient #(type a, type b);

typedef BServerS#(SizeOf#(a), SizeOf#(b)) BServer #(type a, type b);

typedef Tuple2 #(BClient#(a, b), Server#(a, b)) BClientServer #(type a, type b);

typedef Tuple2 #(Client#(a, b), BServer#(a, b)) ClientBServer #(type a, type b);

A BClient can be connected to a BServer and vice versa.

instance Connectable #(BClientS#(a, b), BServerS#(a, b));

instance Connectable #(BServerS#(a, b), BClientS#(a, b));

module mkClientBServer(Tuple2 #(Client#(a, b), BServerS#(sa, sb)))

provisos (Bits#(a, sa), Bits#(b, sb));

module mkBClientServer(Tuple2 #(BClientS#(sa, sb), Server#(a, b)))

provisos (Bits#(a, sa), Bits#(b, sb));

C.6 BitonicSort

Sort a list of items given a predicate that compares elements for <=. The sortLe generates a sortingnetwork using Batcher’s bitonic sort. The strange context is to guarantee a power of two in inputsize.

function ListN#(n, a) sortLe(function Bool le(a x1, a x2))

provisos (Log#(n, k), Log#(nn, k), Add#(n, 0, nn));

80

Page 81: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.7 Boolify

The Boolify class contains a single method boolify. This method is applicable to functions. Whenapplied it will return an equivalent function, which has been built only from Boolean primitives (&&,||, and not).

typeclass Boolify #(type a);

function a boolify(a x1);

endtypeclass

(A curried function can be boolified, if the uncurried can. This instance allows multi-argumentfunctions to be boolified. Note that in BSV0.5 multi-argument functions are usually handled inter-nally in their curried form, and both versions pretty-print in the same way. The relevant instance istherefore not shown here, as it would look either trivial or far too complicated.) A function wherethe argument and result can be turned into bits can be boolified.

instance Boolify #(a -> b)

provisos (Bounded#(a), Bits#(a, sa), Bits#(b, sb));

C.8 ClientServer

The interfaces Client and Server can be used for modules that have a request-response type ofinterface (e.g. a RAM). The server accepts requests and generates responses, and vice versa for theclient. There are no assumptions about how many (if any) responses a request will generate.

interfaceClient #(type a, type b);

method Get#(a) request();

method Put#(b) response();

endinterface: Client

interfaceServer #(type a, type b);

method Put#(a) request();

method Get#(b) response();

endinterface: Server

A Client can be connected to a Server and vice versa.

instance Connectable #(Client#(a, b), Server#(a, b));

instance Connectable #(Server#(a, b), Client#(a, b));

typedef Tuple2 #(Client#(a, b), Server#(a, b)) ClientServer #(type a, type b);

Create a buffer that just passes requests and responses between the two generated interfaces.

module mkRequestResponseBuffer(ClientServer#(a, b))

provisos (Bits#(a, sa), Bits#(b, sb));

Create a buffer that just passes requests and responses between the two generated interfaces. Useshalf the flops of mkRequestResponseBuffer, but also has half the throughput.

81

Page 82: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

module mkRequestResponseBuffer1(ClientServer#(a, b))

provisos (Bits#(a, sa), Bits#(b, sb));

The same, using sized FIFOs.

module mkSizedRequestResponseBuffer#(Integer sz)(ClientServer#(a, b))

provisos (Bits#(a, sa), Bits#(b, sb));

Create a new server with buffered requests.

module mkRequestBuffer#(Server#(a, b) s)(Server#(a, b))

provisos (Bits#(a, sa));

Create a new server with buffered responses.

module mkResponseBuffer#(Server#(a, b) s)(Server#(a, b))

provisos (Bits#(b, sb));

Join a list of servers to one server. All incoming requests are broadcasted all the servers and allresponses are merged. The function introduces a one cycle latency on the response.

module joinServersBC#(List#(Server#(a, b)) ifs)(Server#(a, b))

provisos (Bits#(b, sb));

Join a list of servers to one server. All incoming requests are sent to a selected subset of the serversand all responses are merged. The selection is my a function that can transform the request typewhile testing if it should be sent on. The function introduces a one cycle latency on the response.

module joinServers#(List#(Tuple2 #(a -> Maybe#(a’), Server#(a’, b))) ifs)(Server#(a, b))

provisos (Bits#(b, sb));

Split a server into a number of identical servers. The integer argument specifies how many outstand-ing requests a returned server may have. This number should be the latency of the argument serverto sustain full bandwidth. (A small number still works, as does a larger number.)

module splitServer#(Integer lat, Server#(a, b) serv)(ListN#(n, Server#(a, b)))

provisos (Bits#(b, sb), Log#(n, ln));

C.9 CGetPut

The interfaces CGet and CPut are similar to Get and Put, but the interconnection of them (viaConnectable) is implemented with a credit based FIFO. This means that the CGet and CPut inter-faces have completely registered input and outputs, and furthermore that additional register bufferscan be introduced in the connection path without any ill effect (except an increase in latency, ofcourse). The interface types are abstract (to avoid any non-proper use of the credit signaling proto-col). In the absence of additional register buffers, the round-trip time for communication betweenthe two interfaces is 4 clock cycles. Call this number r. The first argument to the type, n, specifiesthat transfers will occur for a fraction n/r of clock cycles (note that the used cycles will not neces-sarily be evenly spaced). n also specifies the depth of the buffer used in the receiving interface (thetransmitter side always has only a single buffer). So (in the absence of additional buffers) use n = 4to allow full-bandwidth transmission, at the cost of sufficient registers for quadruple buffering at one

82

Page 83: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

end; use n = 1 for minimal use of registers, at the cost of reducing the bandwidth to one quarter;use intermediate values to select the optimal trade-off if appropriate.

NoteFor compiler reasons the actual interfaces are called CGetS and CPutS with CGet and CPut being typeabbreviations. Hopefully this will be fixed soon.

typedef CGetS#(n, a, SizeOf#(a)) CGet #(type n, type a);

typedef CPutS#(n, a, SizeOf#(a)) CPut #(type n, type a);

Create one end of the credit based FIFO. Access to it is via a Put interface.

module mkCGetPut(Tuple2 #(CGetS#(n, a, sa), Put#(a)))

provisos (Bits#(a, sa), Add#(1, k, n), Add#(n, 1, n1), Log#(n1, ln));

Create the other end of the credit based FIFO. Access to it is via a Get interface.

module mkGetCPut(Tuple2 #(Get#(a), CPutS#(n, a, sa)))

provisos (Bits#(a, sa), Add#(1, k, n), Log#(n, ln));

Create a buffer that can be inserted along a connection path.

module mkCGetCPut(Tuple2 #(CGetS#(n, a, sa), CPutS#(n, a, sa)))

provisos (Bits#(a, sa));

The CGet and CPut interface are connectable.

instance Connectable #(CGetS#(n, a, sa), CPutS#(n, a, sa));

instance Connectable #(CPutS#(n, a, sa), CGetS#(n, a, sa));

The same idea may be extended to clients and servers.

typedef CClientS#(n, a, SizeOf#(a), b, SizeOf#(b)) CClient #(type n, type a, type b);

typedef CServerS#(n, a, SizeOf#(a), b, SizeOf#(b)) CServer #(type n, type a, type b);

module mkClientCServer(Tuple2 #(Client#(a, b), CServerS#(n, a, sa, b, sb)))

provisos (Bits#(a, sa), Bits#(b, sb), Add#(1, k, n));

module mkCClientServer(Tuple2 #(CClientS#(n, a, sa, b, sb), Server#(a, b)))

provisos (Bits#(a, sa), Bits#(b, sb), Add#(1, k, n));

83

Page 84: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.10 ClockConv

The ClockConv package adds the ability to have a part of a design clocked with a different clockand to cross between the clock domains. The Clock type is used to specify the clock to be usedfor a “module”. The Clock type is abstract and there are no operations to create a clock value.This means that only clocks supplied from the outside can be used. Externally the Clock type isrepresented by two wires: the reset (MSB) and the clock (LSB).

typedef union tagged { ... } Clock ...;

The class ClockConv is used to collect those types that can cross a clock domain boundary.

typeclass ClockConv #(type a);

The clockConv function takes a Module and gives back a Module of the same type, but which isclocked by the given clock instead of the default clock.

function Module#(a) clockConv(Clock c, Module#(a) mkModule);

The Get interface can cross a clock boundary.

instance ClockConv #(Get#(a))

provisos (Bits#(a, sa));

The Put interface can cross a clock boundary.

instance ClockConv #(Put#(a))

provisos (Bits#(a, sa));

Pairs of interfaces that each can cross a clock boundary can also cross together.

instance ClockConv #(Tuple2 #(a, b))

provisos (ClockConv#(a), ClockConv#(b));

The Closed type constructor allows values of the type to be constructed with the close function,but there is no way to further interact with the closed value. Nothing happens when close is appliedvalue, but the only thing that the result can be used for is to export it from a module. Closed valuesare allowed to cross clock boundaries, and nothing happens to them. This means that a subinterfaceof a module that is in a different clock domain can be made accessible at the top level.

interface Closed #(type a);

function Closed#(a) close(a x);

instance ClockConv #(Closed#(a));

84

Page 85: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.11 CompletionBuffer

A CompletionBuffer is like a FIFO except that entering elements can be done out-of-order. Toenter something into the completion buffer a token is necessary. A token can be obtained with thereserve method. This token is then used in the complete method to enter the actual item. Finally,the drain method takes items out of the buffer; the items are delivered in the order of the tokensthat were checked out.

The n represents the size of the completion buffer, and a is the item type.

interfaceCompletionBuffer #(type n, type a);

method Get#(CBToken#(n)) reserve();

method Put#(Tuple2 #(CBToken#(n), a)) complete();

method Get#(a) drain();

endinterface: CompletionBuffer

The CBToken type is abstract to avoid confusion.

typedef union tagged { ... } CBToken #(type n) ...;

The mkCompletionBuffer function creates a completion buffer. The mkCompletionBuffer functioncreates a completion buffer.

module mkCompletionBuffer(CompletionBuffer#(n, a))

provisos (Bits#(a, sa), Log#(n, ln), Log#(n, TLog#(n)), Add#(1, ln, ln1));

C.12 ConfigReg

The ConfigReg package provides a way to create configuration registers, where each update clobbersthe current value, and the precise timing of updates is not important. Rules fired during the clockcycle the register is written will read a stale value regardless of firing order.

typedef Reg#(a) ConfigReg #(type a);

module mkConfigReg#(a v)(Reg#(a))

provisos (Bits#(a, sa));

module mkConfigRegU(Reg#(a))

provisos (Bits#(a, sa));

C.13 Connectable

The class Connectable is meant to indicate that the two related types can be connected in someway. It does not specify the nature of the connection.

typeclass Connectable #(type a, type b)

dependencies a -> b, b -> a;

module mkConnection#(a x1, b x2)(Empty);

endtypeclass

The special (<->) operator is defined in terms of mkConnection, and is the preferred way to connect.If we have two couples of connectable items then the pair is also connectable, simply by connectingthe individual items.

85

Page 86: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

instance Connectable #(Tuple2 #(a, c), Tuple2 #(b, d))

provisos (Connectable#(a, b), Connectable#(c, d));

Two ListNs are connectable if the elements are.

instance Connectable #(ListN#(n, a), ListN#(n, b))

provisos (Connectable#(a, b));

C.14 Enum

The functions in this package can be used to enumerate values by using their bit representation.Enumerate all values of a bounded type.

List#(a) enumAll

provisos (Bits#(a, sa), Bounded#(a));

Enumerate all values (inclusively) between a lower and upper bound. This is done by applyingunpack to all the bit values between the bounds.

function List#(a) enumFromTo(a lo, a hi)

provisos (Bits#(a, sa));

C.15 Environment

The Environment package contains some value definitions that remain static within a compilation,but may vary between compilations.

Is the compiler generating C?

Bool genC;

Is the compiler generating Verilog?

Bool genVerilog;

Version of the compiler.

String compilerVersion;

Current date and time.

String date;

Test assertions.

Bool testAssert;

86

Page 87: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.16 EqFunction

Functions can be compared for equality if the domain can be enumerated and the range can becompared for equality.

instance Eq #(a -> b)

provisos (Bits#(a, sa), Bounded#(a), Eq#(b));

The ability to compare functions for equality can be useful for compile time verification of propertiesof the Bluespec SystemVerilog code.

C.17 FIFO

The FIFO interface is for FIFOs with implicit full and empty signals.

interface FIFO #(type a);

method Action enq(a x1);

method Action deq();

method a first();

method Action clear();

endinterface: FIFO

The various properties of the different FIFOs can be found at the the description of the correspondingFIFOF functions.

Module#(FIFO#(a)) mkFIFO

provisos (Bits#(a, sa));

Module#(FIFO#(a)) mkFIFO1

provisos (Bits#(a, sa));

module mkSizedFIFO#(Integer n)(FIFO#(a))

provisos (Bits#(a, sa));

Module#(FIFO#(a)) mkLFIFO

provisos (Bits#(a, sa));

C.18 FIFOF

The FIFOF interface is for FIFOs with explicit full and empty signals.

interface FIFOF #(type a);

method Action enq(a x1);

method Action deq();

method a first();

method Bool notFull();

method Bool notEmpty();

method Action clear();

endinterface: FIFOF

87

Page 88: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Make a FIFO of the default depth (currently 2). Note: when the FIFO is full it does not allowsimultaneous enqueue and dequeue operations.

module mkFIFOF(FIFOF#(a))

provisos (Bits#(a, as));

Make a FIFO of depth 1. Note: when the FIFO is full it does not allow simultaneous enqueue anddequeue operations (nor, of course, when it is empty).

module mkFIFOF1(FIFOF#(a))

provisos (Bits#(a, as));

Make a FIFO of the given depth Note: when the FIFO is full it does not allow simultaneous enqueueand dequeue operations. The FIFO depth argument should be > 0.

module mkSizedFIFOF#(Integer n)(FIFOF#(a))

provisos (Bits#(a, as));

Make a “loopy” FIFO of the default depth (currently 1). Note: this FIFO allows simultaneousenqueue and dequeue operations, but using this FIFO may cause combinational loops. (This isbecause of the feedthrough from the deq enable signal to the enq ready signal.)

module mkLFIFOF(FIFOF#(a))

provisos (Bits#(a, as));

C.19 FileIO

The FileIO package contains functions that allow file input and output of values from a C simulation.

The FilePut interface is used to write an item to a file.

interface FilePut #(type a);

method Action put(a x1);

endinterface: FilePut

The mkFileBinPut function is used to create a FilePut interface. Performing a put operation onthis interface will write a binary value to the file. The argument to mkFileBinPut is the file name.The file format is obtained from the item size. The size of an item is rounded to the nearest largerUSZ (32) multiple and that is the size (in bits) of the file item. The order of the bits stored is platformdependent and corresponds to how variables are stored internally. The standard pack operation isused to obtain the bits for an item.

module mkFileBinPut#(String name)(FilePut#(a))

provisos (Bits#(a, sa));

The mkFileHexPut function is used to create a FilePut interface. Performing a put operation onthis interface will write a hexdecimal value to the file. The argument to mkFileHexPut is the filename. Each item will be written with the minimum number of hex digits, prefixed 0x and ended bya new-line.

module mkFileHexPut#(String name)(FilePut#(a))

provisos (Bits#(a, sa));

88

Page 89: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

The FileGet interface is used to read an item from a file. On end-of-file Nothing is returned,otherwise Just applied to the value from the file.

interface FileGet #(type a);

method ActionValue#(Maybe#(a)) get();

endinterface: FileGet

The mkFileBinGet function is used to create a FileGet interface. Performing a get operation onthis interface will read a binary value from the file. The argument to mkFileBinGet is the file name.The format of the file is the same as for mkFileBinPut.

module mkFileBinGet#(String name)(FileGet#(a))

provisos (Bits#(a, sa));

The mkFileHexGet function is used to create a FileGet interface. Performing a get operation onthis interface will read a hexadecimal value from the file. The argument to mkFileHexGet is the filename. The format of the file is the same as for mkFileHexPut.

module mkFileHexGet#(String name)(FileGet#(a))

provisos (Bits#(a, sa));

The file names used have two special cases: the file name“-” is interpreted as standard output/input,and a string starting with a “|” is taken to be a command to which a pipe is created for the data.Example: the expression “mkFileBinPut "| od -X"” would create an interface where items putwould be transferred in binary into the od command which will dump them in hex.

C.20 Fork

The Bluespec SystemVerilog compiler does very aggressive common subexpression elimination (CSE).If this has to be circumvented it has to be done explicitly. The Fork package provides various waysto duplicate values to avoid CSE.

Copy a value into two identical values.

function Tuple2 #(a, a) fork(a)

provisos (Bits#(a, sa));

Copy a value into a list with the specified number of elements.

function List#(a) forkL(a x)

provisos (Bits#(a, sa));

Copy a value into a vector with the specified number of elements.

function ListN#(n, a) forkLN(a x)

provisos (Bits#(a, sa));

89

Page 90: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.21 GetPut

The interfaces Get and Put look like the dequeueing and enqueueing side of a FIFO respectively.They can be used as external interfaces for modules since they allow easy interconnection via theConnectable class.

The get method retrieves an item from an interface removes it at the same time.

interfaceGet #(type a);

method ActionValue#(a) get();

endinterface: Get

The put method simply gives an item to interface.

interfacePut #(type a);

method Action put(a x1);

endinterface: Put

A shorthand.

typedef Tuple2 #(Get#(a), Put#(a)) GetPut #(type a);

Peek at an item without getting it.

function a peekGet(Get#(a) g);

Given a FIFO we can obtain a Get interface (a combination of deq and first).

function Get#(a) fifoToGet(FIFO#(a) f);

Given a FIFO we can obtain a Put interface (via enq).

function Put#(a) fifoToPut(FIFO#(a) f);

Create a FIFO and return the two ends of it.

module mkGetPut(GetPut#(a))

provisos (Bits#(a, sa));

FIFO#(a) f;

mkFIFO the_f(f);

(fifoToGet(f), fifoToPut(f))

endmodule: mkGetPut

Create a FIFO and return the two ends of it.

module mkGPFIFO(GetPut#(a))

provisos (Bits#(a, sa));

FIFO#(a) f;

mkFIFO the_f(f);

(fifoToGet(f), fifoToPut(f))

endmodule: mkGPFIFO

Create a FIFO and return the two ends of it.

90

Page 91: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

module mkGPFIFO1(GetPut#(a))

provisos (Bits#(a, sa));

FIFO#(a) f;

mkFIFO1 the_f(f);

(fifoToGet(f), fifoToPut(f))

endmodule: mkGPFIFO1

Create a sized FIFO and return the two ends of it.

module mkGPSizedFIFO#(Integer sz)(GetPut#(a))

provisos (Bits#(a, sa));

FIFO#(a) f;

mkSizedFIFO#(sz) the_f(f);

(fifoToGet(f), fifoToPut(f))

endmodule: mkGPSizedFIFO

A Get and a Put interface can be connected either way.

instance Connectable #(Get#(a), Put#(a));

instance Connectable #(Put#(a), Get#(a));

C.22 IVec

The IVec package contains some definitions to work around a deficiency in the Bluespec SystemVer-ilog compiler. The compiler does not allow the type ListN in interfaces for which code is generated.To make this almost possible this package contains types that are isomorphic to ListN of some smallnumber of length (0-16). There are also conversion functions to and from ListN. The idea is to usethe type IVecM t where one would have liked to use ListN M t, and then convert to and from thistype as appropriate.

typeclass IVec #(type n, type t)

dependencies t -> n, n -> t;

function t#(a) toIVec(ListN#(n, a) x1);

function ListN#(n, a) fromIVec(t#(a) x1);

endtypeclass

instance IVec #(0, IVec0);

instance IVec #(1, IVec1);

instance IVec #(2, IVec2);

instance IVec #(3, IVec3);

instance IVec #(4, IVec4);

instance IVec #(5, IVec5);

instance IVec #(6, IVec6);

instance IVec #(7, IVec7);

instance IVec #(8, IVec8);

instance IVec #(9, IVec9);

instance IVec #(10, IVec10);

instance IVec #(11, IVec11);

instance IVec #(12, IVec12);

instance IVec #(13, IVec13);

instance IVec #(14, IVec14);

instance IVec #(15, IVec15);

instance IVec #(16, IVec16);

instance IVec #(32, IVec32);

instance IVec #(33, IVec33);

91

Page 92: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.23 LFSR

The LFSR package implements Linear Feedback Shift Registers (LFSRs). LFSRs can be used toobtain pseudorandom sequences, though their linearity permits easy cryptanalysis.12 The interfaceallows the value in the shifter register to be set (with seed), read (with value), and shifted (withnext). When the value is shifted the least significant bit will be fed back according to the polynomialused when the LFSR was created. When a LFSR is created the start value is 1.

interfaceLFSR #(type a);

method Action seed(a x1);

method a value();

method Action next();

endinterface: LFSR

The mkPolyLFSR function creates a LFSR given a polynomial specified by the exponents that havea non-zero coefficient. For example the polynominal x7 + x3 + x2 + x is used by the expression“mkPolyLFSR (7 :> 3 :> 2 :> 1 :> Nil)”.

function m#(LFSR#(Bit#(n))) mkPolyLFSR(List#(Integer) taps)

provisos (IsModule#(m));

The mkFeedLFSR function creates a LFSR where the polynomial is specified by the mask used for feed-back. If“r”is the state of the LFSR the next state is“if r[0:0] == 1 then (r >> 1) � feed else r >> 1”,where “feed” is the argument to mkFeedLFSR.

module mkFeedLFSR#(Bit#(n) feed)(LFSR#(Bit#(n)));

Some maximal length LFSRs. Many more can be found at http://www-2.cs.cmu.edu/ � koopman/lfsr/

m#(LFSR#(Bit#(4))) mkLFSR_4

provisos (IsModule#(m));

mkLFSR_4 = mkFeedLFSR(’h9);

m#(LFSR#(Bit#(8))) mkLFSR_8

provisos (IsModule#(m));

mkLFSR_8 = mkFeedLFSR(’h8E);

m#(LFSR#(Bit#(16))) mkLFSR_16

provisos (IsModule#(m));

mkLFSR_16 = mkFeedLFSR(’h8016);

m#(LFSR#(Bit#(32))) mkLFSR_32

provisos (IsModule#(m));

mkLFSR_32 = mkFeedLFSR(’h80000057);

C.24 List

List defines a list data type and operations.

typedef union tagged {

void Nil;

struct {

a hd;

List #(a) tl;

} Cons;

} List #(type a);

12see http://en.wikipedia.org/wiki/Linear � feedback � shift � register for details

92

Page 93: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Lists can be compared for equality if the elements can.

instance Eq #(List#(a))

provisos (Eq#(a));

A more convenient (right associative) operator for Cons.

function List#(a) (:>)(a x, List#(a) xs);

Put an element last in a list.

function List#(a) (<:)(List#(a) xs, a x);

Map a function over a list, return list of results.

function List#(b) map (function b f(a), List#(a) xs);

Return elements that satisfy the predicate

function List#(a) filter (function Bool p(a), List#(a) xs);

Append two lists, return appended list.

function List#(a) append (List#(a) xs, List#(a) ys);

Append many lists.

function List#(a) concat (List#(List#(a)) xss);

Generate a List of elements generated replicating the given argument.

function List#(a) replicate(Integer n, a c);

Reduction (from the right) over a list.

function b foldr (b function f(a x, b y), b e, List#(a) xs);

Reduction (from the right) over a non-empty list.

function a foldr1 (a function f(a x, a y), List#(a) xs);

Reduction (from the left) over a list.

function b foldl (b function f(b y, a x), b e, List#(a) xs);

Reduction (from the left) over a non-empty list.

function a foldl1 (a function f(a y, a x), List#(a) xs);

Tree reduction over a non-empty list.

function a fold (a function f(a y, a x), List#(a) xs);

93

Page 94: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Create list of range of numbers.

function List#(Integer) upto(Integer n, Integer m);

Move first element last.

function List#(a) rotate (List#(a) xs);

Move last element first.

function List#(a) rotateR (List#(a) xs);

Combine two lists with a function.

function List#(c) zipWith (function c f(a x, b y), List#(a) xs, List#(b) ys);

Combine three lists with a function.

function List#(c) zipWith3 (function d f(a x, b y, c z),

List#(a) xs, List#(b) ys, List#(c) zs);

Combine four lists with a function.

function List#(c) zipWith4 (function e f(a x, b y, c z, d w),

List#(a) xs, List#(b) ys, List#(c) zs, List#(d) ws);

Combine two lists into one list of pairs.

function List#(Tuple2 #(a, b)) zip (List#(a) xs, List#(b) ys);

Combine three lists into one list of tuples.

function List#(Tuple3 #(a, b, c)) zip3 (List#(a) xs, List#(b) ys, List#(c) zs);

Combine four lists into one list of tuples.

function List#(Tuple4 #(a, b, c, d)) zip4

(List#(a) xs, List#(b) ys, List#(c) zs, List#(d) ws);

Separate a list of pairs into a pair of two lists.

function Tuple2 #(List#(a), List#(b)) unzip (List#(Tuple2 #(a, b))xys);

Reverse element order

function List#(a) reverse(List#(a) xs);

Test if a list is empty.

function Bool null (List#(a) xs);

94

Page 95: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

First element of a list.

function a head (List#(a) xs);

All but the first elements of a list.

function List#(a) tail (List#(a) xs);

Last element of a list.

function a last (List#(a) xs);

All but the last elements of a list.

function List#(a) init (List#(a) xs);

Length of a list.

function Integer length (List#(a) xs);

Get the element at a certain position.

function a (!!)(List#(a) xs, Integer n);

In BSV, the square-bracket notation is also available.

instance PrimSelectable #(List#(a), Integer, a);

Similar to (!!), but can generate code (a mux). Combine with (!!)?

function a select(List#(a) l, b k)

provisos (Eq#(b), Literal#(b));

Select a list element with a Boolean list. The Boolean list should have exactly one element thatis True, otherwise the result is undefined. The returned element is the one in the correspondingposition to the True.

function a oneHotSelect(List#(Bool) bs, List#(a) xs)

provisos (Bits#(a, sa));

Update an element in a list.

function List#(a) update(List#(a) l, b k, a x)

provisos (Eq#(b), Literal#(b));

Matrix transposition of a list of lists.

function List#(List#(a)) transpose (List#(List#(a)) xss);

Test if a predicate holds for all elements of a list.

function Bool all(function Bool p(a x1), List#(a) xs);

95

Page 96: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Test if a predicate holds for any elements of a list.

function Bool any(function Bool p(a x1), List#(a) xs);

Take a number of elements.

function List#(a) take (Integer n, List#(a) xs);

Drop a number of elements.

function List#(a) drop (Integer n, List#(a) xs);

Return the initial segment that fulfills a predicate.

function List#(a) takeWhile (function Bool p(a x), List#(a) xs);

Return the tail segment that fulfills a predicate.

function List#(a) takeWhileRev (function Bool p(a x), List#(a) xs);

Remove the initial segment that fulfills a predicate.

function List#(a) dropWhile (function Bool p(a x), List#(a) xs);

Remove the tail segment that fulfills a predicate.

function List#(a) dropWhileRev (function Bool p(a x), List#(a) xs);

Check if an element is in a list.

function Bool elem (a x, List#(a) xs)

provisos (Eq#(a));

function List#(a) scanl(function a f(a x1, b x2), a q, List#(b) xs);

function List#(a) sscanl(function a f(a x1, b x2), a q, List#(b) xs);

function List#(b) scanr(function b f(a x1, b x2), b q, List#(a) xs);

function List#(b) sscanr(function b f(a x1, b x2), b q, List#(a) xs);

The List type is a monad.

instance Monad #(List);

Join a number of actions together.

function Action joinActions (List#(Action) as);

96

Page 97: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Join a number of rules together.

function Rules joinRules (List#(Rules) rs);

Map a function, but pass an accumulator from head to tail.

function Tuple2 #(a, List#(c)) mapAccumL

(function Tuple2 #(a, c) f(a x, b y), a x0, List#(b) ys);

Map a function, but pass an accumulator from tail to head.

function Tuple2 #(a, List#(c)) mapAccumR

(function Tuple2 #(a, c) f(a x, b y), a x0, List#(b) ys);

Map a function over a list consuming two elements at a time. Any straggling element is processedby the second function.

function List#(b) mapPairs

(function b f(a x, a y), function b g(a x), List#(a) xs);

Map a function (of a list) over a list producing a new list. The function consumes an initial segmentof the list and returns the result and the remaining list.

function List#(b) mapn (function Tuple2#(b, List#(a)) f (List#(a) xs),

List#(a) xs);

Fold a list with a function that consumes an initial segment of the list and returns the result andthe remaining list.

function a foldn (function Tuple2#(a, List#(a)) f (List#(a) xs),

List#(a) xs);

Combine all elements in a list with logical or.

function Bool or (List#(Bool) bs);

Combine all elements in a list with logical and.

function Bool and (List#(Bool) bs);

C.25 ListFIFO

The ListFIFO package provides constructors for making FIFOs for values of type List.

module mkListFIFOF#(Integer n)(FIFOF#(List#(a)))

provisos (Bits#(a, sa));

module mkListFIFO#(Integer n)(FIFO#(List#(a)))

provisos (Bits#(a, sa));

97

Page 98: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.26 ListN

ListN defines an abstract data type and operations for lists of a specific length. Because it isabstract, there are no constructors available for this type (like Cons and Nil for the regular List

type).

data ListN n a = · · · abstract · · ·

Here “a” represents the type of the contents of the list (just like in ordinary lists, and “n” representsthe length of the ListN.

Lists can be compared for equality if the elements can.instance (Eq a) => Eq (ListN n a)

A list can be turned into bits if the individual elements can be turned into bits. The first elementof the list is stored in the least significant bits.

instance Bits #(ListN#(n, a), nsa)

provisos (Bits#(a, sa), Mul#(n, sa, nsa));

There are no Bluespec SystemVerilog constructors available for this abstract type (and hence nopattern-matching is available for this type) but the following ordinary functions may be used toconstruct values of this type and to extract the head and tail of a ListN.

function ListN#(n1,a) cons (a x, ListN#(n,a) xs)

provisos (Add#(1, n, n1));

A more convenient (right associative) operator for Cons.

function ListN#(n1,a) (:>) (a x, ListN#(n,a) xs)

provisos (Add#(1, n, n1));

ListN#(0, a) nil;

function a head (ListN#(n,a) xs)

provisos (Add#(1, m, n));

function ListN#(m,a) tail (ListN#(n,a) xs)

provisos (Add#(1, m, n));

Map a function over a ListN, return ListN of results.

function ListN#(n,b) map (function b f(a), ListN#(n,a) xs);

Append two ListN’s, return appended ListN.

function ListN#(mn,a) append (ListN#(m,a) xs, ListN#(n,a) ys)

provisos (Add#(m, n, mn));

Append many lists.

function ListN#(mn,a) concat (ListN#(m,ListN#(n,a)) xss)

provisos (Mul#(m, n, mn));

98

Page 99: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Generate a ListN containing Integers 0 through N-1

ListN#(n, Integer) genList;

Generate a ListN of elements generated by applying the given function to 0 through N-1.

function ListN#(n, a) genWith(function a f(Integer x1));

return = map (f, genList);

endfunction: genWith

Generate a ListN of elements generated replicating the given argument.

function ListN#(n, a) replicate(a c);

Reduction (from the right) over a ListN

function b foldr (b function f(a x, b y), b e, ListN#(n,a) xs);

Reduction (from the right) over a non-empty ListN

function a foldr1 (a function f(a x, a y), ListN#(n,a) xs)

provisos (Add#(1, m, n));

Reduction (from the left) over a ListN

function b foldl (b function f(b y, a x), b e, ListN#(n,a) xs);

Reduction (from the left) over a non-empty ListN

function a foldl1 (a function f(a y, a x), ListN#(n,a) xs)

provisos (Add#(1, m, n));

Tree reduction over a non-empty list.

function a fold (a function f(a y, a x), ListN#(n,a) xs)

provisos (Add#(1, m, n));

Combine two ListN’s with a function.

function ListN#(n,c) zipWith (function c f(a x, b y), ListN#(n,a) xs, ListN#(n,b) ys);

Combine two ListNs with a function; result is as long as the shorter list.

function ListN#(mn,c) zipWithAny (function c f(a x, b y),

ListN#(m,a) xs, ListN#(n,b) ys)

provisos (Max#(n, mn, n), Max#(m, mn, m));

Combine three ListN’s with a function.

function ListN#(n,c) zipWith3 (function d f(a x, b y, c z),

ListN#(n,a) xs, ListN#(n,b) ys, ListN#(n,c) zs);

99

Page 100: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Combine three ListN’s with a function; result is as long as the shortest list.

function ListN#(mn,c) zipWithAny3 (function d f(a x, b y, c z),

ListN#(m,a) xs, ListN#(n,b) ys, ListN#(o,c) zs)

provisos (Max#(n, mn, n), Max#(m, mn, m), Max#(o, mn, o));

Combine two ListN’s into one ListN of pairs.

function ListN#(n,Tuple2 #(a, b)) zip (ListN#(n,a) xs, ListN#(n,b) ys);

Combine three ListN’s into one ListN of tuples.

function ListN#(n,Tuple3 #(a, b, c)) zip3 (ListN#(n,a) xs, ListN#(n,b) ys, ListN#(n,c) zs);

Combine three ListN’s into one ListN of tuples.

function ListN#(n,Tuple4 #(a, b, c, d)) zip4

(ListN#(n,a) xs, ListN#(n,b) ys, ListN#(n,c) zs, ListN#(n,d) ws);

Combine two ListN’s into one ListN of pairs; result is as long as the shorter list.

function ListN#(mn,Tuple2 #(a, b)) zipAny (ListN#(m,a) xs, ListN#(n,b) ys);

provisos (Max#(m, mn, m), Max#(n, mn, n));

Separate a ListN of pairs into a pair of two ListN’s.

function Tuple2 #(ListN#(n,a), ListN#(n,b)) unzip (ListN#(n,Tuple2 #(a, b))xys);

Move first elements last.

function ListN#(n,a) rotate (ListN#(n,a) xs);

Move last element first.

function ListN#(n,a) rotateR (ListN#(n,a) xs);

Reverse element order

function ListN#(n,a) reverse(ListN#(n,a) xs);

Last element of a list.

function a last (ListN#(n,a) xs);

All but the last elements of a list.

function ListN#(m,a) init (ListN#(n,a) xs)

provisos (Add#(1, m, n))

Take a function and a ListN; the function applied to a ListN element would return an action andresult. Return an action representing all those actions and the ListN of corresponding results.

100

Page 101: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function m#(ListN#(n, b)) mapM (function m#(b) f(a x), ListN#(n, a) xs)

provisos (Monad#(m));

Like mapM but throws away the resulting list

function m#(void) mapM_(function m#(b) f(a x), ListN#(n, a) xs)

provisos (Monad#(m));

Combine two lists with a function. Take a function (which takes two arguments) and two ListNs;The function applied to the corresponding element from each list would return an action and result.Return an action representing all those actions and the list of corresponding results.

function m#(ListN#(n, c)) zipWithM(function m#(c) f(a x, b y), ListN#(n, a) xs, ListN#(n, b) ys)

provisos (Monad#(m));

Like zipWithM but throws away the resulting list

function m#(void) zipWithM_(function m#(c) f(a x, b y), ListN#(n, a) xs, ListN#(n, b) ys)

provisos (Monad#(m));

Combine three lists with a function. Take a function (which takes three arguments) and three ListNs;The function applied to the corresponding element from each list would return an action and result.Return an action representing all those actions and the list of corresponding results.

function m#(ListN#(n, c)) zipWith3M(function m#(d) f(a x, b y, c z), ListN#(n, a) xs, ListN#(n, b) ys, ListN#(n, c) zs)

provisos (Monad#(m));

Generate a ListN of elements generated by applying the given monadic function to 0 through N-1.

function m#(ListN#(n, a)) genWithM(function m#(a) f(Integer x))

provisos (Monad#(m));

Generate a ListN of elements generated by using the given monadic value repeatedly.

function m#(ListN#(n, a)) replicateM(m#(a) c)

provisos (Monad#(m));

function m#(b) foldlM (m#(b) function f(b y, a x), b e, ListN#(n,a) xs)

provisos (Monad#(m));

function m#(a) foldM (m#(a) function f(a y, a x), ListN#(n,a) xs)

provisos (Monad#(m), Add#(1, k, n));

function m#(b) foldrM (m#(b) function f(a x, b y), b e, ListN#(n,a) xs)

provisos (Monad#(m));

Take a ListN of actions; return an action representing performing all those actions and returningthe ListN of all the results.

101

Page 102: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function m#(ListN#(n, a)) sequence (ListN#(n, m#(a)))

provisos (Monad#(m));

Get the element at a certain position.

function a (!!)(ListN#(n,a) xs, Integer n);

In BSV, the square-bracket notation is also available.

instance PrimSelectable #(ListN#(n,a), Integer, a);

Similar to (!!), but can generate code (a mux). Combine with (!!)?

function a select(ListN#(n,a) l, b k)

provisos (Eq#(b), Literal#(b));

Update an element in a list.

function ListN#(n,a) update(ListN#(n,a) l, b k, a x)

provisos (Eq#(b), Literal#(b));

Matrix transposition of a list of lists.

function ListN#(m,ListN#(n,a)) transpose (ListN#(n,ListN#(m,a)) xss);

Matrix transposition of a list of lists.

function ListN#(n, List#(a)) transposeLN(List#(ListN#(n, a)) ls);

Test if a predicate holds for all elements of a list.

function Bool all(function Bool p(a x1), ListN#(n,a) xs);

Test if a predicate holds for any elements of a list.

function Bool any(function Bool p(a x1), ListN#(n,a) xs);

Take a number of elements.

function ListN#(m,a) take (Integer n, ListN#(n,a) xs)

provisos (Add#(m,k,n));

Check if an element is in a list.

function Bool elem (a x, ListN#(n,a) xs)

provisos (Eq#(a));

function ListN#(n1,b) scanr(function b f(a x1, b x2), b q, ListN#(n,a) xs)

provisos (Add#(1, n, n1));

102

Page 103: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function ListN#(n,b) sscanr(function b f(a x1, b x2), b q, ListN#(n,a) xs);

function ListN#(n1,a) scanl(function a f(a x1, b x2), a q, ListN#(n,b) xs)

provisos (Add#(1, n, n1));

function ListN#(n,a) sscanl(function a f(a x1, b x2), a q, ListN#(n,b) xs);

Convert to an ordinary list.

function List#(a) toList (ListN#(n, a) xs);

Convert an ordinary list to a ListN.

function ListN#(n, a) toListN (List(a) xs);

Join a number of actions together.

function Action joinActions (ListN#(n,Action) as);

Join a number of rules together.

function Rules joinRules (ListN#(n,Rules) rs);

Map a function, but pass an accumulator from head to tail.

function Tuple2 #(a, ListN#(n,c)) mapAccumL

(function Tuple2 #(a, c) f(a x, b y), a x0, ListN#(n,b) ys);

Map a function, but pass an accumulator from tail to head.

function Tuple2 #(a, ListN#(n,c)) mapAccumR

(function Tuple2 #(a, c) f(a x, b y), a x0, ListN#(n,b) ys);

Map a function over a list consuming two elements at a time. Any straggling element is processedby the second function.

function ListN#(n2,b) mapPairs

(function b f(a x, a y), function b g(a x), ListN#(n,a) xs)

provisos (Div#(n, 2, n2));

C.27 ListReg

The ListReg package provides a constructor for registers for storing values of type List. Note thatthe list is assumed to always have the same length as the list given as the initial value.

module mkListReg#(List#(a) xs)(Reg#(List#(a)))

provisos (Bits#(a, sa));

XXX THIS PACKAGE IS NOT TO BE MADE PUBLICLY AVAILABLE WITH BSC0.5. THEPUBLIC PACKAGE WILL BE LBus, WHICH USES THIS ONE.

103

Page 104: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.28 LocalBus

The LocalBus package provides a way to create registers that are accessible through some type oflocal bus (e.g., PCI).

The local bus registers are collected automagically in a ModuleCollect monad. An LBSModule sa

sd corresponds to a Module except that it also keeps a set of registers. The address is sa bits wideand the data is sd bits wide.

type LBSModule sa sd i = ModuleCollect (LBSReg sa sd) i

The LBSReg type is normally never seen by a user of the LBSModule; it is only needed when creatingnew kinds of local bus registers. This LBSReg interface is what the local bus uses to access a register.

interface LBSReg sa sd =

lbsAddr :: LBAddr sa -- address of the register

lbsSet :: Bit sd -> Action -- set method

lbsGet :: ActionValue (Bit sd) -- get method

Note that the lbsGet method allows an action to be performed when the local bus reads the value.This allows implementing, e.g., clear-on-read registers.

The type LBAddr is the address used to get and set register from the local bus. (This type is exportedabstractly.)

data LBAddr sa = LBAddr (Bit sa)

deriving (Literal, Eq, Bits)

C.28.1 Creating registers

The lbRegRO function creates a register that looks like a normal register in the module that createsit, but it is also accessible from the local bus at the given address. From the local bus the registeris read-only; attempts to write it have no effect. The created register has to have a bit width smallthan or equal to the local bus width. If it is smaller it will padded with zeroes on the left.

lbRegRO :: (Bits r sr, Add k sr sd) => LBAddr sa -> r -> LBSModule sa sd (Reg r)

The lbRegRW function creates a register that looks like a normal register in the module that createsit, but it is also accessible from the local bus at the given address.

lbRegRW :: (Bits r sr, Add k sr sd) => LBAddr sa -> r -> LBSModule sa sd (Reg r)

The lbsOffset function can be used to add an offset to all local bus register addresses in anLBSModule.

lbsOffset :: LBAddr sa -> LBSModule sa sd i -> LBSModule sa sd i

interface Accum n =

add :: Bit n -> Action

value :: Bit n

lbAccum :: (Add k i sd) => LBAddr n -> Bit k -> LBSModule n sd (Accum k)

104

Page 105: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.28.2 Collecting registers together

The external interface of a local bus is RAM-like. It is through this interface that register accessesnormally happen.type LBASync sa sd = RAM (LBAddr sa) (Bit sd)

Given a LBSModule with a set of register we can extract the local bus (RAM-like) interface and thenormal interface.lbsCollect :: LBSModule sa sd i -> Module (LBASync sa sd, i)

The LBSModule is used to collect individual registers. Once the registers have been collected into anLBASync interface these interfaces can be collected together.type LBAModule sa sd i = ModuleCollect (LBASync sa sd) i

The mkLBA function make a LBAModule out of the result from lbsCollect.mkLBA :: Module (LBASync sa sd, i) -> LBAModule sa sd i

The lbaCollect function combines local bus register clusters. It introduces a one cycle latency onboth request and response.lbaCollect :: (Bits (RAMreq (LBAddr sa) (Bit sd)) sreq) =>

LBAModule sa sd i -> Module (LBASync sa sd, i)

The LBAAtModule module represents modules located at a a particular place in the local bus addressspace.type LBAAtModule m n a i = ModuleCollect (LBAddr m, LBASync n a) i

Set the address space location.lbaSetAddr :: LBAddr m -> LBAModule n a i -> LBAAtModule m n a i

C.29 Loop

The Loop package contains some functions to simplify the construction of loops. All the constructshere take an ActionList as the loop body. These action are then executed in sequence a number oftimes, where the number depends on the looping construct.

The for function constructs a for loop where a register will take on the specified values in sequence.It is invoked as follows “for var low high body”, where var is a register, low is the lower bound,high is the upper bound, and body is the action sequence that forms the loop body.

module for#(Reg#(a) i, a lo, a hi, ActionList#(n) stmts)(ActionSeq)

provisos (Arith#(a), Ord#(a), Bits#(a, sa), Add#(1, m, n), Add#(n, 1, n1), Log#(n1, l));

The function forN is like for, except that the loop counts down from high to zero (inclusive). It isinvoked as follows “forN var high body”.

module forN#(Reg#(a) i, a hi, ActionList#(n) stmts)(ActionSeq)

provisos (Arith#(a), Ord#(a), Bits#(a, sa), Add#(1, m, n), Add#(n, 1, n1), Log#(n1, l));

The function forBreak is like for, except that the loop can be terminated early (just as with abreak in C). It is invoked as follows “for var low high ( � break -> body )”

module forBreak#(Reg#(a) i, a lo, a hi, function ActionList#(n) stmts (Action br))(ActionSeq)

provisos (Arith#(a), Ord#(a), Bits#(a, sa), Add#(n, 1, n1), Add#(n1, 1, n2), Log#(n2, l));

The forever function constructs a loop that terminates when the “break” function is called. It isinvoked as follows “forever ( � break -> body )”

module forever#(function ActionList#(n) stmts (Action br))(ActionSeq);

XXX THIS PACKAGE NOT PUBLICLY AVAILABLE WITH BSV0.5

105

Page 106: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.30 ModuleCollect

The ModuleCollect type is a variation on Module that allows items to be collected while elaboratingthe module structure. The collection is kept as a list, so each item in the collection has to have thesame type.

The type constructor ModuleCollect is abstract.

data ModuleCollect a i

The ModuleCollect type constructor is a Monad.

instance Monad (ModuleCollect a)

The ModuleCollect type constructor is an IsModule.

instance IsModule (ModuleCollect a)

Add an item to the collection.

addToCollection :: a -> ModuleCollect a i

Retrieve the collection, and the regular value.

getCollection :: ModuleCollect a i -> Module (i, List a)

Apply a function to each item added to the collection within the second argument.

mapCollection :: (a -> a) -> ModuleCollect a i -> ModuleCollect a i

C.31 Monad

Monad defines monad operations.

Think of a monadic type “m a” as representing an “action” and returning a result of type “a”.

Take a function and a list; the function applied to a list element would return an action and result.Return an action representing all those actions and the list of corresponding results.

function m#(List#(b)) mapM(function m#(b) f(a x1), List#(a) x)

provisos (Monad#(m));

Take an action and a list; return an action representing the original action repeated as many timesas there are list elements.

function m#(List#(b)) mapM_(m#(b) c)

provisos (Monad#(m));

Think of a monadic type “m a” as representing an “action” and returning a result of type “a”.

Combine two lists with a function. Take a function which takes two arguments and two lists; Thefunction applied to the corresponding element from each list would return an action and result.Return an action representing all those actions and the list of corresponding results.

function m#(List#(c)) zipWithM(function m#(c) f(a x1, b x2), List#(a) xs, List#(b) ys)

provisos (Monad#(m));

106

Page 107: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Think of a monadic type “m a” as representing an “action” and returning a result of type “a”.

Combine three lists with a function. Take a function which takes three arguments and three lists;The function applied to the corresponding element from each list would return an action and result.Return an action representing all those actions and the list of corresponding results.

function m#(List#(d)) zipWith3M(function m#(d) f(a x1, b x2, c x3),

List#(a) xs,

List#(b) ys,

List#(c) zs)

provisos (Monad#(m));

Take a list of actions; return an action representing performing all those actions and returning thelist of all the results.

function m#(List#(a)) sequence()

provisos (Monad#(m));

foldlM f z xsf z xs1 represents an action and result z1

f z1 xs2 represents an action and result z2

· · ·Return an action representing all these actions and the final zn

function m#(a) foldlM(function m#(a) f(a x1, b x2), a a, List#(b) xs)

provisos (Monad#(m));

Tree reduction over a non-empty list. First argument combines pairs of leaves. No transformationat singleton leaves.

function m#(a) foldM(function m#(a) f(a x1, a x2), List#(a) xs)

provisos (Monad#(m));

Tree reduction over a non-empty list. First argument combines pairs of leaves. Second argument isapplied to singleton leaves.

function m#(a) folduM(function m#(a) f(a x1, a x2), function m#(a) g(a x1), List#(a) xs)

provisos (Monad#(m));

foldrM f z xsf xsn z represents an action and result zn

f xsn−1 zn represents an action and result zn−1

· · ·Return an action representing all these actions and the final z1

function m#(b) foldrM(function m#(b) f(a x1, b x2), b z, List#(a) xs)

provisos (Monad#(m));

The fmap function is a generalization of the the List.map function to an arbitrary monad.

function m#(b) fmap(function b f(a x1), m#(a) xs)

provisos (Monad#(m));

Generate a List of elements generated by using the given monadic value repeatedly.

function m#(List#(a)) replicateM(Integer n, m#(a) c)

provisos (Monad#(m));

107

Page 108: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.32 OInt

The OInt n type is a type that can store a number in the range “0..n-1”. The representation ofa “OInt n” takes up n bits, where exactly one bit is a set to one, and the others are zero, i.e., it isa “one-hot” decoded version of the number. The reason to use a OInt number is that the select

operation is more efficient than for an ordinary number; the code generated for select takes advantageof the fact that only one of the bits may be set at a time.

typedef ... OInt #(type n) ... ;

Numeric literals can be used as usual (indicating which bit should be set).

instance Literal #(OInt#(n));

Values can be compared for equality.

instance Eq #(OInt#(n));

There are upper and lower bounds.

instance Bounded #(OInt#(n));

An ordinary number can be converted to an OInt. An out-of-range number gives an unspecifiedresult.

function OInt#(n) toOInt(Bit#(k) k);

An OInt can be converted to an ordinary number.

function Bit#(k) fromOInt(OInt#(n) o);

An OInt can be used to select an element from a list in an efficient way.

function a select(ListN#(n, a) xs, OInt#(n) o)

provisos (Bits#(a, sa));

C.33 Once

The Once package encapsulates the notion of an action that should only be performed once.

The start method performs the action that has been encapsulated in the Once module, but oncestart has been called it cannot be called again (an implicit condition will enforce this). However,if the reset method is called, the start method can be called once again.

interface Once;

method Action start();

method Action reset();

endinterface: Once

The mkOnce function is used to create a Once interface where the action argument has been encap-sulated and will be performed when start is called.

module mkOnce#(Action a)(Once);

108

Page 109: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.34 PopCount

The function popCountNaive just generates the sum of all the bits in the input word by extractingthem and adding them linearly.

function Bit#(m) popCountNaive()

provisos (Add#(a, 1, m));

The function popCountTable uses a lookup table with the input as an index to get the populationcount.

function Bit#(m) popCountTable()

provisos (Add#(a, 1, m));

The function popCountTree uses a balanced tree of adders to add the input bits.

function Bit#(m) popCountTree()

provisos (Add#(1, b, n), Add#(a, 1, m));

The function popCountWallace uses a Wallace tree to add the input bits.

function Bit#(m) popCountWallace()

provisos (Add#(1, a, m));

Use a table of a small width, add the results with a Wallace adder.

function Bit#(m) popCountTableWallace()

provisos (Add#(LogK, k, m));

Use a table of a small width, add the results with a balanced tree.

function Bit#(m) popCountTableTree()

provisos (Add#(a, LogK, m));

C.35 Pull

The Pull a interface represents a stream that produces values of type “a” only when “pulled” by aconsumer.

Modules with the Pull interface can be combined using � to model computations that compriseseveral steps, each of which may be buffered.

interface Pull #(type a);

method ActionValue#(a) pull();

endinterface: Pull

Apply a function to the data in the stream.

function Pull#(b) apply(function b f(a x1), Pull#(a) src);

Allow an action to peek at the stream.

109

Page 110: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function Pull#(a) tee(function Action p(a x1), Pull#(a) src);

Wrap the stream in a module (without buffering).

module pass#(Pull#(a) p)(Pull#(a));

Apply a function to the data in the stream and wrap the stream in a module (without buffering).

module passed#(function b f(a x1))(Pull#(b));

Wrap a stream in a module (with a buffer initialized to the first argument).

module buffer#(a init, Pull#(a) src)(Pull#(a))

provisos (Bits#(a, sa));

Apply a function to the data in the stream and wrap the stream in a module (with a buffer initializedto ‘ � ’).

module buffered#(function b f(a x1))(Pull#(b))

provisos (Bits#(b, sb));

A consumer that always pulls data from the given stream and throws it away.

module sink#(Pull#(a) p)(Empty);

A producer of junk.

module spew(Pull#(a));

Combine two streams (e.g., spew sink).

function m#(b) ( )()provisos (Monad#(m));

See ex/PullSquares.bs in the Bluespec distribution for an example.

C.36 Push

The Push a interface represents a stream that consumes values of type “a” only when “pushed” bya producer.

Modules with the Push interface can be combined using 13 to model computations that compriseseveral steps, each of which may be buffered.

interfacePush #(type a);

method Action push(a x1);

endinterface: Push

Apply a function to the data in the stream.

function Push#(a) apply(function b f(a x1), Push#(b) dst);

13You can get by typing C-q 273 in (X)Emacs or C-k >> in Vim insert mode.

110

Page 111: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Allow an action to peek at the stream.14

function Push#(a) tee(function Action a(a x1), Push#(a) dst);

Wrap the stream in a module (without buffering).

module pass#(Push#(a) dst)(Push#(a));

Apply a function to the data in the stream and wrap the stream in a module (without buffering).

module passed#(function b f(a x1))(Push#(a));

Wrap a stream in a module (with a register buffer initialized to the first argument).

module buffer#(a init, Push#(a) dst)(Push#(a))

provisos (Bits#(a, sa));

Wrap a stream in a module (with a FIFO buffer).

module qbuffer#(Push#(a) dst)(Push#(a))

provisos (Bits#(a, sa));

Wrap a stream in a module (with a loopy FIFO buffer). This saves register elements, but the pushaction logic may depend on checking all elements in the pipe.

module qbuffer#(Push#(a) dst)(Push#(a))

provisos (Bits#(a, sa));

Apply a function to the data in the stream and wrap the stream in a module (with a register bufferinitialized to ‘ � ’).

module buffered#(function b f(a x1))(Push#(a))

provisos (Bits#(a, sa));

Apply a function to the data in the stream and wrap the stream in a module (with a loopy FIFObuffer).

module qbuffered#(function b f(a x1))(Push#(a))

provisos (Bits#(a, sa));

Apply a function to the data in the stream and wrap the stream in a module (with a FIFO buffer).

module qbuffered#(function b f(a x1))(Push#(a))

provisos (Bits#(a, sa));

A consumer that drops all data.

module sink(Push#(a));

A producer that always pushes junk on the given stream.

14Why tee? Run man tee.

111

Page 112: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

module spew#(Push#(a) dst)(Empty);

Combine two streams (e.g., spew � sink).

function m#(b) ( � )(function m#(b) f(a x1), m#(a) a)

provisos (Monad#(m));

Wrap a Push interface around a register.

function Push#(a) regToPush(Reg#(a) r);

Wrap a Push interface around a FIFO.

function Push#(a) fifoToPush(FIFO#(a) q);

See ex/PushSquares.bs in the Bluespec distribution for an example.

C.37 RAM

C.37.1 RAM and TRAM

The RAM type is used for various types of memories. The memory is a Server which accepts read orwrite requests. A read request will generate a response containing the read data. The latency for aRAM is arbitrary, it does not even have to be a fixed latency.

Note, the types of the address and data are arbitrary.

typedef Server#(RAMreq#(adr, dta), dta) RAM #(type adr, type dta);

typedef Client#(RAMreq#(adr, dta), dta) RAMclient #(type adr, type dta);

typedef union tagged {

adr Read;

Tuple2#(adr, dta) Write;

} RAMreq #(type adr, type dta) deriving (Eq, Bits);

The TRAM type represents a tagged RAM. It is similar to the RAM interface, but each read requesthas an additional tag that will be part of the response for a read.

typedef Server#(TRAMreq#(tag, adr, dta), TRAMresp#(tag, dta)) TRAM #(type tag, type adr, type dta);

typedef

Client#(TRAMreq#(tag, adr, dta), TRAMresp#(tag, dta)) TRAMclient #(type tag, type adr, type dta);

112

Page 113: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef tagged union {

TRAMreqRead#(tag, adr, dta) Read;

TRAMreqWrite#(tag, adr, dta) Write;

} TRAMreq #(type tag, type adr, type dta) deriving (Eq, Bits);

typedef struct {

tg tag;

adr address;

} TRAMreqRead #(type tg, type adr, type dta) deriving (Eq, Bits);

typedef struct {

dta value;

adr address;

} TRAMreqWrite #(type tg, type adr, type dta) deriving (Eq, Bits);

typedef struct {

tg tag;

dta value;

} TRAMresp #(type tg, type dta) deriving (Eq, Bits);

The tagRAM function converts a RAM to a TRAM by putting a tag FIFO next to it. The FIFO sizeis specified by the first argument.

module tagRAM#(Integer sz, Module#(RAM#(adr, dta)) mkRAM)(TRAM#(tg, adr, dta))

provisos (Bits#(tg, stg));

C.37.2 SyncSRAM

The SyncSRAM package contains definitions of the low level type for connecting to synchronousSRAMs. It is not intended for programming with directly; it is only used to interface to internaland external SRAMs. The SyncSRAMS type is the type of an SRAM. An SRAM is a “server” in thesense that it accepts a request every clock cycle and delivers a response every clock cycle. The typehas three parameters, lat, the latency in clock cycles, adrs, the size of the address, and dtas, thesize of the data.

typedef

Server#(SyncSRAMrequest#(lat, adrs, dtas), Bit#(dtas)) SyncSRAMS #(type lat, type adrs, type dtas);

Correspondingly, SyncSRAMC is the type of a user (client) of an SRAM.

typedef

Client#(SyncSRAMrequest#(lat, adrs, dtas), Bit#(dtas)) SyncSRAMC #(type lat, type adrs, type dtas);

An SRAM request is simply the wires to the SRAM.

NoteSyncSRAMrequest should really be a struct, but we get nice wire names by using an interface.

interface (SyncSRAMrequest :: # -> # -> # -> *) #(type lat, type adrs, type dtas);

method Bit#(adrs) addr();

method Bit#(dtas) wdata();

method Bit#(1) we();

method Bit#(1) ena();

endinterface: (SyncSRAMrequest :: # -> # -> # -> *)

113

Page 114: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Note, it is important that the latency argument is accurate. Various SRAM adapters rely on thelatency information in the type to do the right thing.

C.37.3 SRAM and TSRAM

The SRAM package contains functions for wrapping a raw SRAM so that it has the more convenientRAM interface. The mkWrapSRAM function takes a SyncSRAM module and turns it into a RAM module.

module mkWrapSRAM#(Module#(SyncSRAMS#(lat, adrs, dtas)) mkRam)(RAM#(adr, dta))

provisos (Bits#(adr, adrs),

Bits#(dta, dtas),

Add#(1, lat, lat1),

Add#(4, lat, lat4),

Log#(lat4, llat));

The wrapSRAM module generates a SyncSRAMC client and a RAM server. The client interface can beexported and hooked up to an external SRAM, or hooked up to an internally generated SRAM.

module wrapSRAM(Tuple2 #(SyncSRAMC#(lat, adrs, dtas), RAM#(adr, dta)))

provisos (Bits#(adr, adrs),

Bits#(dta, dtas),

Add#(1, lat, lat1),

Add#(4, lat, lat4),

Log#(lat4, llat));

Both the mkWrapSRAM and wrapSRAM modules add two cycles of latency to the SRAM latency. Thereason for this is that the raw interface to the SRAM has fully“registered”inputs and outputs (whichis necessary for many SRAMs).

NoteThe current implementation of these functions is broken, it adds three extra cycles of latency.

The TSRAM package corresponds to the SRAM package, but for tagged SRAMs.

module mkWrapSTRAM#(Module#(SyncSRAMS#(lat, adrs, dtas)) mkRam)(TRAM#(tg, adr, dta))

provisos (Bits#(adr, adrs),

Bits#(dta, dtas),

Bits#(tg, tgs),

Add#(1, lat, lat1),

Log#(lat1, llat));

module wrapSTRAM(Tuple2 #(SyncSRAMC#(lat, adrs, dtas), TRAM#(tg, adr, dta)))

provisos (Bits#(adr, adrs),

Bits#(dta, dtas),

Bits#(tg, tgs),

Add#(1, lat, lat1),

Log#(lat1, llat));

C.37.4 SPSRAM

The SPSRAM package is used to generate internal single ported SRAMs (for the LSI libraries). Theargument specifies the size of the SRAM. The SRAM has a one cycle latency.

module mkSPSRAM#(Integer nwords)(SyncSRAMS#(1, adrs, dtas));

114

Page 115: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.37.5 DPSRAM

The DPSRAM package contains is used to generate internal dual ported SRAMs (for the LSI libraries).The argument specifies the size of the SRAM.

module mkDPSRAM#(Integer nwords)(Tuple2 #(SyncSRAMS#(1, adrs, dtas), SyncSRAMS#(1, adrs, dtas)));

C.37.6 SRAMFile

The SRAMFile package is used to generate single ported SRAMs, where the initial contents is takenfrom a file. The arguments specify the file name and the size of the SRAM. The SRAM has a onecycle latency.

mkSRAMFile :: (IsModule m) => String -> Integer -> m (SyncSRAMS 1 adrs dtas)

C.38 Reserved

Reserved15 defines an abstract data type which only has the purpose of taking up space. It is usefulwhen defining a struct where you need to enforce a certain layout. A value of type Reserved n

takes up exactly n bits.

data Reserved n = · · · abstract · · ·

Converting Reserved to or from bits yields an unspecified value (“_”).

instance Bits #(Reserved#(n), n);

Any two Reserved values are considered to be equal.

instance Eq #(Reserved#(n));

instance Ord #(Reserved#(n));

The upper and lower bound return unspecified values (“_”).

instance Bounded #(Reserved#(n));

C.39 RPush

The RPush a interface represents a stream that consumes values of type “a” only when “pushed” bya producer. The stream can also be “reset,” forgetting all buffered state (which is what distinguishesit from the Push interface.)

Modules with the RPush interface can be combined using 16 to model computations that compriseseveral steps, each of which may be buffered.

interface RPush #(type a);

method Action push(a x1);

method Action reset();

endinterface: RPush

15Idea and implementation stolen from Nick Horgan.16You can get � by typing C-q 273 in (X)Emacs or C-k >> in Vim insert mode.

115

Page 116: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Apply a function to the data in the stream.

function RPush#(a) apply(function b f(a x1), RPush#(b) dst);

Allow an action to peek at the stream.17

function RPush#(a) tee(function Action a(a x1), RPush#(a) dst);

Wrap the stream in a module (without buffering).

module pass#(RPush#(a) dst)(RPush#(a));

Apply a function to the data in the stream and wrap the stream in a module (without buffering).

module passed#(function b f(a x1))(RPush#(a));

Wrap a stream in a module (with a FIFO buffer).

module buffer#(RPush#(a) dst)(RPush#(a))

provisos (Bits#(a, sa));

Apply a function to the data in the stream and wrap the stream in a module (with a FIFO buffer).

module buffered#(function b f(a x1))(RPush#(a))

provisos (Bits#(a, sa));

A consumer that drops all data.

module sink(RPush#(a));

A producer that always pushes junk on the given stream.

module spew#(RPush#(a) dst)(Empty);

Combine two streams (e.g., spew � sink).

function m#(b) ( � )(function m#(b) f(a x1), m#(a) a)

provisos (Monad#(m));

Wrap a RPush interface around a FIFO.

function RPush#(a) fifoToRPush(FIFO#(a) q);

17Why tee? Run man tee.

116

Page 117: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.40 RWire

An RWire is a primitive for building modules that need to behave in some special way if multiplemethods are used in the same clock cycle.

This is a very dangerous primitive. It is implemented only by wires; the enable signal of the setappears the tag of the get. The primitive can be used to build many safe primitives, e.g. FIFOs.The danger comes partly from the fact it is easy to create cycles using this primitive.

Semantically it behaves like a register, but where the value disappears after an unspecified, butbounded number of rewrites.

interface RWire #(type a);

method Action wset(a x1);

method Maybe#(a) wget();

endinterface: RWire

module mkRWire(RWire#(a))

provisos (Bits#(a, sa));

C.41 Stmts

The Stmts package provides a C-like way of defining finite state machines.

Defining a state machine proceeds in two steps: first, a description of the FSM using C-like syntax(this internally builds an abstract syntax tree); second, the description is translated into an FSM.

C.41.1 Statements

The type of statements.

typedef StmtM#(void) Stmt;

The base type of statements is abstract.

typedef ... StmtM #(type a);

To use the do syntax the base type has to be a monad.

instance Monad #(StmtM);

Actions can be turned into statements. Takes 1 cycle to execute.

function Stmt s(Action a);

There are if statements, with one and two arms. Takes 1 + n cycles to execute if the chosen branchtakes n cycles.

function Stmt if1(Bool c, Stmt s);

function Stmt if2(Bool c, Stmt s, Else el, Stmt e);

A type to make the else arm more readable.

117

Page 118: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

typedef enum { Else } Else;

The while statement. Testing the condition takes 1 cycle.

function Stmt while(Bool c, Stmt s);

The forx statement. The initialization is executed before the loops start. The increment is executedafter all statements in the loop body. Testing the condition takes 1 cycle.

function Stmt forx(Tuple3 #(Stmt, Bool, Stmt) ff, Stmt b);

Break out of the enclosing loop. Takes 0 cycles to execute. If executed outside a loop it terminatesthe FSM execution.

Stmt break;

Start next iteration of the enclosing loop. Takes 0 cycles to execute.

Stmt continue;

Turn (a sequence of) statments into a parallel construct. Takes n+1 cycles to execute if the longestbranch takes n cycles.

function Stmt par(Stmt s);

Make sure (a sequence of) statements are executed seqeuntially.

function Stmt seq(Stmt s);

The empty statement, does nothing. Takes 0 cycles to execute.

Stmt skip;

The unit statement, does nothing. Takes 1 cycle to execute.

Stmt delay;

Wait until a condition is fulfilled. Takes at least 1 cycle to execute.

function Stmt wait(Bool c);

C.41.2 Variables

The interface of variables.

interface Var #(type a);

method a _read();

method Stmt _write(a x1);

endinterface: Var

Declare a variable initialized at reset.

118

Page 119: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

function StmtM#(Var#(a)) static(a x)

provisos (Bits#(a, sa));

Declare a variable with an unspecified initial value.

StmtM#(Var#(a)) static_

provisos (Bits#(a, sa));

Declare a variable that is initialized each time the block is used.

function StmtM#(Var#(a)) auto(a x)

provisos (Bits#(a, sa));

C.41.3 Locks

The lock type is abstract.

typedef ... Lock;

Create a new lock.

StmtM#(Lock) mkLock;

Acquire a lock; waits until the lock is gotten.

function Stmt lock(Lock l);

Release a lock.

function Stmt unlock(Lock l);

C.41.4 State machine interface

The state machine interface.

interface StmtFSM;

method Action start();

method Bool done();

endinterface: StmtFSM

Turn a statement into a state machine.

module stmtFSM#(Stmt s)(StmtFSM);

119

Page 120: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.41.5 Examples

A factorial example:

typedef Var#(Bit#(32)) Int32;

function Stmt fac(Bit#(32) x);

return (actionvalue

Int32 i;

i <- static_;

Int32 r;

r <- auto(1);

Int32 upper;

upper <- static_;

if2(x > 15,

actionvalue

r <= 0;

endactionvalue,

Else,

actionvalue

upper <= x;

endactionvalue);

forx(((i <= 1) , (i <= upper) , (i <= i+1)),

actionvalue

r <= r * i;

endactionvalue);

s($display("fac %0d = %0d", x, r));

endactionvalue);

endfunction: fac

module factest(Empty);

Reg#(Bit#(32)) n;

mkReg#(10) the_n(n);

mfac <- stmtFSM(fac(n));

o <- mkOnce(mfac.start);

rule

(True); o.start;

endrule

endmodule: factest

Parallel execution and locks:

Stmt party;

party = actionvalue

Int32 i;

i <- static(0);

l <- mkLock;

while(i < 100,

actionvalue

par(actionvalue

seq(actionvalue

lock(l);

i += 1;

i += 1;

unlock(l);

endactionvalue);

seq(actionvalue

lock(l);

120

Page 121: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

i += 1;

i += 1;

i += 1;

i += 1;

unlock(l);

endactionvalue);

seq(actionvalue

lock(l);

s($display("i=%0d", i));

unlock(l);

endactionvalue);

endactionvalue);

endactionvalue);

endactionvalue;

C.42 Tabulate

The tabulate function can be used to tabulate an arbitrary function (given the type constraints).This means that that the function will be precomputed for its argument at compile time and theright value will be selected at run time by a case expression.

This is a powerful function that captures several design patterns where a mux is used.

function b tabulate(function b f(a x1), a x)

provisos (Bounded#(a), Bits#(a, sa));

NOTE, the tabulate function uses comparison of the bit representations of the type “a” to decideequality. This may not behave like the defined equality for the type.

C.43 UIntRange

The type UIntRange lo hi represents an unsigned integer using the number of bits needed to store“hi”. The values of the type are in the range “lo..hi”.

The advantage of using UIntRange over UInt is that the compiler can take advantage of the rangeinformation when compiling the program. It also makes the code more self-documenting and catchesmore type errors.

NOTE, using unpack it is possible to make a value that is not within the specified range. Doing sowill result in unspecified behaviour.

data UIntRange lo hi = · · · abstract · · ·

instance Bits #(UIntRange#(lo, hi), TLog#(TAdd#(hi, 1)));

instance Literal #(UIntRange#(lo, hi));

instance Bounded #(UIntRange#(lo, hi));

Increment a value. This operation wraps around so incrementing “hi” gives the value “lo”.

incr :: UIntRange#(lo, hi) -> UIntRange#(lo, hi);

Decrement a value. This operation wraps around so decrementing “lo” gives the value “hi”.

decr :: UIntRange#(lo, hi) -> UIntRange#(lo, hi);

121

Page 122: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

C.44 Wallace

A Wallace tree adder is useful when many numbers need to be added at the same time. It works byadding 3 bits of weight n producing 2 bits, one of weight n and one of weight n + 1. By repeatingthis step a number of times the addition of k bits of weight n has been reduced to adding 2k/3 bits(of different weights). By repeating this over and over we finally reach a point when there is onlyone bit left at each weight, and this is the final result.

The wallaceAddBags function takes a list of bags of bits and computes the sum of all the bits. Eachbag is represented as a List. The bits in the first bag as weight 20, in the second bag 21, etc. Theinitial number of input lists should equal the number of bits in the result.

function Bit#(n) wallaceAddBags();

The wallaceAdd function takes a list of m bit numbers and adds them forming an n bit result.

function Bit#(n) wallaceAdd()

provisos (Add#(m, k, n));

122

Page 123: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Index

· (infix function composition), 75$ (infix low-precedence “apply”), 74& (Bitwise class “and” method), 69&& (Bool “and” operator), 71(..) (exporting member names), 12* (Arith class “multiply” method), 69*/ (close nested comment), 10+ (Arith class “add” method), 69++ (Bit concatenation operator), 70+++ (String concatenation operator), 74+> (Rules aggregation operator), 73- (Arith class “subtract” method), 69., see structures, member selection/* (open block comment), 10// (one-line comment), 10/= (Eq class method), 68< (Ord class method), 69<+ (Rules aggregation operator), 73<+> (Rules aggregation operator), 73<< (Bitwise class “left shift” method), 69<= (Ord class method), 69<= (Reg assignment), 33== (Eq class method), 68> (Ord class method), 69>= (Ord class method), 69>> (Bitwise class “right shift” method), 69? (don’t care expression), 11, 37_read (Reg interface method), 51_write (Reg interface method), 51^ (Bitwise class “exclusive or” method), 69$

in identifiers, 10_

in identifiers, 10| (Bitwise class “or” method), 69|> (ActionSeq interface method), 77|| (Bool “or” operator), 71

abs, absolute value, 74ActionList (ActionSeq type), 77actions

Action (type), 39action (keyword), 39combining, 39

ActionSeq (interface type), 78actionSeq (ActionSeq function), 78actionSeqBreak (ActionSeq function), 78ActionValue (type), 40Add (built-in class of size types), 68Add (type class, of size types), 15

addToCollection (ModuleCollect function),106

all (ListN function), 102all (List function), 95any (ListN function), 102any (List function), 96split (Bit function), 50append (ListN function), 98append (List function), 93application

of functions to arguments, 41Arith (type class), 69Array (interface type), 78ArrayFile (package), 79asReg (dummy Reg function), 73asReg (dummy Reg function), 52Assert (package), 79asTypeOf (Prelude function), 76

begin (keyword), 34, 38begin-end expression blocks, 38begin-end statement blocks, 34BGetPut (package), 79bind (Monad class method), 68Bit (type), 70Bit (type), 49bit (type), 49BitonicSort (package), 80Bits (type class), 68Bits (type class), 60

deriving, 61representation of data types, 61

Bitwise (type class), 69Bool (type), 71Boolify (class), 81Bounded (type class), 69Bounded (type class)

deriving, 63

case (keyword), 48case statement, 48CGetPut (package), 82clear (FIFOF interface method), 52clear (FIFO interface method), 52Client (interface), 81ClientServer (package), 81Clock (type), 84ClockConv (class), 84ClockConv (package), 84clockConv (function), 84close (function), 84

123

Page 124: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

Closed (type), 84comment

block, 10one-line, 10

compiler directives, 11compilerVersion, 86CompletionBuffer (interface), 85CompletionBuffer (package), 85concat (ListN function), 98concat (List function), 93conditional statements, 35, 35ConfigReg (package), 85Connectable (class), 85Connectable (package), 85Cons (List constructor), 92cons (ListN function for construction), 98const (Prelude function), 75context, see provisoscontext too weak (overloading resolution), 58curry (Prelude function), 75

date, 86deq (FIFOF interface method), 52deq (FIFO interface method), 52deriving

Bits, 61Bounded, 63Eq, 62brief description, 16for isomorphic types, 63

Div (built-in class of size types), 68div (Integer function), 72don’t care expression, see ?DPSRAM (package), 115drop (List function), 96dropWhile (List function), 96dropWhileRev (List function), 96

Either (type), 73elem (ListN function), 102elem (List function), 96else (keyword), 35Empty (interface type), 71end (keyword), 34, 38endpackage (keyword), 12enq (FIFOF interface method), 52enq (FIFO interface method), 52Enum (package), 86Fork (package), 89enum, 29enumAll (Enum function), 86enumerations, 29enumFromTo (Enum function), 86Environment (package), 86

Eq (type class), 68Eq (type class)

deriving, 62EqFunction (package), 87error (forced error), 74exp (Integer function), 72log2 (Integer function), 72export (keyword), 12export, identifiers from a package, 12

False (Bool constant), 71FIFO (package), 87FIFO (type), 87FIFO (interface type), 52FIFOF (package), 87FIFOF (type), 87FIFOF (interface type), 52FileGet (interface type), 89FileIO (package), 88FilePut (interface type), 88filter (List function), 93fire when enabled (rule assertion), 57first (FIFOF interface method), 52first (FIFO interface method), 52flip (Prelude function), 75fmap (Monad function), 107fold (ListN function), 99fold (List function), 93foldl (ListN function), 99foldl1 (ListN function), 99foldl1 (List function), 93foldlM (ListN function), 101foldlM (Monad function), 107foldM (ListN function), 101foldM (Monad function), 107foldl (List function), 93foldr (ListN function), 99foldr (List function), 93foldr1 (ListN function), 99foldr1 (List function), 93foldrM (Monad function), 107folduM (Monad function), 107for (Loop function), 105forBreak (Loop function), 105forever (Loop function), 105forN (Loop function), 105fromInteger (Literal class method), 69fromInteger (converting integer literals to spe-

cific types), 11function calls, 41function definitions, 35

genC, 86genList (ListN function), 99

124

Page 125: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

genVerilog, 86genWith (ListN function), 99replicate (ListN function), 99replicate (List function), 93genWithM (ListN function), 101Get (interface), 90get (Reg interface method), 73getCollection (ModuleCollect function), 106GetPut (package), 90grammar, 9

head (ListN function), 98head (List function), 95higher order functions, 63

id, the identity function, 75Identifier (grammar terminal), 10identifier (grammar terminal), 10identifiers, 10

export from a package, 12import into a package, 12qualified, 13with $ as first letter, 10

if (keyword), 35in method implicit conditions, 21

if-else statements, 35implicit conditions, 21

asserting that a rule has none, 57on interface methods, 21

import (keyword), 12import, identifiers into a package, 12infix operators

associativity, 37precedence, 37predefined, 37

init (ListN function), 100init (List function), 95instance (of overloading group), 57instance (of type class), 57Int (type), 50Integer (type), 72Integer literals, 10interface

expression, 44interface (keyword)

in interface declarations, 17in interface expressions, 45

interfaces, 17invert (Bitwise class method), 69IVec (package), 91

joinActions (ListN function), 103joinActions (List function), 96joinRules (ListN function), 103joinRules (List function), 97

joinServers (function), 82joinServersBC (function), 82Just, see Maybe

kinds, 68

last (ListN function), 100last (List function), 95lbAccum (function), 104lbaCollect (function), 105LBAddr (type), 104lbRegRO (function), 104lbRegRW (function), 104lbsCollect (function), 105lbsOffset (function), 104LBSReg (interface), 104length (List function), 95LFSR (package), 92liftM (Prelude function), 76List (type), 92ListFIFO (package), 97ListN (type), 98ListReg (package), 103Literal (type class), 69Literals

Integer, 10real, 11String, 11

LocalBus (package), 104Log (built-in class of size types), 68Log (type class, of size types), 15Loop (package), 105loop statements, 35

map (ListN function), 98map (List function), 93mapAccumL (ListN function), 103mapAccumL (List function), 97mapAccumR (ListN function), 103mapAccumR (List function), 97mapCollection (ModuleCollect function), 106mapM (Monad function on ListN), 100mapM (Monad function), 106mapM � (ListN function), 101mapM_ (Monad function), 106mapPairs (ListN function), 103mapPairs (List function), 97Max (built-in class of size types), 68Max (type class, of size types), 15max (Prelude function), 75maxBound (Bounded class method), 69Maybe (type), 72Maybe (type), 32message (compilation message), 74messageM (compilation message), 74

125

Page 126: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

meta notation, see grammarmethods

of an interface, 17mfix (MonadFix class method), 68min (Prelude function), 76minBound (Bounded class method), 69mkArray (Array function), 78mkArrayFile (ArrayFile function), 79mkArrayFull (Array function), 78mkArrayFullFile (ArrayFile function), 79mkBClientServer (function), 80mkBGetPut (function), 80mkCClientServer (function), 83mkCGetCPut (function), 83mkCGetPut (function), 83mkClientBServer (function), 80mkClientCServer (function), 83mkDPSRAM (module), 115mkFIFO (function), 87mkFIFO (FIFO function), 52mkFIFO1 (function), 87mkFIFOF (function), 88mkFIFOF (FIFOF function), 52mkFIFOF1 (function), 88mkFileBinGet (function), 89mkFileBinPut (function), 88mkFileHexGet (function), 89mkFileHexPut (function), 88mkGetBPut (function), 80mkGetCPut (function), 83mkGetPut (function), 90mkGPFIFO (function), 90mkGPFIFO1 (function), 90mkGPSizedFIFO (function), 91mkLBA (function), 105mkLFIFO (function), 87mkLFIFOF (function), 88mkOnce, 108mkRegA (Reg function), 73mkReg (Reg function), 73mkReg (Reg function), 51mkRegU (Reg function), 73mkRegU (Reg function), 51mkRequestBuffer (function), 82mkRequestResponseBuffer (function), 81mkRequestResponseBuffer1 (function), 81mkResponseBuffer (function), 82mkSizedFIFO (function), 87mkSizedFIFO (FIFO function), 52mkSizedFIFOF (function), 88mkSizedFIFOF (FIFOF function), 52mkSizedRequestResponseBuffer (function), 82mkSPSRAM (module), 114mkSRAMFile (module), 115

mkWrapSRAM (function), 114mkWrapSTRAM (function), 114mod (Integer function), 72Module (type), 74ModuleCollect (package), 106ModuleCollect (type), 106modules

module (keyword), 19Monad (type class), 68, 106MonadFix (type class), 68Mul (built-in class of size types), 68

Nat (type), 72negate (Arith class method), 69Nil (List constructor), 92nil (ListN function for construction), 98no implicit conditions (rule assertion), 57noAction (empty action), 70noAction (empty action), 40noinline (pragma), 56not (Bool function), 71Nothing, see Maybenull (List function), 94

OInt (type), 108Once (type), 108operators

infix, 37prefix, 37

Ord (type class), 69overloading groups, see type classesoverloading, of types, 57

pack (Bits class method), 68pack (Bits type class overloaded function), 60package, 12package (keyword), 12pattern matching, 47

error, 49patterns, 47polymorphism, 14PopCount (package), 109pragma, 55Prelude, 68Prelude, 13PrimAction (type), 70provisos, 58

brief description, 14Pull (interface type), 109Push (interface type), 110Put (interface), 90

RAM (package), 112RAM (type), 112RAMclient (type), 112

126

Page 127: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

RAMreq (type), 112Real literals, 11records, see structReg (type), 73Reg (type), 51register assignment, 33register writes, 33replicateM (ListN function), 101replicateM (List function), 107Reserved (type), 115reset, 108return (Monad class method), 68reverse (ListN function), 100reverse (List function), 94rotate (ListN function), 100rotate (List function), 94rotateR (ListN function), 100rotateR (List function), 94RPush (interface type), 115rule

expression, 46rule assertions, 56

fire when enabled, 57no implicit conditions, 57

rulesaggregating, 47prioritizing, 47

Rules (type), 73Rules (type), 46RWire (package), 117

scanl (ListN function), 103scanl (List function), 96scanr (ListN function), 102scanr (List function), 96select (ListN function), 102select (List function), 95SeqList (ActionSeq type), 78seqOfActionSeq (ActionSeq function), 78sequence (Monad function on ListN), 101sequence (Monad function), 107Server (interface), 81set (Reg interface method), 73signedGE (Bit function), 71signedGT (Bit function), 71signedLE (Bit function), 71signedLT (Bit function), 71signedShiftRight (Bit function), 71signExtend (Bit function), 71size types, 14

type classes for constraints, 15SizeOf (pseudo-function on types), 61sortLe (function), 80split (Bit splitting function), 71

splitServer (function), 82SPSRAM (package), 114SRAM (package), 114SRAMFile (package), 115sscanl (ListN function), 103sscanl (List function), 96sscanr (ListN function), 102sscanr (List function), 96done (ActionSeq interface method), 78start, 108start (ActionSeq interface method), 78staticAssert, 79Stmts (package), 117STRAM (package), 114String (type), 74String literals, 11struct, 30structure

type definition, 30structures

member selection, 43update, 43

sub (Array interface method), 78SyncSRAM (package), 113SyncSRAMC (type), 113SyncSRAMS (type), 113

Tabulate (package), 121tabulate (Tabulate function), 121tagged, see uniontagged union

type definition, 30tagged unions

member selection, see pattern matchingupdate, 44

tagRAM (function), 113tail (ListN function), 98tail (List function), 95take (ListN function), 102take (List function), 96takeWhile (List function), 96takeWhileRev (List function), 96testAssert, 86toList (ListN function), 103toListN (ListN function), 103TRAM (package), 112TRAM (type), 112TRAMclient (type), 112TRAMreq (type), 112TRAMresp (type), 113transpose (ListN function), 102transpose (List function), 95transposeLN (ListN function), 102True (Bool constant), 71

127

Page 128: BluespecTM SystemVerilog Version 3.8 Reference … Guide Preliminary Draft Please do not circulate without permission from Bluespec, Inc. ... As in Verilog, identi ers whose rst character

truncate (Bit function), 71tuples

expressions, 50patterns, 51selecting components, 51type definition, 50

type assertionsstatic, 42

type class, 68type classes, 57type declaration, 13type variables, 14types, 13

parameterized, 14polymorphic, 14

UInt (type), 50UIntRange (type), 121uncurry (Prelude function), 75underscore, see

union, 30union tagged

type definition, 30unpack (Bits class method), 68unpack (Bits type class overloaded function),

60unzip (ListN function), 100unzip (List function), 94upd (Array interface method), 78update (ListN function), 102update (List function), 95upto (List function), 94

valueOf (pseudo-function of size types), 15variable declaration, 33variables, 33verilog (pragma), 55

Wallace (package), 122warning (forced warning), 74while (Prelude function), 75wrapSRAM (module), 114wrapSTRAM (module), 114

zeroExtend (Bit function), 71zip (ListN function), 100zip (List function), 94zip3 (List function), 94zip4 (List function), 94zipAny (ListN function), 100zipWith (ListN function), 99zipWith (List function), 94zipWith3 (ListN function), 99zipWith3 (List function), 94zipWith4 (List function), 94

zipWithAny (ListN function), 99zipWithAny3 (ListN function), 100zipWithM (ListN function), 101zipWithM (List function), 106, 107zipWithM � (ListN function), 101

128