know_your_objects - oop for hardware designers

36
Know Your Objects OOP for Hardware Designers Rev. 1.0 ALDEC Webinar Created and Presented by Jerry Kaczynski, ALDEC Research Engineer

Upload: doomachaley

Post on 14-Jul-2016

12 views

Category:

Documents


3 download

DESCRIPTION

Object oriented Programming for HARDWARE

TRANSCRIPT

Page 1: Know_Your_Objects - OOP for Hardware Designers

Know Your Objects

OOP for Hardware Designers

Rev. 1.0

ALDEC Webinar

Created and Presented by

Jerry Kaczynski,

ALDEC Research Engineer

Page 2: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Agenda • Introduction: Raising Abstraction Level

• Benefits of Encapsulation

• Why We Need Inheritance

• That Mysterious Polymorphism

• Decoding Dynamic Dispatch

• Summary/Q&A

2

Page 3: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

RAISING ABSTRACTION LEVEL

Introduction:

3

Page 4: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Abstraction In Design Domain • When first digital Integrated Circuits were designed,

there was no need to raise abstraction level: small number of transistors needed to implement 4 NAND gates could be drawn on a piece of paper.

• Programming PLDs at the transistor level was not feasible: schematics and other gate level design tools were created.

• Schematics for CPLDs/FPGAs were getting too complicated, so RTL and behavioral descriptions were needed.

• Complete systems that can be squeezed into modern circuits require even higher levels of abstraction: transaction or even pure algorithmic.

4

Page 5: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Abstraction In Program Domain • First computers were programmed by flipping switches representing

bits of registers – no abstraction whatsoever…

• Assembly languages replaced bit combinations with easier to comprehend mnemonics. More abstract, but still tied to the particular machine.

• High-level languages abstracted both control (procedures, functions, etc.) and data (vectors, arrays, records, etc.)

• Object Oriented Programming (OOP) tied abstracted control and data together, providing powerful tool for designing large programs/systems.

5

Page 6: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Abstraction in HDLs • Classical Hardware Description Languages (HDLs) – VHDL and Verilog –

are operating at the procedural level to let you design at RTL or behavioral level.

• New, large digital systems require at least Transaction Level Modeling, which is easiest to implement in OOP.

• The penalty for using high abstraction level is inability to control minute details of implementation.

• Abstract models are gradually refined down to RTL/gate level, where they can be fine-tuned and implemented.

6

ALGORITHM

TLM

RTL

GATE

Page 7: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

BENEFITS OF ENCAPSULATION

Bundling Things In Your Design:

7

Page 8: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Old Style • Classical languages (BASIC, C, Verilog, VHDL) abstract control and data

separately:

Subroutines (procedures/tasks and functions) describe what program can do.

Data types (arrays, records/structures) define data that can be manipulated by subroutines.

• In large designs that extensively use language resources this separation often leads to confusion: Can I use to_integer function with STD_LOGIC_VECTOR argument?

Can I read only low byte of memory word?

• Wouldn’t it be nice if data and operations you can perform on it were tied together?

8

Page 9: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

VHDL Protected Types • VHDL has a mechanism for encapsulating data (in bundles resembling

records) and procedures/functions operating on them in protected types.

• Protected types have structure similar to packages: Public subprograms and data fields are listed in protected type declaration.

Private data fields/subprograms and implementations of public subprograms are listed in protected type body.

• To use protected type, you have to declare shared variable of that type.

• To do anything with shared variable, you use notation similar to accessing record fields: shared_variable_name.member_name.

• Note: This feature is available in the language since 2002 version.

9

Page 10: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

VHDL ‘OOP’ Counter

type base_counter is protected procedure clear; procedure count; impure function show return integer; end protected base_counter; type base_counter is protected body variable contents : integer := -7; procedure clear is begin contents := 0; end procedure clear; procedure count is begin contents := contents + 1; end procedure count; impure function show return integer is begin return contents; end function show; end protected body base_counter;

shared variable my_counter : base_counter; . . . -- 'Untimed' use my_counter.clear; OUTPUT <= my_counter.show; . . . my_counter.count; OUTPUT <= my_counter.show; . . . -- 'Refined' use process (CLK, RESET) begin if RESET then my_counter.clear; elsif CLK'event and CLK='1' then my_counter.count; end if; end process;

10

Page 11: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Is it enough? • Protected type approach to bundling data and functions works pretty

well, but there is some room for improvements…

To enhance existing protected type, you have to modify its source code: reuse is not flexible enough.

Shared variables are static, so all you can do with them is decided at the compilation time.

• Some general-purpose languages (C++, Java) and SystemVerilog support classes and objects – the staple of OOP:

You can create child class that inherits everything from the original class.

Objects are created in dynamically allocated memory at runtime.

11

Page 12: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Classes and Objects • Class is an abstract idea of grouping together: Some pieces of data called attributes (or member variables or

properties),

Subroutines that operate on those pieces of data: methods (a.k.a. member functions).

• Based on the idea of class, we can build actual objects (can you see the analogy with types and variables?)

• When we declare object of a certain class in our program, a handle (or pointer) is created – not actual object.

• In the program code we have to call constructor method of the class to allocate memory for the object and assign initial values to its properties.

12

Class

Object

Page 13: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

SystemVerilog ‘OOP’ Counter

package oop; class Base_Counter; int contents; function new(); contents = -7; endfunction task clear(); contents = 0; endtask task count(); contents += 1; endtask function int show(); return contents; endfunction endclass endpackage

module top; timeprecision 100ps; timeunit 1ns; import oop::*; Base_Counter my_counter = new; initial begin $display($stime, my_counter.show); #10 my_counter.clear; $display($stime, my_counter.show); repeat(10) begin #10 my_counter.count; $display($stime, my_counter.show); end end endmodule

13

Page 14: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Encapsulation? • One of the main reasons to use classes and objects is

to achieve encapsulation:

Bundling of data (attributes) and procedures operating on it (methods).

Shielding attributes from direct access by end users.

• Some scholars prefer only first or second feature of encapsulation mentioned above; we should be aware of both.

• Different languages assume different default level of access to class members:

If, like in C++, members are private by default (accessible only within its class), you can make them public by adding public qualifier in the declaration.

If members are public by default (like in SystemVerilog) you can change

it by using local qualifier (in SV only; C++ uses private qualifier).

14

Page 15: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Introducing UML • Universal Modeling Language (UML) is a popular graphical

representation of classes and their relationships.

• In UML class diagram a box represents the class:

Top section names the class.

Middle section lists class attributes.

Bottom section describes class methods.

• Level of member description detail varies: in general diagrams only member names are listed (no data types, argument names, etc.)

• Non-default access to the member may be marked by:

+ in front of the name of public member.

– in front of the name of private/local member.

15

Page 16: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

WHY WE NEED INHERITANCE

Improving Reuse:

16

Page 17: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Smart Reuse • Let’s say that we want to add “load” functionality to our Base_Counter

class.

• In procedural languages we would have to:

Copy description of the original counter.

Add “load” functionality.

Save modified description as a new counter.

• This approach works as long as Base_Counter never changes:

If somebody changes Base_Counter description but forgets to modify new counter accordingly – we have a problem…

• Inheritance – very important feature of OOP – can solve this problem…

17

Page 18: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Inheritance • We can use inheritance to create new class (called derived class or child

class) based on original class (called base class or parent class).

• Inheritance creates “is-a” relationship: new class objects are also old class objects and can replace them in the program code.

• UML class diagram represents inheritance by ‘empty triangle arrow’ pointing from the new to the old class.

• Only changes to the old class contents are listed in the new class box: everything else is … inherited.

• Arrow points in the direction of generalization and against the direction of specialization.

• In our diagram, new Load_Counter class specializes old Base_Counter class (which is more general of the two).

18

Page 19: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

SystemVerilog Child Counter Class

package oop; class Base_Counter; int contents; function new(); contents = -7; endfunction task clear(); contents = 0; endtask task count(); contents += 1; endtask function int show(); return contents; endfunction endclass

class Load_Counter extends Base_Counter; task load(input int val); contents = val; endtask endclass

endpackage

module top; timeprecision 100ps; timeunit 1ns; import oop::*; Load_Counter my_counter = new; initial begin $display($stime, my_counter.show); #10 my_counter.clear; $display($stime, my_counter.show); repeat(5) begin #10 my_counter.count; $display($stime, my_counter.show); end #10 my_counter.load(777); $display($stime, my_counter.show); end endmodule

19

We have extended base class functionality by adding method.

Page 20: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Another Flavor of Inheritance • Our Load_Counter demonstrated how derived class can add members,

but it is not the only way…

• Child class can also override methods of the parent class by providing their new definitions.

• Let’s say that we want to crate newer class that still has ‘load’ functionality, but is also parameterized with maximal count value.

• This time we will have to write new count() method that rolls back to zero after reaching maximal count.

• Updated UML class diagram of our class hierarchy is presented to the right.

20

Page 21: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Another Child Counter Class

package oop; class Base_Counter; int contents; function new(); contents = -7; endfunction task clear(); contents = 0; endtask task count(); contents += 1; endtask function int show(); return contents; endfunction endclass

class Load_Counter extends Base_Counter; task load(input int val); contents = val; endtask endclass >>>>>>>>

class Super_Counter #(parameter max = 31) extends Load_Counter; task count(); if (contents == max) contents = 0; else contents += 1; endtask endclass

endpackage

21

We have modified base class functionality by overriding method.

Page 22: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Side Comment: Aggregation • Inheritance is the preferred method of building new classes if further

extensions are planned.

• If we perform final assembly of our design (testbench or top-level model), we can use aggregation.

• Aggregation instantiates lower level class objects inside the container class.

• UML class diagrams represent aggregation using lines with empty diamonds at the container class end:

22

Page 23: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

THAT MYSTERIOUS POLYMORPHISM

Making Smart Decisions:

23

Page 24: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Manipulating Handles • All examples of code we have seen so far were calling class constructor

to build object. Address of the object returned by the constructor was stored in the handle, which was used only to access object attributes and methods.

• You can pass objects around by making assignments of one handle to another. It makes sense since you can create multiple objects dynamically…

• OOP always lets you assign object of child class to the handle of parent class type. Such assignment triggers automatic upcasting of the object to the parent class type.

• So assigning Super_Counter object to Base_Counter handle is absolutely legal in our project…

24

Page 25: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Overridden Method Problem • Let’s do some handle passing:

Super_Counter #(15) better_counter = new; Base_Counter count_handle; count_handle = better_counter;

• Now we have Super_Counter object accessible via

Base_Counter variable. We have two implementations of count() method in class hierarchy. What will happen if we call this method like this: count_handle.count;

• The answer is: implementation of overridden method is selected based on the handle type, not object type!

• It means we have a problem: Base_Counter::count()

that is called does not know how to roll back...

25

Page 26: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Virtual Methods • You can declare methods as virtual.

• When you override virtual method in a child class, implementation created for that class will stick with the object no matter what is the type of the handle!

• That type of behavior is called polymorphism and is one of the key features of OOP.

• Let’s try it in our class hierarchy:

We have to make count() virtual.

We also have to display some control messages from virtual and non-virtual methods so we can see who is calling whom…

26

Page 27: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Counter Class with Virtual Method

package oop; class Base_Counter; int contents; function new(); contents = -7; endfunction task clear(); contents = 0; $display( "Base_Counter::clear was executed! \n"); endtask virtual task count(); contents += 1; $display( "Base_Counter::count was executed! \n"); endtask function int show(); return contents; endfunction endclass

class Load_Counter extends Base_Counter; task load(input int val); contents = val; endtask endclass >>>>>>>>

class Super_Counter #(parameter max = 31) extends Load_Counter; task clear(); contents = 0; $display( "Super_Counter::clear was executed! \n"); endtask

virtual task count(); if (contents == max) contents = 0; else contents += 1; $display( "Super_Counter::count was executed! \n"); endtask endclass

endpackage

27

Page 28: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Using Virtual Methods – TB // Here’s the snippet of testbench using our class with virtual method: Super_Counter #(15) better_counter = new; Base_Counter simple_counter = new; Base_Counter count_handle; initial begin count_handle = better_counter; $display("Calling non-virtual 'clear' from 'Base_Counter' object with 'Base_Counter' handle..."); simple_counter.clear; $display("Calling non-virtual 'clear' from 'Super_Counter' object with 'Base_Counter' handle..."); count_handle.clear; #10; $display("Calling virtual 'count' from 'Base_Counter' object with 'Base_Counter' handle..."); simple_counter.count; $display("Calling virtual 'count' from 'Super_Counter' object with 'Base_Counter' handle..."); count_handle.count; end

28

Page 29: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Using Virtual Methods – Results // Here’s the console dump from simulation of our class with virtual method: # KERNEL: Calling non-virtual 'clear' from 'Base_Counter' object with 'Base_Counter' handle... # KERNEL: Base_Counter::clear was executed! # KERNEL: # KERNEL: Calling non-virtual 'clear' from 'Super_Counter' object with 'Base_Counter' handle... # KERNEL: Base_Counter::clear was executed! # KERNEL: # KERNEL: Calling virtual 'count' from 'Base_Counter' object with 'Base_Counter' handle... # KERNEL: Base_Counter::count was executed! # KERNEL: # KERNEL: Calling virtual 'count' from 'Super_Counter' object with 'Base_Counter' handle... # KERNEL: Super_Counter::count was executed! # KERNEL:

29

Page 30: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

DECODING DYNAMIC DISPATCH

Making Miracles Happen:

30

Page 31: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Things Can Get Complicated • If this presentation is your first encounter with encapsulation,

polymorphism and similar terms, you are justified to think that they are not exactly trivial…

• But wait! Developers of simulators have quite difficult tasks to deal with, too. Especially if they were handling only Verilog or VHDL before.

• If you call a function in classical HDL, compiler knows its location and can insert proper jump in the executable code.

• When compiler encounters virtual method call, compiler usually doesn’t know which implementation to call…

31

Page 32: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Dynamic Dispatch • In addition to dynamic memory allocation for objects, simulators

have to deal with runtime binding of method calls to proper implementations.

• This process is called dynamic dispatch or dynamic binding and requires some novel approach to organizing simulation.

• Usually compiler stores virtual method calls in special virtual table. Simulator fills that table with proper implementation addresses as objects are created and updates it as objects are passed around.

• Of course this handling is slower than regular method calls – that’s why methods are not virtual by default.

32

Page 33: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Why All The Trouble? • Objects, encapsulation, polymorphism mixed with Transaction

Level Modeling (TLM) let you create very powerful, yet extremely flexible verification environments.

• You probably heard about OVM or UVM – they are such environments! Now you should have a little easier task of understanding them….

33

Page 34: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

SUMMING UP

34

Page 35: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Tools Used • All pieces of code presented in this webinar (VHDL and SystemVerilog)

were tested on Riviera-PRO™ simulator.

• While you can draw UML diagrams by hand, there are free tools that can make this task easier and faster:

Java-based Violet UML Editor runs on any platform and is ideal solution for beginners not familiar with UML. All UML diagrams in this presentation were created in Violet. To download it, google “VioletUML”.

UMLet is a slightly more advanced UML editor. Google its name to download it.

Popular multi-platform graphing tool Dia (http://dia-installer.de/) can create UML diagrams, too.

• Although there are tools that can generate C++ or Java code from the UML diagrams, none of them can generate SystemVerilog code…

35

Page 36: Know_Your_Objects - OOP for Hardware Designers

www.aldec.com

Conclusion • Feel free to contact ALDEC if you need more info about EDA-related topics

and our design creation and verification tools.

36

Download: • Recorded webinars • White papers • Trial versions of our tools

ALDEC Website: http://www.aldec.com Telephone E-mail USA +1-702-990-4400 [email protected] Canada: +1-613-867-8600 [email protected] Europe: +33-6-80-32-60-56 [email protected] Japan: +81-3-5312-1791 [email protected] India: +91-80-32551030 [email protected] China: +86-21-6875-20-30 [email protected] Taiwan: +886-2-26599119 ext. 950 [email protected] Israel: +972-52-2573422 [email protected]