Home > SytemC Tutorials > SystemC Tutorial: ports

SystemC Tutorial: ports

Forewords

These tutorials do not try to teach you everything about SystemC in large chapters taken from the language reference manual (LRM). Instead they focus on the most important aspects of the language, basic and advanced covering them in tutorials designed to take around ten minutes each.

Ports

A Port is an essential element of any SystemC model. Ports are used by modules as a gateway to and from the outside world. In a simplistic way, one can consider a port like the pin of a hardware component.
In HDLs such as VHDL or Verilog, ports are very much like the pins metaphor; In the case of SystemC ports have a substantially more generalized purpose and as a result they are far more sophisticated and useful than their HDLs counterparts.

A simple SystemC port declaration would look like the following code:

sc_in<bool> my_input;

As can be observed the semantic is kept to a minimum level of complexity; The port has a name my_input and in this particular instance, it is of input mode since we used the sc_in<> port type (or port mode if you prefer). The last observation that we can make from this simple line of code is the use of the bool data type inside the <> of the sc_in port type. This data type refers to the kind of data that will be exchanged on that port. In other words we are expecting to receive boolean values on the my_input port.

As you would expect, numerous predefined port types exist in SystemC; Such as: sc_in<Type>, sc_out<Type>, sc_inout<Type>, etc. All of those ports are almost identical to their HDL equivalents in VHDL or Verilog; they have a name, a type and a mode (in, out, etc). As a mater of fact, these kinds of ports are commonly used in RTL SystemC. However, as we indicated earlier, SystemC ports are much more than just RTL like ports; This is because SystemC ports not only have a name and a type but most importantly they define the access mechanisms that should be used on them. Pragmatically the access mechanisms are just a list of allowed messages that can be used on them. If we consider the sc_in<bool> port of the previous example, SystemC defines that one can use the read() message on it. Not surprisingly, an sc_out<> port would allow the use of the write() message. The following code illustrates the use of an sc_in<bool> and an sc_out<bool> ports.

// More code not shown here

sc_in<bool> my_input;
sc_out<bool> my_output;

// More code not shown here

void do_run() {
if (my_input.read() == true) {
my_output.write(false);
} else {
my_output.write(true);
}
}
};

// More code not shown here


For the sake of simplicity the creators of the SystemC language have provided operators that can be used instead of the read() and write() messages. Consequently the following code is also acceptable:

// More code not shown…

void do_run() {
if (my_input == true) {
my_output = false;
} else {
my_output = true;
}
}

// More code not shown…

The list of access messages allowed on specific ports has already been defined for the existing SystemC ports. However SystemC allows the user to define his/her very own set of messages for his/her very own ports. For instance one could imagine the existence of a high-level port used on a CPU model that could receive messages such as: dma_request() or interrupt_request() form the outside world.
The creation of user defined ports goes beyond the scope of this tutorial and can only be covered when you will have gained an understanding of the notion of SystemC interfaces.

Ports and Modules

Up until now we only considered ports in isolation. Prosaically ports are parts of modules and are used to pass data of some form in and out of the modules. SystemC ports are by definition object instances of predefined classes (sc_in<>, sc_out<>, etc.) . As a result they can be accessed from within any member function defined inside the module. For instance the following code would be a valid way of using ports:

class portsTutorial: public sc_module {
public:
sc_in<bool> my_input;
sc_out<bool> my_output;

SC_HAS_PROCESS(portsTutorial);

portsTutorial(sc_module_name nm): sc_module(nm) {
SC_METHOD(do_run);
sensitive << my_input;
}

protected:
void do_run() {
if (my_input.read() == true) {
my_output.write(false);
} else {
my_output.write(true);
}
}
};

Ports and Signals

Ports and signals have a special relationship since ports will connect to other ports via signals (also known as channels). More importantly, ports and signals share a common language. All the messages that can be used on a port should also be available on the signals (channels) connected to that port. As a result specific ports can only be connected to compatible signals; for instance an sc_in<> or an sc_out<> port can be connected to an sc_signal<> however and sc_fifo_in<> or an sc_fifo_out<> port can only be connected to an sc_fifo<> kind of channel. The following code illustrates the use of ports with signals:

// Top level
class top: public sc_module {
public:
sc_signal<bool> sig_1, sig_2;

portsTutorial uut;

top(sc_module_name nm): sc_module(nm), uut(”uut“) {
uut.my_input(sig_1);
uut.my_output(sig_2);
}
};


As can be observed the connection of a port and a signal is a simple operation. Nevertheless this semantics may look surprising since a usual object-oriented message is of the form: object_name.message(parameters) . In this case, uut.my_input(sig_1) is composed of two objects: uut which is the component’s name and my_input which is the port’s name and finally sig_1 is a parameter. In other words we have: object_name.object_name(parameter) but no message call on the object. The reason is a simple one; the creators of SystemC used an overloading trick to make ports/signals connections appear simpler. In fact if you wanted to be a object-orientation purist you could write the following code to the same effect:

top(sc_module_name nm): sc_module(nm), uut(”uut“) {
uut.my_input.bind(sig_1);
uut.my_output.bind(sig_2);
}

The bind() message is effectively what is being used to connect a port to a signal (channel) although in the previous example it was hidden through an overloading trick.
Lastly, there is yet anther way to connect your ports to your signals this is done using positional mapping where the signals are mapped to the ports by position. An example of positional mapping is as follows:

top(sc_module_name nm): sc_module(nm), uut(”uut“) {
uut(sig_1, sig_2);
}

This style is certainly the most succinct way of connecting a component to a set of signals however it is usually seen as a more error prone way since the signals can easily be miss-ordered.

Summary

This tutorial covered the basic uses of ports in a SystemC model. Ports are part of modules and are used to connect modules together via signals (channels). In this tutorial wefocused on the predefined SystemC ports however, most commonly the user creates it’s own port kind defining it’s own set of messages that can be exchanged on those ports. The subject of user defined port we be covered in an other tutorial.

The pdf file and the source files for this tutorial can be found HERE.

David Cabanis.

Advertisements
Categories: SytemC Tutorials
  1. Ashwini
    June 11, 2007 at 11:01 pm

    Can a systemC port have a user defined data type? If yes, can you give an example?

  2. June 18, 2007 at 5:34 pm

    Yes you can have a user defined data type on a SystemC port. For instance :

    struct my_struct { int data; int add; };

    sc_in input_port;

    In this case though, you would have to provide an overloaded version of the = and == operators for this new type to be able to use my_struct with an sc_signal such as:

    sc_signal sig_a;

  3. malex
    March 10, 2008 at 7:39 pm

    yes, such as:

    sc_in packet_rx;

  4. malex
    March 10, 2008 at 7:42 pm

    loool there is a problem with the html tags…

    both I and sclive said that is possible, but giving a wrong readable example.

    you have to use the instead of the ( and the )

    sc_in(my_struct) packet_rx;

  5. lollipop
    February 15, 2009 at 6:22 am

    how to connect one port to another port
    pls give an example

  6. Ndamyimana
    February 28, 2009 at 11:32 am

    Thx from your discussion on user defined data type, I am also doing project related to systemC

  7. Ndamyimana
    February 28, 2009 at 11:36 am

    I got a problem within port bounds in module main.cpp with sc_signal when I use struct my_struct, could u provide some ideal sc_signal sig_a works

  8. Newbee
    March 25, 2009 at 11:06 pm

    How do I parametrize the port using constructors? eg: sc_in<sc_uint > and changing N from constructor..?

  9. Lupus
    March 29, 2009 at 4:17 am

    I am new to systemc. I am trying to model a component that takes N input values, and generate M output values. The N values are coming from distinct sources and the M values are outputs to different sinks. The values of M and N should not be fixed, but specified as inputs for the systemc simulation.
    I was wondering if I can create a module with variable number of ports. In other words, pass the number of ports as a parameter for the module constructor. If not, is anyone aware how can I try to build my component?
    Thank you

  10. hallo
    October 1, 2010 at 8:46 pm

    you can define a maximum limit of ports – say 10, then connect only required ports leaving others hanging ?

  11. September 26, 2012 at 6:25 am

    How can I declare a port of type array of a type struct? and How can I write or read one element of that struct in this case? Thanks…

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: