Hi Lu,
lu peng wrote:
>
>>
>> Your question about reading data member of the class of
>> SimicsTracerImpl: you can't/shouldn't directly, but rather use the
>> port mechanism as explained above to get data to the cache. If you
>> have some new data field or information you need to pass, add it to
>> the instruction object so it goes through the port.
>>
> For each instruction or each memory operation, you created an instance
> of the object ArchitecturalInstruction. I have some new data fields in
> SimicsTracerImpl. So did you mean that I should add some related fields
> in this class and pass them to the Cache System? If so, more
> specifically, in which function & file does the cache system will 'pull'
> them out? I found many available() calls in the component/Cache
> directory. It looks that they called some functions such as
> FLEXUS_CHANNEL(TopOutI).available(). There are many MemoryPort instances
> such as BottomOut,TopOutI,TopOutD, etc.
>
From the cache, you can't really access members of SimicsTracerImpl, so
I would advise against adding fields to that class that you need to
access elsewhere. Components in Flexus communicate with Transports over
Channels, as you may have noticed. So you need to get your fields into
a transport. Here's an example of how to add the integer 'foo' to the
instruction object and read it from the cache. I'm assuming you're using
a simulator such as CMPFlex.
1. Add 'foo' to the ArchitecturalInstruction 'slice'. A slice is one
piece of data in a transport. Open
components/Common/Slices/ArchitecturalInstruction.hpp and add the
appropriate declaration for 'foo', as well as a method to get and set
the value of foo (see how we handle thePhysicalAddress for an example).
2. Call setFoo where appropriate, e.g. in real_hier_operate in
SimicsTracer.hpp. For example, this could look like:
theConsumer->optimizedGetInstruction().setFoo(10);
would set foo for the current instruction to 10. This gets 'foo' into
the transport, which in CMPFlex, goes
theFeeder->theFetch->theBPWarm->theExecute->theL1d
so there's quite a ways to go between theFeeder (where we just added
'foo') to the cache (theL1d). We can also look at the connections
between these components as a function of transports. From theFeeder
down to theExecute, the arrows in the above diagram are really
InstructionTransports. The Execute component translates the
instructions into memory requests that go to the cache.
3. At this point, we need to add 'foo' to the MemoryMessage slice, just
like we did in step 1 above. components/Common/Slices/MemoryMessage.hpp
4. In components/Execute/ExecuteImpl.cpp, find issueMemoryOperation().
This function translates the instruction object into a memory message
and sends it out the request channel. Add a line similar to
operation->setFoo(anInstructionState->instruction().getFoo());
5. Now (finally) we can read foo in the cache. In
components/Cache/CacheImpl.cpp, look for a line similar to:
void push( interface::FrontSideIn_Request const &, MemoryTransport &
aMessage) {
This is the start of the function that accepts a new memory request.
Within this function, you have access to foo:
aMessage[MemoryMessageTag]->getFoo()
At this point, I don't know what you want to do in the cache. But this
is how to get a value from the feeder to the cache.
I hope this helps,
Brian
> In a word, if I modify a field in SimicsTracerImpl for an instruction or
> a memory operation, in which file & function of the Cache system can
> know this?
>
> Thanks in advance,
> Lu
>
>