Hi folks, especially the folks who wrote the TLM/gem5 bridge in util/tlm. As I'm sure most of you are aware, I added an implementation of the systemc API/kernel in gem5. While it's now possible to instantiate systemc objects in a gem5 config and hand around pointers to them using config parameters, there isn't a way to hook those objects to gem5's memory system like native objects which have gem5 ports.
TLM is a pretty big ball of stuff, and given the existing implementation and my interest in not breaking that or creating something slightly incompatible and/or confusing, I want to dump my thoughts so far and get some feedback and even ideally assistance from some folks who know these areas better than I do. Connecting ports in gem5's configs: At the topmost level, the port binding mechanism calls a python function ccConnect on PortRef objects, the things which represent gem5 ports in gem5's python configuration files. That function does some sanity checks, and ultimately calls connectPorts which is a function exposed from C++. The C++ implementation of connectPorts is in src/python/pybind11/pyobject.cc, where it takes two sets of parameters, a SimObject, name, and index for each side of the connection being made. This file used to have a bunch of conditional compilation in it, but you may remember some changes I made recently which got rid of that. Looking at the body of this function, the first thing it does is to use dynamic_cast to try to cast these SimObject pointers in to ethernet related objects. If that's successful, then the assumption is that these objects are really connecting together an Ethernet network, rather than the memory interconnect network within a system. If so, then the lookupEthPort function is called which extracts the appropriate interfaces, and those are stuck together. If that doesn't work, then the function moves on to check to see if the SimObjects are MessageBuffers from Ruby. If so, then nothing happens since apparently that's handled somewhere else(?). Then finally if even that doesn't work, gem5 checks if the SimObjects are MemObjects. If so, then they have their ports extracted with the getMasterPort and getSlavePort functions which return port objects, and then those are glued together. Possible changes: It seems slightly dubious to me that these are all hanging off the same port interface, but lets set that aside for now. What we have are really three different mechanisms which are all serially in the same function, and that function checks them one at a time to figure out which one applies. This has at least two deficiencies. First, this function has a lot of unrelated stuff in it depending on what flavor of binding it's doing. On average, two thirds of the function is dead weight for any particular invocation. Second, if we wanted to add a new type of binding, for instance between a systemc object and a gem5 object or vice versa, then we'd have to modify this common and fairly core file to build that in from the ground up. I did a little research, and my understanding is that pybind11 will let you polymorphically bind C++ functions to a single python function name. At call time, it will check each one one at a time until it finds one that works, and then will call that. By making connectPorts three different functions which take pointers of the desired types and then binding all of them to the connectPorts name in python, we make pybind11 the arbiter and central collection point, rather than the hard coded body of this C++ function. Connecting systemc and gem5 objects: I'm thinking there are two different ways to do this. The first would be to make a systemc interface type which is the same as or inherits from the gem5 port interface. The systemc module/model would need to speak the gem5 protocol directly, and this wouldn't be very easy to use when passing through packets (or whatever TLM calls them) which were generated by a module which didn't buy into using gem5's memory system protocol natively. Looking at the code in util/tlm, I don't 100% understand what's going on there (although the examples are great, thank you for those), but it looks like you've already done something at least sort of like this. Is any of that applicable here? The second way would be to slightly repackage the bridge in util/tlm so that it was more of a single entity in the gem5 config with two sides, a gem5 side and a TLM side. This is a little different from how it looks like it works in the examples since it's (by necessity) split into two halves which live on either side of the gem5/systemc dividing line. I understand this less, although I'll keep looking at it to try to grok all the moving pieces. I haven't really learned much about TLM so that may be a limiting factor in learning how this works. This seems like a more robust solution and would leverage the work that's already been done, but I'm not sure how much work it would be or if there would be significant gotchas involved somewhere. Thoughts/feedback would be greatly appreciated! Thanks! Gabe _______________________________________________ gem5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/gem5-dev
