Download presentation
Presentation is loading. Please wait.
Published byAriel Lucas Modified over 9 years ago
1
CPE 626 The SystemC Language Aleksandar Milenkovic E-mail: milenka@ece.uah.edumilenka@ece.uah.edu Web:http://www.ece.uah.edu/~milenkahttp://www.ece.uah.edu/~milenka
2
A. Milenkovic 2 Outline Motivation for SystemC What is SystemC? Modules Processes
3
A. Milenkovic 3 Standard Methodology for ICs System-level designers write a C or C++ model Written in a stylized, hardware-like form Sometimes refined to be more hardware-like C/C++ model simulated to verify functionality Parts of the model to be implemented in hardware are given to Verilog/VHDL coders Verilog or VHDL specification written Models simulated together to test equivalence Verilog/VHDL model synthesized
4
A. Milenkovic 4 Designing Big Digital Systems Current conditions Every system company was doing this differently Every system company used its own simulation library System designers don’t know Verilog or VHDL Verilog or VHDL coders don’t understand system design Problems with standard methodology: Manual conversion from C to HDL oError prone and time consuming Disconnect between system model and HDL model oC model becomes out of date as changes are made only to the HDL model System testing oTests used for C model cannot be run against HDL model => they have to be converted to the HDL environment
5
A. Milenkovic 5 Idea of SystemC C and C++ are being used as ad-hoc modeling languages Why not formalize their use? Why not interpret them as hardware specification languages just as Verilog and VHDL were? SystemC developed at Synopsys to do just this
6
A. Milenkovic 6 SystemC Design Methodology Refinement methodology Design is slowly refined in small sections to add necessary hardware and timing constructs Written in a single language higher productivity due to modeling at a higher level testbenches can be reused saving time Future releases will have constructs to model RTOS
7
A. Milenkovic 7 What Is SystemC? A subset of C++ that models/specifies synchronous digital hardware A collection of simulation libraries that can be used to run a SystemC program A compiler that translates the “synthesis subset” of SystemC into a netlist
8
A. Milenkovic 8 What Is SystemC? Language definition is publicly available Libraries are freely distributed Compiler is an expensive commercial product See www.systemc.org for more information
9
A. Milenkovic 9 Quick Overview A SystemC program consists of module definitions plus a top-level function that starts the simulation Modules contain processes (C++ methods) and instances of other modules Ports on modules define their interface Rich set of port data types (hardware modeling, etc.) Signals in modules convey information between instances Clocks are special signals that run periodically and can trigger clocked processes Rich set of numeric types (fixed and arbitrary precision numbers)
10
A. Milenkovic 10 Modules Hierarchical entity Similar to Verilog’s module Actually a C++ class definition Simulation involves Creating objects of this class They connect themselves together Processes in these objects (methods) are called by the scheduler to perform the simulation
11
A. Milenkovic 11 Modules SC_MODULE(mymod) {// struct mymod : sc_module { /* port definitions */ /* signal definitions */ /* clock definitions */ /* storage and state variables */ /* process definitions */ SC_CTOR(mymod) { /* Instances of processes and modules */ } };
12
A. Milenkovic 12 Ports Define the interface to each module Channels through which data is communicated Port consists of a direction inputsc_in outputsc_out bidirectionalsc_inout and any C++ or SystemC type SC_MODULE(mymod) { sc_in load, read; sc_inout data; sc_out full; /* rest of the module */ };
13
A. Milenkovic 13 Signals Convey information between modules within a module Directionless: module ports define direction of data transfer Type may be any C++ or built-in type SC_MODULE(mymod) { /* port definitions */ sc_signal > s1, s2; sc_signal reset; /* … */ SC_CTOR(mymod) { /* Instances of modules that connect to the signals */ } };
14
A. Milenkovic 14 Instances of Modules Each instance is a pointer to an object in the module Connect instance’s ports to signals SC_MODULE(mod1) { … }; SC_MODULE(mod2) { … }; SC_MODULE(foo) { mod1* m1; mod2* m2; sc_signal a, b, c; SC_CTOR(foo) { m1 = new mod1(“i1”); (*m1)(a, b, c); m2 = new mod2(“i2”); (*m2)(c, b); } };
15
A. Milenkovic 15 Positional Connection // filter.h #include "systemc.h“ // systemC classes #include "mult.h“ // decl. of mult #include "coeff.h“ // decl. of coeff #include "sample.h“ // decl. of sample SC_MODULE(filter) { sample *s1;// pointer declarations coeff *c1; mult *m1; // signal declarations sc_signal > q, s, c; SC_CTOR(filter) { // constructor s1 = new sample ("s1"); // create obj. (*s1)(q,s); // signal mapping c1 = new coeff ("c1"); (*c1)(c); m1 = new mult ("m1"); (*m1)(s,c,q); }
16
A. Milenkovic 16 Named Connection #include "systemc.h“ // systemC classes #include "mult.h“ // decl. of mult #include "coeff.h“ // decl. of coeff #include "sample.h“ // decl. of sample SC_MODULE(filter) { sample *s1; coeff *c1; mult *m1; sc_signal > q, s, c; SC_CTOR(filter) { s1 = new sample ("s1"); s1->din(q); // din of s1 to signal q s1->dout(s); // dout to signal s c1 = new coeff ("c1"); c1->out(c); // out of c1 to signal c m1 = new mult ("m1"); m1->a(s); // a of m1 to signal s m1->b(c); // b of m1 to signal c m1->q(q); // q of m1 to signal c }
17
A. Milenkovic 17 Internal Data Storage Local variables to store data within a module May be of any legal C++, SystemC, or user-defined type Not visible outside the module unless it is made explicitly // count.h #include "systemc.h" SC_MODULE(count) { sc_in load; sc_in din; // input port sc_in clock; // input port sc_out dout; // output port int count_val; // internal data storage void count_up(); SC_CTOR(count) { SC_METHOD(count_up); //Method process sensitive_pos << clock; } }; // count.cc #include "count.h" void count::count_up() { if (load) { count_val = din; } else { // could be count_val++ count_val = count_val + 1; } dout = count_val; }
18
A. Milenkovic 18 Processes Only thing in SystemC that actually does anything Functions identified to the SystemC kernel and called whenever signals these processes are sensitive to change value Statements are executed sequentially until the end of the process occurs, or the process is suspended using wait function Very much like normal C++ methods + Registered with the SystemC kernel Like Verilog’s initial blocks
19
A. Milenkovic 19 Processes (cont’d) Processes are not hierarchical no process can call another process directly can call other methods and functions that are not processes Have sensitivity lists signals that cause the process to be invoked, whenever the value of a signal in this list changes Processes cause other processes to execute by assigning new values to signals in the sensitivity lists of the processes To trigger a process, a signal in the sensitivity list of the process must have an event occur
20
A. Milenkovic 20 Three Types of Processes METHOD Models combinational logic THREAD Models testbenches CTHREAD Models synchronous FSMs Determines how the process is called and executed
21
A. Milenkovic 21 METHOD Processes Triggered in response to changes on inputs Cannot store control state between invocations Designed to model blocks of combinational logic
22
A. Milenkovic 22 METHOD Processes Process is simply a method of this class Instance of this process created and made sensitive to an input SC_MODULE(onemethod) { sc_in in; sc_out out; void inverter(); SC_CTOR(onemethod) { SC_METHOD(inverter); sensitive(in); } };
23
A. Milenkovic 23 METHOD Processes Invoked once every time input “in” changes Should not save state between invocations Runs to completion: should not contain infinite loops Not preempted Read a value from the port Write a value to an output port void onemethod::inverter() { bool internal; internal = in; out = ~internal; }
24
A. Milenkovic 24 THREAD Processes Triggered in response to changes on inputs Can suspend itself and be reactivated Method calls wait() function that suspends process execution Scheduler runs it again when an event occurs on one of the signals the process is sensitive to Designed to model just about anything
25
A. Milenkovic 25 THREAD Processes Process is simply a method of this class Instance of this process created alternate sensitivity list notation SC_MODULE(onemethod) { sc_in in; sc_out out; void toggler(); SC_CTOR(onemethod) { SC_THREAD(toggler); sensitive << in; } };
26
A. Milenkovic 26 THREAD Processes Reawakened whenever an input changes State saved between invocations Infinite loops should contain a wait() Relinquish control until the next change of a signal on the sensitivity list for this process void onemethod::toggler() { bool last = false; for (;;) { last = in; out = last; wait(); last = ~in; out = last; wait(); }
27
A. Milenkovic 27 CTHREAD Processes Triggered in response to a single clock edge Can suspend itself and be reactivated Method calls wait to relinquish control Scheduler runs it again later Designed to model clocked digital hardware
28
A. Milenkovic 28 CTHREAD Processes Instance of this process created and relevant clock edge assigned SC_MODULE(onemethod) { sc_in_clk clock; sc_in trigger, in; sc_out out; void toggler(); SC_CTOR(onemethod) { SC_CTHREAD(toggler, clock.pos()); } };
29
A. Milenkovic 29 CTHREAD Processes Reawakened at the edge of the clock State saved between invocations Infinite loops should contain a wait() Relinquish control until the next clock cycle Relinquish control until the next clock cycle in which the trigger input is 1 void onemethod::toggler() { bool last = false; for (;;) { wait_until(trigger.delayed() == true); last = in; out = last; wait(); last = ~in; out = last; wait(); }
30
A. Milenkovic 30 A CTHREAD for Complex Multiply struct complex_mult : sc_module { sc_in a, b, c, d; sc_out x, y; sc_in_clk clock; void do_mult() { for (;;) { x = a * c - b * d; wait(); y = a * d + b * c; wait(); } SC_CTOR(complex_mult) { SC_CTHREAD(do_mult, clock.pos()); } };
31
A. Milenkovic 31 Put It All Together Process TypeSC_METHODSC_THREADSC_CTHREAD Exec. Trigger Signal Events Clock Edge Exec. Suspend NOYES Infinite Loop NOYES Suspend / Resume by N.A.wait() wait_until() Construct & Sensitize Method SC_METHOD(call_back); sensitive(signals); sensitive_pos(signals); sensitive_neg(signals); SC_THREAD(call_back); sensitive(signals); sensitive_pos(signals); sensitive_neg(signals); SC_CTHREAD( call_back, clock.pos()); SC_CTHREAD( call_back, clock.neg());
32
A. Milenkovic 32 Watching SC_THREAD and SC_CTHREAD processes typically have infinite loops that will continuously execute Use watching construct to jump out of the loop Watching construct will monitor a specified condition When condition occurs control is transferred from the current execution point to the beginning of the process
33
A. Milenkovic 33 Watching: An Example // datagen.h #include "systemc.h" SC_MODULE(data_gen) { sc_in_clk clk; sc_inout data; sc_in reset; void gen_data(); SC_CTOR(data_gen){ SC_CTHREAD(gen_data, clk.pos()); watching(reset.delayed() == true); } }; // datagen.cc #include "datagen.h" void gen_data() { if (reset == true) { data = 0; } while (true) { data = data + 1; wait(); data = data + 2; wait(); data = data + 4; wait(); } Watching expressions are tested at the wait() or wait_until() calls. All variables defined locally will lose their value on the control exiting.
34
A. Milenkovic 34 Local Watching Allows us to specify exactly which section of the process is watching which signal, and where event handlers are located W_BEGIN // put the watching declarations here watching(...); W_DO // This is where the process functionality goes... W_ESCAPE // This is where the handlers // for the watched events go if (..) {... } W_END W_BEGIN macro marks the beginning of the local watching block. W_BEGIN – W_DO: watching declarations W_DO – W_ESCAPE: process functionality W_ESCAPE – W_END: event handlers W_END macro ends local watching block
35
A. Milenkovic 35 Local Watching Rules All of the events in the declaration block have the same priority. If a different priority is needed then local watching blocks will need to be nested Local watching only works in SC_CTHREAD processes The signals in the watching expressions are sampled only on the active edges of the process. In an SC_CTHREAD process this means only when the clock that the process is sensitive to changes Globally watched events have higher priority than locally watched events
36
A. Milenkovic 36 D-FF in SystemC // dff.h #include "systemc.h" SC_MODULE(dff) { sc_in din;// data input sc_in clock;// clock input sc_out dout;// data output void doit();// method in the module SC_CTOR(dff) { // constructor SC_METHOD(doit); // doit type is SC_METHOD // method will be called whenever a // positive edge occurs on port clock sensitive_pos << clock; } }; // dff.cc #include "dff.h" void dff::doit() { dout = din; }
37
A. Milenkovic 37 Bus Controller in SystemC Assumptions 32-bit internal data path; 8-bit external data path every address and data transaction will have to be multiplexed over the 8-bit bus Protocol 32-bit address is sent to the bus controller (BC) process address will be multiplexed byte by byte and sent to MC bus controller will wait for ready signal from memory receive the data send the data to microcontroller
38
A. Milenkovic 38 Bus Controller: bus.h // bus.h #include "systemc.h" SC_MODULE(bus) { sc_in_clk clock; sc_in newaddr; sc_in > addr; sc_in ready; sc_out > data; sc_out start; sc_out datardy; sc_inout > data8; sc_uint tdata; sc_uint taddr; void xfer(); SC_CTOR(bus) { SC_CTHREAD(xfer, clock.pos()); // ready to accept new address datardy = true; } };
39
A. Milenkovic 39 Bus Controller: bus.cc // bus.cc #include "bus.h" void bus::xfer() { while (true) { // wait for a new address to appear wait_until( newaddr.delayed() == true); // got a new address so process it taddr = addr.read(); datardy = false; // cannot accept new address now data8 = taddr.range(7,0); start = true; // new addr for memory controller wait(); // wait 1 clock between data transfers data8 = taddr.range(15,8); start = false; wait(); data8 = taddr.range(23,16); wait(); data8 = taddr.range(31,24); wait();
40
A. Milenkovic 40 Bus Controller: bus.cc (cont’d) // now wait for ready signal from memory controller wait_until(ready.delayed() == true); // now transfer memory data to databus tdata.range(7,0) = data8.read(); wait(); tdata.range(15,8) = data8.read(); wait(); tdata.range(23,16) = data8.read(); wait(); tdata.range(31,24) = data8.read(); data = tdata; datardy = true; // data is ready, new addresses ok }
41
A. Milenkovic 41 Local Watching Example Modify bus controller by allowing the bus controller to be interrupted during the transfer from the memory but not to the memory... // now wait for ready signal from memory controller wait_until(ready.delayed() == true);
42
A. Milenkovic 42 Local Watching Example W_BEGIN watching(reset.delayed()); // Active value of reset will trigger watching W_DO // the rest of this block is as before tdata.range(7,0) = data8.read(); // now transfer memory data to databus wait(); tdata.range(15,8) = data8.read(); wait(); tdata.range(23,16) = data8.read(); wait(); tdata.range(31,24) = data8.read(); data = tdata; datardy = true; // data is ready, new addresses ok W_ESCAPE if (reset) { datardy = false; } W_END }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.