mintz q207
Post on 11-May-2015
255 Views
Preview:
TRANSCRIPT
www.trusster.com 1
OOP for Hardware Verification ̶ Demystified!
OOP for Hardware Verification ̶ Demystified!
Mike MintzCo-author, Hardware Verification with C++
and Hardware Verification with SystemVerilogmike@trusster.com
www.trusster.com 2
Overview• Common Currency
• Data Abstraction
• Virtual Functions
• Base Classes
• Q&A
www.trusster.com 3
Common Currency
generator checker
monitordriver
DUT
*There is nothing new under the sun.
Sub sole nihil novi est.*
www.trusster.com 4
Data Abstraction
• Procedural code has separate data structures and functions.
• OOP moves the functions into the data structure,
• Every possible function for that structure is now in one place.
• This works well for a driver.
www.trusster.com 5
Data Abstraction – Code DetailsProcedural Data Abstraction
begin
usb_driver driver;
usb_init (&driver);
usb_enumerate (&driver);
usb_send (&driver, 0, {0,12}, 2);
end
begin usb_driver driver;driver. init ();driver.enumerate ();driver.send (0, {0,12}, 2);
end
struct usb_driver {wire d_plus, d_minus;}
void usb_init (usb_driver * d);
void usb_send_packet (usb_driver * d, int type, int* data, int length);
void usb_enumerate (usb_driver * d);
struct usb_driver {
wire d_plus, d_minus;
void init ();
void send_packet (int type, int* data, int length);
void enumerate ();
};
www.trusster.com 6
Virtual Function
• Is a run-time function call.• Is the “I don’t know” function.• Great for separating concerns
(and increasing portability).• This works well for a monitor.
www.trusster.com 7
Virtual FunctionsMonitor class Derived for printing
struct usb_printer: public usb_monitor {
virtual void packet_completed (int length, int* data) {
for (int i(0); i < length; ++i) {
printf (“Packet [%d]:0x%x\n”, i, data[i]);
}
}
};
Derived for checkerstruct usb_checker : public usb_monitor {
virtual void packet_completed (int length, int* data) {
checker_->check (length, data);
}
checker* checker_;
};
Derived for channelstruct usb_monitor_agent : public usb_monitor {
virtual void packet_completed (int length, int* data) {
channel_->put (data_packet (length, data));
}
usb_channel* channel_;
};
struct usb_monitor {
wire d_plus, d_minus;
void start_monitor_thread ();
virtual void packet_completed (int length, int* data) =0;
};
www.trusster.com 8
Base Class
• Is a class with one or more virtual methods.
• Is the “follow my lead” class.• Sets up a framework or interface.• This works well for a test irritator.
www.trusster.com 9
Base Classes – Code Details
struct irritator {
virtual void out_of_reset () =0;
virtual void start () =0;
virtual void stop () =0;
virtual void wait_for_completion () =0;
};
Irritator class Derived for USB
Derived for PCIE Derived for Ethernet
struct usb_irritator : public irritator {
virtual void out_of_reset ();
virtual void start ();
virtual void stop ();
virtual void wait_for_completion ();
};
struct pcie_irritator: public irritator {
virtual void out_of_reset ();
virtual void start ();
virtual void stop ();
virtual void wait_for_completion ();
};
struct ethernet_irritator: public irritator {
virtual void out_of_reset ();
virtual void start ();
virtual void stop ();
virtual void wait_for_completion ();
};
www.trusster.com 10
Using OOP – Truss Top-Level Components
Verification Component Hierachy
verification top
test watchdog timer
testbench
test component
irritator
chip
C++HDL
Source: Hardware Verification with C++, page 95, page 100
class verification_component {
public:
verification_component (const std::string&);
virtual void randomize () = 0;
virtual void time_zero_setup () = 0;
virtual void out_of_reset (reset r) = 0;
virtual void start () = 0;
virtual void wait_for_completion () = 0;
virtual void report (const std::string) = 0;
};
www.trusster.com 11
The “Dance”new()
WatchdogTest Testbenchverification_top
randomize()
time_zero_setup()
out_of_reset()
start()
wait_for_completion()
report(“final”)
report(“timeout”)
Createtopobjects
Build andconfigure
Maintestrun
Timeoutpath
Testresults
The Dance
Source: Hardware Verification with C++, page 97
your_test::new(testbench*, watchdog*, std::string)
testbench::new(std::string)
verification_top()
your_test::randomize()
testbench::randomize()
watchdog::time_zero_setup()
testbench::time_zero_setup()
your_test::time_zero_setup()
watchdog::out_of_reset()
testbench::out_of_reset ()
your_test::out_of_reset()
watchdog::write_to_hardware()
testbench::write_to_hardware()
your_test::write_to_hardware()
watchdog::start()
testbench::start()
$TRUSS_HOME/src/watchdog.cpp
your_test::start()
your_test::wait_for_completion()
testbench::wait_for_completion()
your_test::report(“Final Report”)
testbench::report(“Final Report”)
$PROJECT_HOME/verification/tests/your_test.cpp
$PROJECT_HOME/verification/testbench/top/testbench.cpp
Hold the reset line for the minimal amount, then release it. Return when registers can be accessed
Pull wires/registers up or down before releasing the reset line
Perform top-level randomization, for example, chose interfaces or features to be tested
testbench
Legend
your_test
watchdog
watchdog::new(std::string)Build objects,apply constraints
Push the configurations down to the hardware
Pause until the checkers are finished
Print which components have completed
Exercise the chip
The Dance – Detailed Flow
Source: Hardware Verification with C++, page 117
www.trusster.com 12
The “Dance” ̶ painfully detailedyour::new(generator, bfm, checker)
your::randomize()
your::time_zero_setup()
your::out_of_reset()
your::write_to_hardware()
test_component::start()
your::generate_()
test_component:wait_for_completion()
test_component::final_report (“Final Report”)
Start your generator, BFM, and checker
Performs the same function as the top-level components
Set up and run your“main traffic” method
Wait for your checker to complete
test_component::start_()
your::start_components_()
test_component::run_component_traffic_()
$PROJECT_HOME/verification/test_components/your_test_component.cpp
your_test_component:wait_for_completion_ ()
$TRUSS_HOME/inc/truss_test_component.h
called from the same named method in test
Test Component Dance – Detailed Flow
base implementation provided
you must implement
Your test
The test buildsyour test component
Legend
your_test_component::randomize()
test_component::start()
your_test_component::generate_()
Start your testbench generator, bfm, checker
Start_ runs in a thread!
Set up and run your “main traffic” method
test_component::start_()
your_test_component::start_components_()
test_component::run_component_traffic_()
The irritator dance
irritator::run_component_traffic_()
your_test_component::inter_generate_gap_() Pause the generate loop
from your_test::start()
until irritator::stop_generation()
$PROJECT_HOME/verification/test_components/your_irritator.cpp
$TRUSS_HOME/inc/test_component.h, and irritator.hyou may implement
you must implement
Legend
Source: Hardware Verification with C++, page 120 Source: Hardware Verification with C++, page 121
www.trusster.com 13
Summary• OOP is a little bit of syntax with a large
amount of attitude.
• Learning OOP is gradual process, with making mistakes an integral part.
• OOP is not really that “different” – just different packaging
• See www.trusster.com for forums, articles, code, and more.
www.trusster.com 14
Q & A*
*shameless plug
top related