I would like to describe services as components with their ports and interfaces. It should become clear by the description, what functionalities are provided, and how to utilize them.
In my understanding, I can type a port either with this notation <name>:<type>, where the type can be specified by an interface block? Or using the "lollipop", where the interface type is specified by the name of the "lollipop"?
Now, I would like to see what application or transportation protocol is utilized by a interface/port, to get an idea on how to connect to it. But I don't know what is the best way to do so. I thought about two ways.
First: specifying the protocol (here TCP/IP) by the port type and the interface (provided information) by the "lollipop" notation.
Second: specifying a transportation/application protocol as the base interface of an application specific interface.
I really don't know if any of that makes sense or if there is a better way to describe that. Please let me know.
EDIT:
Based on the answer of qwerty_so, I understand that the generalization of an interface from a protocol is wrong. But to indicate the utilized protocol, it should be specified by the port type? Based on that, I made another representation of two components (this time in UML, i hope it doesn't cause any confusion). Each component provides the same interface through a varied port. Basically it is the same as the first notation, extendet by the realize relation from the lollipop to the interface. The first component utilizes a basic TCP/IP and the second a gRPC protocol in order to realize the Interface1.
two components with different port types and same interface
Is that a more accurate way to represent the interface and its realization by a specific protocol?
Is the realize relation necessary, because shouldn't it be clear by the interface name?
TCP/IP is a protocol. And that's what is used for the port. Draw a realize relation from the port towards the interface.
The interface1 is the software interface. So draw a realize relation from the lollipop towards that.
Your lowest design would be wrong since interface and protocol are two very different things.
I always think of a port a a plug bundling a number of (SW) interfaces. In SysML terms it also extends to power supply as interface (which for pure soft-workers is kind of strange ;-).
Related
I have experienced some back-end issues using systemverilog interfaces when and interface is traversing over hierarchical boundaries. I've tried to sketch the situation in the attached drawing.
The top picture shows the "regular" method of using interfaces. the interface and connected module are all instantiated at the same level of hierarchy. This works for simulation and back-end.
The middle picture shows my situation. At the toplevel I have a module and interface instantiation. The interface is connected to the purple module and then connected to 2 sub-modules. In simulation this works.
Then the synthesis tool complains that the interface at the purple level should be an modport. So I added that. However the synthesis tool is interpreting the wires in the as bidirectional and adds logic to facilitate this. In my design all wires are unidirectional.
The only workaround I could find to fix this issue is depicted in the lower picture. I connect via a modport the original interface (labeled A). Then I instantiate a new interface (labeled B) which has the same parent as interface A. Both interfaces A and B are connected to a connect module which contains a lot of statements like:
assign interfaceB.rx1 = interfaceA.rx1;
assign interfaceB.rx2 = interfaceA.rx2;
assign interfaceA.statusX = interfaceB.statusX;
etc
so it is just a "dumb" connection of interface A and B.
This way of work feels very wrong as this connect module is creating a lot of overhead. Is there a good / easier way of using the interface over hierarchical boundaries that is not only working in simulations but also works for synthesis?
Thanks
Hierarchical composition is definitely a shortcoming of SystemVerilog interfaces.
You can simplify your solution by creating InterfaceB with a port list and making connections to the individual signals from the InterfaceA port. That eliminates the connect module.
interface InterfaceB( input rx1, rx2, output ...)'
modport .../ same as what you have
endinterface
SystemVerilog interfaces have really simplified my FPGA designs. They allow me to route many signals to multiple blocks in logical groupings. I really like them. I use them with modports to indicate the in/out directions. In the two books I've read on SystemVerilog, interfaces are introduced and the syntax is shown before modports. At the end of the chapter/section, modports are introduced as a helpful way to use interfaces. As far as I can tell, I would never use an interface if the concept of a modport did not exist. So, this brings me to my question...
Are there usage cases for interfaces that make sense without using modports?
The usage case could be in implementation/synthesis or in verification/simulation. I'm mostly curious to learn something new here about interfaces. I looked for related questions but didn't see any.
modports are intended for tools (like synthesis) that compile a design with boundaries that require direction information. If you flatten out the hierarchy with an embedded interface, there's no need for directions. Simulation tools almost always do this, so interfaces used just for verification do not need modports.
Some people put modports in interfaces for verification as a way of restricting access to certain signals, but unfortunately, many simulation tools do not enforce the direction, especially when used with a virtual interface.
Since I have not yet completely understood the correct usage of port and interface symbols in component diagrams, a few questions:
I.
Imagine a piece of software which wants to use a very special remote logger service over network (TCP). The messages may be some XML. So the logger exposes an interface which specifies things like handshake, XML structure, XML elements etc. so that the logger will accept a message.
a) Am I right that this interface may be called "ILoggerProtocol", the port may be named after the service it provides ("logging")?
b) So the component in my application implements that interface so that it generates a compliant message for the server?
c) Now an interesting thing: for the communication, there is an additional library "Networking" which provides simple TCP stuff, so it does the TCP connect, sends messages, handles errors etc. Do I need this class when I only want to emphasise the way from the generated messages to the server? Is then MY port the TCP interface?
d) And when I want to draw the complete picture, how can I add the Networking component to the diagram correctly, pointing out that ILoggerProtocol is used AND that it goes over TCP through the Networking component?
II. Ports inside my application: now there are two libraries where one just uses the other; basically, in C/C++, it would #include the other's header file:
e) Is that the correct diagram?
f) Do I need ports here? If yes, what would they actually represent in reality? What names would you give them?
g) Or are the lollipops just sufficient without the port symbols?
III. concerning lollipops:
h) are those two notations basically the same and interchangeable? I have found the name "assembly" for the combined version, so maybe there is a difference...
A short answer first (trying to rip up the rest later): a port is an embedded element which allows to group a number of interfaces. The best I can come up for an example is a complex socket (the port) which bundles things like power supply, communication lines, you name it (the interfaces).
Now for the details.
a) Yes, that's correct. You would usually use a <<delegate>> stereotyped association to show that the outer interface is used(/realized if it's a lollipop) somewhere inside.
b) No. This is a required interface. It is used inside but implemented outside (where the lollipop resides).
c&d) I'd use a <<use>> from MyApplication towards Networking to show that. Normally you would not go into too much detail (unless it is essential). Obvious things like TCP are clearly pictured with the <<use>>
e) You can(/should) use <<include>> or <<use>> instead.
f&g) see the general answer above
h) Yes. The first is a flexible notation of the second.
P.S. Just looking over this once again and I notice that in the top picture the inner directed association should be pointing the other direction and be stereotyped <<delegate>>.
Since WinRT exposes both the IStorageFolder interface and the StorageFolder class, my reflex was to use the interface throughout my code. I reasoned that IStorageFolder could be used as an abstraction to support non-filesystem folders like those in compressed archives. However, looking at the IStorageFolder interface, every method is declared to return concrete StorageFolder instances. As such, it would not be possible to implement a virtual filesystem based on this interface.
So how is IStorageFolder a useful abstraction? Or does its existence have a technical justification?
It is an interface because there are two implementations of IStorageFolder: One is StorageFolder, and another is FolderInformation. Since there are two implementations, the common behavior uses an interface so that you can write a function that operates on either StorageFolder or FolderInformation.
I am pretty aware of the benefits of interfaces and how it helps aggregate common functionality of similar types of objects. However I believe people have taken this 'always program to an interface' a bit too far.
a) People starting off by ALWAYS defining an interface and then implementing it in a class even if that interface is too specific to be implemented by any other class. - Am I the only one who thinks that this serves no useful purpose?
b) Forcing all 'related' interfaces to derive for a common (useless) interface because it is now 'extendable' - What?
c) What do you do in scenarios where two or more objects seem related but it is very difficult to define common interface methods because of its underlying differences?
Lets say for example, an interface named IConnection with a Connect() method. (this is how most examples trivialize interfaces). The problem is, different type of classes that implement the IConnection interface might require different data for establishing the connection, some might require a user name and password, some might require some kind of special connection key, some might require nothing at all. The Connect method as a contract is perfectly valid as each class will need some way of establishing a connection but the data they need is different.
Is an interface required in this case? If it is, how do you define the Connect method? If not, how do you prove that your concrete classes are still 'extendable'?
Sorry for the long rant, this has been bugging me for quite some time now. Most people after reading the famous design patterns book try to implement every possible pattern in everything they do without bothering to figure out whether it helps. I believe the pattern should be brought into play when you are faced with a problem not just for the heck of it.
In your IConnection example you're basically describing an abstract Connect() method, since each class will have to implement its own version. Usually (always?) abstract methods can only be defined with the same parameters, so Connect(username, password) and Connect(key) couldn't be implementations of the same Connect() method from an interface.
Now, at this point, you could define it as IConnection::Connect(SomeConnectionData) and derive UsernamePasswordConnectionData and KeyConnectionData, etc., etc. from that SomeConnectionData class but all this would be so hard to explain and implement that its pretty good clue that interfaces and inheritance aren't helping the situation.
If it makes programming it and using it harder, don't do it. If something is made "extendable" by becoming too complex to understand, no will extend it anyway. It's perfectly okay to define a bunch of classes, each with their own Connect() methods just as a convention.