[ibis-macro] Re: BIRD-190, even time domain flow requires the IR input to downstream Rx2 AMI_Init to have the full IR including the upstream channel IR

  • From: "Bob Miller" <dmarc-noreply@xxxxxxxxxxxxx> (Redacted sender "bob.miller" for DMARC)
  • To: Walter Katz <wkatz@xxxxxxxxxx>
  • Date: Tue, 11 Jul 2017 14:36:27 -0600

To add a bit more elaboration: the directive:

"For this reason, the parameters of the Rx AMI_Init function should always
default to valid values or have a mechanism to accept user-defined
coefficients and allow the user to turn off any automatic optimization
routines to ensure successful simulations."

represents a nearly useless manual optimization bone thrown to the end
user, who will not generally be able to manually adapt the terminal Rx (at
least one of ours) to the channel successfully. Furthermore, the "valid
values" prescribed here cannot hope to open the eye on a difficult channel.
There simply is no single setting of Rx taps (out of the millions possible)
which will do this on every (read: more than a lucky few") channels.

to wit: "successful simulations" are *far *from "ensured".

Regards,

Bob

On Tue, Jul 11, 2017 at 2:22 PM, Walter Katz <wkatz@xxxxxxxxxx> wrote:

All,



I sent this out to IBIS-ATM on June 19. There are RX models today that
require the full IR in order to setup the equalization for AMI_GetWave.
This was contemplated and discuss in June 1010, and I have included some
e-mails from back then.



So not including the upstream equalization in the downstream Rx2 IR gives
the wrong result in both statistical and time domain simulation.



BIRD 190 says:



Note: The Rx2 executable model file writer for the downstream channels
with Redrivers should keep in mind that the impulse response that is
presented to the Rx AMI_Init function does not include the effects of the
upstream equalization.  Therefore, the Rx AMI_Init function will not be
able to perform accurate optimization in the absence of the upstream
channel characteristics and/or equalization effects.  For this reason, the
parameters of the Rx AMI_Init function should always default to valid
values or have a mechanism to accept user-defined coefficients and allow
the user to turn off any automatic optimization routines to ensure
successful simulations.

IBIS already says on page 178 (redundant with the lines in blue):



Note: The Rx executable model file writer should keep in mind that it is
not guaranteed that the impulse response that is presented to the Rx
AMI_Init function will always include the effects of the Tx filter.
Therefore the Rx AMI_Init function may not be able to perform accurate
optimization under all circumstances.  For this reason, the parameters of
the Rx AMI_Init function should always default to valid values or have a
mechanism to accept user-defined coefficients and allow the user to turn
off any automatic optimization routines to ensure successful simulations.



And the lines in red re-affirm the fact that the Redriver flow is in error
and gives the wrong result.



Walter



Walter Katz

wkatz@xxxxxxxxxx

Phone 303.449-2308 <(303)%20449-2308>

Mobile 303.335-6156 <(303)%20335-6156>

*From:* Walter Katz [mailto:wkatz@xxxxxxxxxx]
*Sent:* Monday, June 19, 2017 9:28 PM
*To:* Arpad_Muranyi@xxxxxxxxxx; ibis-macro@xxxxxxxxxxxxx
*Subject:* RE: [ibis-macro] Re: Response to BIRD-190



Arpad,



There are a large number of e-mails relating to optimization and IBIS
models. I pulled out the following quote from this e-mail from you to me on
12/1/2010



   1. However, let’s consider an example when the Init function contains

an optimizer which takes initial values for the tap coefficients

and after some number crunching returns better coefficients.



I would think that in this case the tap coefficients will be

declared as InOut arguments, and the initial values given to the

Init function will be overwritten by the Init function when the

optimizer is done.  Now, how is this result propagated to the

GetWave function?  Notice that the GetWave function doesn’t have an

AMI_parameters_in argument.  This makes me think that the

AMI_parameters_in argument of the Init function is also visible to

the GetWave function, and the modified tap coefficients from the

Init function are passed to GetWave through the AMI_parameters_in

memory location.  This implies that the return value of an InOut

argument should be returned in place (which is #1 above).  Using

this thinking we won’t need the AMI_parameters_out argument for

returning the values of InOut arguments.



This describes exactly how Bob Miller’s models work, and it is in words
you wrote.



There are tons of references to this in many e-mails. It is clear that the
original intent of IBIS AMI models were to enable the AMI_Init, the
AMI_Getwave and both combined to optimize tap coefficients.



I am also included a random relevant e-mail from 2009 from Kumar.



There are literally hundreds of e-mails between 2007 and today talking
about various methods of optimization. It is very interesting to see some
of these discussions in retrospect.



Walter







Walter Katz

wkatz@xxxxxxxxxx

Phone 303.449-2308 <(303)%20449-2308>

Mobile 303.335-6156 <(303)%20335-6156>

*From:* ibis-macro-bounce@xxxxxxxxxxxxx [mailto:ibis-macro-bounce@
freelists.org <ibis-macro-bounce@xxxxxxxxxxxxx>] *On Behalf Of *Muranyi,
Arpad
*Sent:* Monday, June 19, 2017 8:18 PM
*To:* ibis-macro@xxxxxxxxxxxxx
*Subject:* [ibis-macro] Re: Response to BIRD-190



Aren’t those Model_Specific parameters?  If so, no one else but

the model maker knows what they mean or can be used for…



Thanks,



Arpad

==================================================



*From:* Walter Katz [mailto:wkatz@xxxxxxxxxx ;<wkatz@xxxxxxxxxx>]
*Sent:* Monday, June 19, 2017 7:01 PM
*To:* ibis-macro@xxxxxxxxxxxxx; Muranyi, Arpad <Arpad_Muranyi@xxxxxxxxxx>
*Subject:* Re: [ibis-macro] Re: Response to BIRD-190



Why would an initial function return tap coeficients based on the input ir?

Get Outlook for Android <https://aka.ms/ghei36>




---------- Forwarded message ----------
From: "Muranyi, Arpad" <Arpad_Muranyi@xxxxxxxxxx>
To: <ibis-macro@xxxxxxxxxxxxx>
Cc:
Bcc:
Date: Wed, 1 Dec 2010 20:47:37 -0400
Subject: [ibis-macro] About the Typos BIRD comments from Fangyi

Walter,



(I changed the subject line so we know what this thread is all about).



Thanks for your comment, I agree partially, but not completely.

You say “…if it has one of the following leaves…”, which doesn’t

make sense to me.  We can’t have Usage or Type alone.  What did

you refer to by “one of”?  The bottom part of the list under

“Allowed-Value Method” or the whole list?  Even with considering

the bottom part of the list, this interpretation is flawed because

under certain circumstances Default and Value are mutually exclusive.



On the other hand, I like the sentence “A branch that is an AMI

parameter may not contain a branch.”  I think we should use that

in the BIRD.



How about if the Typos BIRD would say the following:



|*              A branch in the .ami file is an "AMI Parameter" if it

|*              contains the leaves Type, Usage, and any of the following

|*              leaves:

|*

|*                   Default

|*                   <data_format> or Format <data_format>

|*

|*              and does not contain another branch.



Note that I left out the word “only” Fangyi suggested, but added

the words in red at the end.





To address comment #3 from Fangyi, I added a few words to the end of the

paragraph on the top of pg. 5 of the BIRD draft shown in red:



|*              The tree data structure passed in and out of the DLL

|*              described in section 3.1.2.6 of Section 10 of this document

|*              is similar to the tree data structure in the .ami file
except

|*              the 'Reserved_Parameters' and 'Model_Specific' branches are

|*              not included, the "AMI Parameter" branches become leaves
and

|*              the “AMI parameters” of Usage Info and Out are not
included.





This actually raises a few more questions in my mind, especially

with the other email thread I started not too long ago about the

AMI_parameters_out argument in mind.



I can’t find anything in the specification that describes how the

DLL returns an Out or InOut parameters and how the EDA tool is supposed

to look for them.  Here are the possibilities that come to my mind.

Let’s start with an InOut example first to make my question easier to

understand.



The AMI_parameters_in argument is a pointer to a string, and the

content of the string contains the InOut parameter name with a value.

The DLL reads this value, and after some number crunching decides to

return a different value.  Where should this output value go?



1)  The DLL could overwrite the string that it was given by the

EDA tool in the same memory location.  Recall, the argument

is a pointer to the string, and it could be processed “in

place”, just as we do with the impulse matrix.



2)  On the other hand, we have another argument for AMI_parameters_out.

Is this where the DLL is supposed to put the output value it

generated?  If so, I would imagine that the DLL has to make a

copy of the AMI_parameter (leaf value) string with the new value

in the value location and put it in the memory location of

AMI_parameters_out.



3)  However, let’s consider an example when the Init function contains

an optimizer which takes initial values for the tap coefficients

and after some number crunching returns better coefficients.



I would think that in this case the tap coefficients will be

declared as InOut arguments, and the initial values given to the

Init function will be overwritten by the Init function when the

optimizer is done.  Now, how is this result propagated to the

GetWave function?  Notice that the GetWave function doesn’t have an

AMI_parameters_in argument.  This makes me think that the

AMI_parameters_in argument of the Init function is also visible to

the GetWave function, and the modified tap coefficients from the

Init function are passed to GetWave through the AMI_parameters_in

memory location.  This implies that the return value of an InOut

argument should be returned in place (which is #1 above).  Using

this thinking we won’t need the AMI_parameters_out argument for

returning the values of InOut arguments.



4)  Now let’s put another twist to this story and consider an Out

argument.  Is the parameter string supposed to contain the name

of the AMI parameter name and a place holder for the return value

so that the Init function can modify this string in place when it

outputs the value?



Or, is the parameter string not supposed to include the name of

the Out argument, and is the Init function supposed to modify this

string in place and add that AMI parameter to it?



Or, is the Init function supposed to use the AMI_parameters_out

argument for returning Out parameters?



5)  Studying the spec I also noticed that the AMI_parameters_out argument

is optional for GetWave, but for Init we don’t say that it is

optional, so I assume it is required (correct me if I overlooked

something).  Shouldn’t the AMI_parameters_out be consistently

optional or required for both Init and GetWave?



Depending on the answers above, if the output should be placed in

the AMI_parameters_out argument, we can’t say that it is optional,

at least not if the input parameter string includes Out or InOut

parameters.



Sorry for the lengthy discussion here.  I almost feel like I may not

see the tree from the forest here, and if that is true, please correct

my “observations” above.  On the other hand, I the tree is indeed not

visible in our “spec forest”, I think we need to do a little more cleaning.





Thanks,



Arpad

==========================================================================



*From:* Walter Katz [mailto:wkatz@xxxxxxxxxx]
*Sent:* Wednesday, December 01, 2010 2:42 PM
*To:* fangyi_rao@xxxxxxxxxxx; Muranyi, Arpad; ibis-macro@xxxxxxxxxxxxx
*Subject:* RE: [ibis-macro] Re: IBIS-ATM teleconference - Agenda for
11/30/2010



My definition of a parameter is:



A parameter tree contains a root, branches and leaves. A branch of the
parameter tree is an AMI Parameter, if it has one of the following leaves.
A branch that is an AMI parameter may not contain a branch.

Usage

Type

Default

Allowed-Value Method

Value

List

Range

Increment

Corner

Steps



Walter



*From:* ibis-macro-bounce@xxxxxxxxxxxxx [mailto:ibis-macro-bounce@
freelists.org] *On Behalf Of *fangyi_rao@xxxxxxxxxxx
*Sent:* Tuesday, November 30, 2010 2:53 PM
*To:* Arpad_Muranyi@xxxxxxxxxx; ibis-macro@xxxxxxxxxxxxx
*Subject:* [ibis-macro] Re: IBIS-ATM teleconference - Agenda for
11/30/2010



Hi, Arpad;



I have following questions regarding the Typo BIRD.



1.       On page 2, shall we merge the two modifications on line 140 into
one?



2.       At the bottom of page 4, shall we say “A branch in the .ami file
is an “AMI Parameter” if it only contains the leaves Type, Usage, and any
of the following leaves”? Shall we explicitly state that a branch having
Usage and/or Type and a sub-branch is illegal?



3.       The first paragraph on page 5 seems to suggest that parameters
of Usage Info and Out are also passed into the DLL by the parameter string
for AMI Init.



Thanks,

Fangyi




---------- Forwarded message ----------
From: "C. Kumar" <kumarchi@xxxxxxxxx>
To: <wkatz@xxxxxxxxxx>, <ibis-macro@xxxxxxxxxxxxx>, <
fangyi_rao@xxxxxxxxxxx>
Cc:
Bcc:
Date: Mon, 12 Oct 2009 22:36:15 -0400
Subject: RE: [ibis-macro] Re: An AMI Overview
fangyi:
i agree the  case of tx with getwave and rx just with init is problematic.
the tx has getwave because the init alone cannot provide equalization
information. but rx init is not very useful without tx equalization
factored in

in this case the minimum rx init can do is to just allow the user/eda tool
supply the coefficients

--- On *Mon, 10/12/09, fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>
<fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>>* wrote:


From: fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>
Subject: RE: [ibis-macro] Re: An AMI Overview
To: kumarchi@xxxxxxxxx, wkatz@xxxxxxxxxx, ibis-macro@xxxxxxxxxxxxx
Date: Monday, October 12, 2009, 10:15 PM

Hi, Kumar;



As Walter pointed out Rx Init does need a modified impulse from Tx to
prepare GetWave or to optimize taps for optimal performance. The problem of
all these confusion and broken flows is that AMI is letting the Init
function provide multiple functionalities including



Prepare for GetWave or optimize taps

Return approximate LTI model for statistical simulation

Return Tx/Rx EQ information



It is too much to put in one single function.



Fangyi



*From:* C. Kumar [mailto:kumarchi@xxxxxxxxx]
*Sent:* Monday, October 12, 2009 6:54 PM
*To:* wkatz@xxxxxxxxxx; ibis-macro@xxxxxxxxxxxxx; RAO,FANGYI (A-USA,ex1)
*Subject:* Re: [ibis-macro] Re: An AMI Overview



instead of knotting up all over the place, we have to simplify the flow

i.e if a model has getwave , it cannot modify the impulse response

if the vendor wants to provide approximate models he has to provide
separate models containing just init,

any other method of prescribing both getwave and init will need to
confusion and broken models/flows

--- On *Mon, 10/12/09, fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>
<fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>>* wrote:


From: fangyi_rao@xxxxxxxxxxx <fangyi_rao@xxxxxxxxxxx>
Subject: [ibis-macro] Re: An AMI Overview
To: wkatz@xxxxxxxxxx, ibis-macro@xxxxxxxxxxxxx
Date: Monday, October 12, 2009, 8:34 PM

Hi, Walter;



You may not notice in my example the Rx Init returns h_AC*h_TEI + h_REI
instead of h_AC*h_TEI*h_REI. In this case the Tx portion can’t be removed
from the final impulse by deconvolution. We can’t recover h_REI by
deconvolution either. The flow will be broken if Tx has GetWave but Rx does
not.



Thanks,

Fangyi





*From:* Walter Katz [mailto:wkatz@xxxxxxxxxx]
*Sent:* Monday, October 12, 2009 4:39 PM
*To:* RAO,FANGYI (A-USA,ex1); ibis-macro@xxxxxxxxxxxxx
*Subject:* RE: [ibis-macro] Re: An AMI Overview



Fangyi,



By deconvolution ( *http://en.wikipedia.org/wiki/Deconvolution*
<http://en.wikipedia.org/wiki/Deconvolution> ).



The input to Rx Init is h_AC*h_TEI, the output of Rx Init is
h_AC*h_TEI*h_REI. Deconvolution takes the Fourier Transform of the input
and output impulse responses, then divides the coefficients of the two
Fourier Transforms, and then does an inverse Fourier Transform to get
h_REI. We do this for this flow because we have no other choice. That is
why I am proposing to add to Rx Init models the ability to just return
h_REI.



Walter



Walter Katz

303.449-2308 <(303)%20449-2308>

Mobile 720.333-1107 <(720)%20333-1107>

wkatz@xxxxxxxxxx

www.sisoft.com



-----Original Message-----
*From:* fangyi_rao@xxxxxxxxxxx [mailto:fangyi_rao@xxxxxxxxxxx]
*Sent:* Monday, October 12, 2009 6:55 PM
*To:* wkatz@xxxxxxxxxx; ibis-macro@xxxxxxxxxxxxx
*Subject:* RE: [ibis-macro] Re: An AMI Overview



Hi, Walter;



Thanks for your explanation. Regarding point 2, I still think if model
vendors are allowed to modify impulse any way they want, then following
scenario will be broken.



Tx has GetWave.

Tx Init modifies h_AC and returns h_AC_Tx=h_AC*h_TEI

Rx does NOT have GetWave.

h_AC_Tx is passed into Rx Init.

Rx Init modified h_AC_Tx and returns h_AC_Tx_Rx= h_AC*h_TEI + h_REI

Tx GetWave output is to be convolved with h_AC_Rx=h_AC + h_REI, which is
the combined impulse of channel and Rx.



Without knowing how Rx Init modifies the impulse, how can EDA tools remove
the h_TEI portion from h_AC_Tx_Rx to get h_AC_Rx?



Thanks,

Fangyi







*From:* Walter Katz [mailto:wkatz@xxxxxxxxxx]
*Sent:* Monday, October 12, 2009 3:04 AM
*To:* RAO,FANGYI (A-USA,ex1); ibis-macro@xxxxxxxxxxxxx
*Subject:* RE: [ibis-macro] Re: An AMI Overview



Fangyi,



1.     Even if a model is non-LTI, it may have an LTI approximation. If
the Init call returns an LTI approximation, then the EDA tool can use
“Statistical” methods to do very fast analysis, realizing that the GetWave
time domain simulation will still need to be made to confirm the result. If
the Init call does not return an LTI approximation, then the EDA tool must
use time domain methods only to analyze the channel.

2.     The current IBIS 5.0 specification has words like (section 2.1.6):

| 6. AMI_Init parses the configuration parameters, allocates dynamic

| memory, places the address of the start of the dynamic memory in

| the memory handle, computes the impulse response of the block and

| passes the modified impulse response to the EDA tool. The new

 |   impulse response is expected to represent the filtered response.

Since returning an impulse response assumes LTI (or an LTI approximation),
the model maker can do this calculation any way he chooses. One way to do
this calculation convolution. We spent much time determining if we should
use the word convolution, concatenation, combination, and ended up with the
word modified. It would probably be worth adding a paragraph to the
document that explicitly says that whenever convolution is used, it is
simply to represent the result of the function to be preformed, and the
model maker or EDA vendor can use any mathematical method deemed
appropriate for performance, accuracy or other algorithmic reasons.



Walter



Walter Katz

303.449-2308 <(303)%20449-2308>

Mobile 720.333-1107 <(720)%20333-1107>

wkatz@xxxxxxxxxx

www.sisoft.com



-----Original Message-----
*From:* ibis-macro-bounce@xxxxxxxxxxxxx [mailto:ibis-macro-bounce@
freelists.org]*On Behalf Of *fangyi_rao@xxxxxxxxxxx
*Sent:* Sunday, October 11, 2009 8:22 PM
*To:* wkatz@xxxxxxxxxx; ibis-macro@xxxxxxxxxxxxx
*Subject:* [ibis-macro] Re: An AMI Overview



Hi, Walter;



Thanks for your clarification of AMI methodology. I’d like to see the
overview or the spec also states clearly about following two topics.



1.       For non-LTI models that have GetWave, how does AMI_Init enable
model developers to also support statistical simulation using LTI
approximation?

2.       Do we explicitly assume the modified impulse returned by
AMI_Init is the CONVOLUTION between input impulse and the equalizer? I know
at least one model vendor would not be happy about this assumption because
their modified impulse is not from convolution.



Regards,

Fangyi



*From:* ibis-macro-bounce@xxxxxxxxxxxxx [mailto:ibis-macro-bounce@
freelists.org] *On Behalf Of *Walter Katz
*Sent:* Saturday, October 10, 2009 2:20 PM
*To:* IBIS-ATM
*Subject:* [ibis-macro] An AMI Overview



All,



We have all been getting into the nuts and bolts of AMI. I think we need
to step back and understand what AMI is all about. The following has been
said in many ways in many places, but I think it is appropriate to review
it at this time. I do not know if this belongs in the IBIS AMI
specification, but it sure would be nice.



Walter



AMI Overview



The analysis of high speed (>4 Gbps) offers some simplifications and some
challenges. The simplifications arise from the fact the driver (Tx) final
stage output, and the receiver (Rx) input along with the interconnect
between them can be treated as Linear and Time Invariant (LTI)
“Analog-Channel”. This allows various mathematical techniques to be applied
improving simulation performance by orders of magnitude. The complication
that has led to the development of the AMI standard arises from the need
for complex signal processing in both the Tx before the final stage driver
and particularly the Rx after the Rx receiver. The good news is that the
signal processing does not interact with the Tx/Interconnect/Rx
Analog-Channel. The signal processing that is going on is considered
important Intellectual Property (IP) of the IC vendors, and this along with
the need for simulating millions of bits and the IP considerations led to
the AMI standard.



A SerDes-Channel consists of Tx signal processing, Analog-Channel and Rx
signal processing. The Tx AMI model represents the Tx signal processing, an
impulse response represents the Analog-Channel, and the Rx AMI model
represents the Rx signal processing.



The Analog-Channel is represented as an impulse response hAC(t). It is the
differential mode impulse response of the interconnects between the Tx and
the Rx and includes the reactive load (impedance) of the Tx final stage
driver and the Rx receiver. This impulse response can be created using many
mathematical techniques, including, but not limited to simulation and TDR
measurement. Traditional IBIS does not model differential LTI buffers, this
will be addressed when I introduce new AMI reserved parameters. This is
also related to the topic of Vladimir’s presentation this Tuesday.



The Tx AMI model and Rx AMI model may themselves be either LTI or non-LTI.
If they are LTI they can be represented accurately by an impulse response.
If they are not LTI, they can be approximated by an impulse response. AMI
models are delivered as executable code in the form of a Shared Object (SO)
or a Dynamically Linked Library (DLL), and an .ami ASCII file.  All AMI
DLL’s have an AMI_Init entry, and an AMI_Close entry. This is all that is
required if the model is LTI. If a model is non-LTI then is must also have
an AMI_GetWave. If a model does have an AMI_GetWave then the model make is
telling the EDA tool that the model is non-LTI and that using the just
impulse response from the AMI_Init is not deemed sufficient to accurately
model the channel.



The .ami file tells the EDA tool if the model has an AMI_GetWave entry,
and sufficient information to configure the model, and to analyze the
results that the model generates.



When a model is LTI it does not need a GetWave entry. When LTI, the only
information that need be abstracted from the model is the impulse response
of the models equalization. The input to the Tx AMI_Init function is the
impulse response of the channel. The input to the Rx AMI_Init function is
the impulse response of the channel combined with the impulse response of
the Tx equalization obtained from the call to Tx AMI_Init.



When a model is non-LTI (or more importantly, the IC Vendor believes that
the non-LTI behavior is important) then it does require an AMI_GetWave
entry. The AMI_Init entry is used to return to the EDA tool an approximate
impulse response of the models equalization, and to pass on initialization
information to be used by the AMI_GetWave entry. The AMI_GetWave entry is
then called repeatedly with sequential blocks of waveforms. The waveforms
are that are input to Tx AMI_GetWave indicate the transition times of the
digital stimulus input to the Tx equalization circuitry. The waveforms that
are output of Tx AMI_GetWave are the waveforms that drive the
Analog-Channel. The waveform that is input to Rx AMI_GetWave is the
waveform that is the input to the Rx buffer. The output of the Rx
AMI_GetWave is the waveform at the Rx decision point, and optionally clock
ticks indicating the location of each recovered clock. The EDA tool
processes the waveform at the Rx decision point, and either uses the clock
ticks or the Clock Recovery Mean and Rj to generate bathtub curves, BER and
other channel data.



A fundamental principle of AMI modeling is that every EDA platform (both
software and hardware) will give the same results when presented with the
same Analog-Channel impulse response, the same AMI model conditions, and
the same input stimulus pattern. Each EDA platform may differ on how its
sets the Tx and Rx AMI model conditions, the stimulus pattern, how it
creates the Analog-Channel impulse response, and how it processes the
resulting outputs.





Walter Katz

303.449-2308 <(303)%20449-2308>

Mobile 720.333-1107 <(720)%20333-1107>

wkatz@xxxxxxxxxx

www.sisoft.com








Other related posts: