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
> 
> 

Reply via email to