Hi all,

I agree that the documentation could be better. I think the fundamental
issue that is causing the confusion here is the absence of a notion of an
input and output (computation) phase in gem5. Compared to other
discrete-event simulators/kernels, we do not have a notify and update
phase, and this is where the use of the functions would be disambiguated.
In the update phase we would already be at the clock edge + delta, so any
call to these ³Cycle² functions would round upwards.

The issue above gets even worse when you consider a clock-domain crossing
(CDC), as per Joel¹s implementation. An event from source clock domain
(sendTiming) is causing a direct call of nextCycles in destination clock
domain. This has non-deterministic behavior, much like a real clock domain
crossing. Sometimes it will take 2 (destination) cycles, sometimes it will
take 3. I think you simply need two or three items in a queue, much like a
real CDC. In a previous life I solved this by explicitly modeling the
CDCs, but I¹m not sure we have to go that far.

In terms of what to do, I suggest we start by adding more descriptions
along the lines of what I have written above. However, to really try and
protect the users/developers from themselves I think the separation of
notify/update is needed to actually know what you get. In the current
implementation the ordering of concurrent events with the same priority is
the only thing saving us, and that depends on the instantiation order
(a.f.a.i.k). It would be an interesting exercise to simply implement a
random shuffle of all events that are concurrent and simultaneous and see
what comes out.

Do you guys agree?


Andreas


On 1/8/14, 5:54 AM, "Steve Reinhardt" <[email protected]> wrote:

>It would be interesting to hear from Andreas, since this is his code...
>
>After looking at it a little bit, my opinion is that the code is working,
>but the function names and comment are unclear at best (maybe even a
>little
>confusing).
>
>It seems fairly clear (at least quite reasonable) that
>clockEdge(Cycles(1))
>should return the next clock edge that's at least one cycle in the future,
>which is what it appears to be doing.
>
>It's not clear that that's what nextCycle() ought to be returning, though;
>I agree with Joel that it's intuitive that nextCycle() would return the
>tick at the start of the next cycle, i.e., the next clock edge that's at
>least one tick in the future.
>
>However, if you look at curCycle(), that function returns the tick at the
>start of the "current" cycle, which will be either the current tick (if
>we're on a clock edge) or the next clock edge (if we're between clocks).
> This is the same as clockEdge(0).  So nextCycle() is consistent with
>curCycle() in that it returns the tick of the next clock edge after the
>one
>that curCycle() would return.  (At least that appears to be true to me.)
>
>I think there's a discrepancy between the straightforward English
>interpretation and what's useful.  I'd argue that, when you talk about the
>tick that corresponds to a cycle, you think of the tick at the beginning
>of
>a cycle.  Thus if you're in the middle of a cycle, and you say "when did
>the current cycle start", you actually end up with a tick in the past.
> This is rarely if ever what you want when you're in the middle of your
>code though.  So for practical reasons, curCycle() (which is very heavily
>used, unlike nextCycle(), which is currently only used to schedule the
>next
>tick in the CPU models) really says "give me the current cycle, if we're
>already on a clock edge, else give me the next cycle", which may be useful
>but doesn't really match the name very well.
>
>Actually it's clear that curCycle() and nextCycle() do the right thing if
>you're already on a clock edge.  I wonder how often they are used when
>this
>is not the case?  In some ideal fantasy world, it might be nice to have
>curCycle() and nextCycle() assert that you are on a clock edge (forcing
>you
>to use those functions in event handlers that get processed only on clock
>edges), and require programmers to use clockEdge() explicitly in functions
>that might be called between edges.
>
>Steve
>
>
>
>On Tue, Jan 7, 2014 at 5:06 PM, Nilay Vaish <[email protected]> wrote:
>
>> I am trying to make a connection with how the buffer would have operated
>> when a digital circuit is designed.  Suppose the sender raised the
>>message
>> lines at t = 0.5.  Then, the receiver's buffer would latch the message
>>at t
>> = 1.  The receiver should be able to process this message starting t =
>>1 +
>> delta.  In our discrete simulator, we schedule the processing event at
>>time
>> t = 2 and in one instant do all the work that was to be done in the
>>clock
>> cycle.
>>
>> I agree with Ali and I think the function is working as expected.
>>
>> --
>> Nilay
>>
>>
>>
>> On Tue, 7 Jan 2014, Ali Saidi wrote:
>>
>>
>>>
>>> Hi Joel,
>>>
>>> I think you're right that it's not quite as intended. I believe the
>>> semantics are supposed to be:
>>>
>>> clockEdge() returns the next clock edge and can be the current clock
>>> edge
>>>
>>> and nextCycle() returns the next clock edge and can't be the current
>>> one.
>>>
>>> Right now if nextCycle is called in the middle of a cycle its returns
>>> the tick 1.5 cycles away.
>>>
>>> However, as I'm writing this I have a feeling that was the desired
>>> behavior of at least part of the memory system where the idea was if
>>>you
>>> didn't have the input at the beginning of a cycle you shouldn't be able
>>> to act on it until the next one.
>>>
>>> Anyone else have an opinion?
>>>
>>> Ali
>>>
>>> On 07.01.2014 12:58, Joel Hestness wrote:
>>>
>>>  Hey Nilay,
>>>> This is in my own code. Below is the pseudo-code for the way the
>>>>buffer
>>>> operates. It's in the receiver's clock domain, and a request can
>>>>arrive
>>>> at
>>>> any point during a cycle, because the sender's clock may be
>>>> different/out-of-phase. When a packet arrives off a receiver's clock
>>>> edge,
>>>> nextCycle() returns the clock edge that would be 2 cycles hence, even
>>>> though the buffer could be operated on at the next clock edge.
>>>>
>>>> bool recvTimingReq(packet) {
>>>> if buffer not occupied:
>>>> // push packet into buffer (size 1)
>>>> // schedule event to handle buffered packet in next cycle (using
>>>> nextCycle())
>>>> return true;
>>>> else:
>>>> return false;
>>>> }
>>>>
>>>> Thanks,
>>>> Joel
>>>>
>>>> On Tue, Jan 7, 2014 at 12:17 PM, Nilay Vaish <[email protected]>
>>>>wrote:
>>>> On Mon, 6 Jan 2014, Joel Hestness wrote: Hey crew, I'm running into
>>>>some
>>>> confusion about the semantics of the nextCycle() function in clocked
>>>> objects. In particular, it seems as though this function can return
>>>>more
>>>> than one cycle in the future: Take as an example a buffer that is to
>>>>accept
>>>> input for a receiving component. It is possible that the buffer
>>>>receives an
>>>> input signal during the middle of one of the receiver's cycles (i.e.
>>>>not on
>>>> a receiver's clock edge). In this case, the receiver's nextCycle()
>>>>function
>>>> calls clockEdge(Cycles(1)). clockEdge(), in turn, calls update(),
>>>>which
>>>> will increment the receiver's tick to be the tick of the next clock
>>>>edge
>>>> ahead of curTick(). At this point, when clockEdge(Cycles(1)) continues
>>>> executing, it adds yet another full cycle to the receiver's next clock
>>>> edge, and that is what is returned from nextCycle(). Because of this,
>>>>the
>>>> buffer I've put together using nextCycle() can only accept 1 input
>>>>every
>>>> other cycle when the sender and r!
>>>>
>>> ec
>>
>>> eiver
>>> clocks are out of phase. Is this intended functionality of
>>>nextCycle()? I
>>> need a clarification before I start getting into a discussion here. Is
>>>this
>>> behavior being observed in some existing code? From your description,
>>>it
>>> seems you have made some modifications. -- Nilay
>>> _______________________________________________ gem5-dev mailing list
>>> [email protected] http://m5sim.org/mailman/listinfo/gem5-dev [1]
>>>
>>>
>>>
>>> Links:
>>> ------
>>> [1] http://m5sim.org/mailman/listinfo/gem5-dev
>>> _______________________________________________
>>> gem5-dev mailing list
>>> [email protected]
>>> http://m5sim.org/mailman/listinfo/gem5-dev
>>>
>>>  _______________________________________________
>> gem5-dev mailing list
>> [email protected]
>> http://m5sim.org/mailman/listinfo/gem5-dev
>>
>_______________________________________________
>gem5-dev mailing list
>[email protected]
>http://m5sim.org/mailman/listinfo/gem5-dev
>


-- IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium.  Thank you.

ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered 
in England & Wales, Company No:  2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, 
Registered in England & Wales, Company No:  2548782

_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to