SystemC 26 Communication - port
Three key concepts for communication
-
Interface:
- a) an abstract class derived from
sc_interface
but not derived fromsc_object
. - b) contains a set of pure virtual functions that shall be defined in one or more channels derived from that interface.
- a) an abstract class derived from
-
Port:
- a) provides the means by which a module can be written such that it is independent of the context in which it is instantiated.
- b) forwards interface method calls to the channel to which the port is bound.
- c) defines a set of services (as identified by the type of the port) that are required by the module containing the port.
-
Channel:
- a)
sc_prim_channel
is the base class for all primitive channels. - b) channel may provide public member functions that can be called using the interface method call paradigm.
- c) a primitive channel shall implement one or more interfaces.
- a)
In short:
- Port requires services, interface defines services, channel implements services.
- A port can connect (bind) to a channel if the channel implements the interface that the port requires.
- A port is basically a pointer to a channel.
when to use port:
- If a module is to call a member function belonging to a channel that is outside the module itself, that call should be made using an interface method call through a port of the module. Otherwise is considered bad coding style.
- However, a call to a member function belonging to a channel instantiated within the current module may be made directly. This is known as portless channel access.
- If a module is to call a member function belonging to a channel instance within a child module, that call should be made through an export of the child module.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;
SC_MODULE(MODULE1) { // defines one module
sc_signal<int> s; // a signal (channel) inside the module
sc_port<sc_signal_out_if<int> > p; // a port used to write to an outside channel
SC_CTOR(MODULE1) {
SC_THREAD(selfWrite); // a process to write to own channel
SC_THREAD(selfRead); // a process to read from own channel
sensitive << s; // triggered by value change on the channel
dont_initialize();
SC_THREAD(outsideWrite); // a process to write to an outside channel
}
void selfWrite() {
int val = 1; // init value
while (true) {
s.write(val++); // write to own channel
wait(1, SC_SEC); // repeat after 1 s
}
}
void selfRead() {
while (true) {
std::cout << sc_time_stamp() << ": reads from own channel, val=" << s.read() << std::endl; // read from own channel
wait(); // receives from signal
}
}
void outsideWrite() {
int val = 1; // init value
while (true) {
p->write(val++); // write to an outside channel, calls the write method of the outside channel. p is a pointer.
wait(1, SC_SEC);
}
}
};
SC_MODULE(MODULE2) { // a module that reads from an outside channel
sc_port<sc_signal_in_if<int> > p; // a port used to read from an outside channel
SC_CTOR(MODULE2) {
SC_THREAD(outsideRead); // a process to read from an outside channel
sensitive << p; // triggered by value change on the channel
dont_initialize();
}
void outsideRead() {
while (true) {
std::cout << sc_time_stamp() << ": reads from outside channel, val=" << p->read() << std::endl; // use port to read from the channel, like a pointer.
wait(); // receives from port
}
}
};
int sc_main(int, char*[]) {
MODULE1 module1("module1"); // instantiate module1
MODULE2 module2("module2"); // instantiate module2
sc_signal<int> s; // declares a signal (channel) outside module1 and moudle2
module1.p(s); // binds (connects) port p of module1 to channel (signal) s
module2.p(s); // binds port p of module2 to channel s
sc_start(2, SC_SEC);
return 0;
}
// Result:
// direct channel read
0 s: reads from own channel, val=1
// read through port
0 s: reads from outside channel, val=1
// direct channel read
1 s: reads from own channel, val=2
// read through port
1 s: reads from outside channel, val=2