cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ronaldschreiber
Visitor
Visitor
14,133 Views
Registered: ‎08-06-2009

How to constrain a path from internal register through external logic (async. RAM) to internal register?

Jump to solution

I need your help with the following problem:

 

My FPGA design uses an external asynchronous RAM for storing data. The control signals (address, chip enable, output enable, write enable, ...) of the RAM are generated by FPGA registers clocked with MClk. The RAM output data is captured by FPGA registers also clocked with MClk. The internally generated clock MClk is specified with a PERIOD constraint. This PERIOD constraint allows timing optimization and analysis of FPGA-internal paths. How can I tell the tools that I also have paths through the external RAM with its delays?

 

For my opinion the OFFSET IN/OUT constraints can not be used: MClk is not available on a pad. Furthermore these constraints do not allow to specify a closed path.

 

I use ISE 11.2. My design targets on a Spartan3.

 

Thank you for your help!

0 Kudos
1 Solution

Accepted Solutions
hobson
Xilinx Employee
Xilinx Employee
11,934 Views
Registered: ‎04-15-2008

Hi Bert,

 

Technically, in a situation like you've described (80MHz creating 57MHz), yes.  The DCM/PLL will edge align its outputs, so the 2 clocks will be edge aligned for 1 cycle, but since they're different frequencies, their edges will diverge over the next few cycles.  Eventually, enough cycles will pass until their edges are aligned for one cycle again... and then the divergence begins again.

 

Since data is coming into the device at 57Mbps (after all, that's the speed you clocked it out at), the same phenomenon will occur when comparing it to the input 80MHz clock.

 

However, all of that doesn't really matter.  You're not clocking the data into the device with the 80MHz clock.  You're using the 57MHz clock to capture the 57Mbps data.  The 57MHz clock and the data coming in will not diverge.  They will have a constant phase relationship, which is why you can position the clock edge in the data eye using OFFSET IN constraints, IDELAYs, etc. and have it capture data correctly cycle after cycle.

 

I know this is confusing because with the OFFSET IN constraint, you essentially say "my 57Mbps data will be available at the input pin 3ns before my 80MHz rising clock edge hits its input pin."  But you must remember 2 things:

1) The DCM/PLL will edge align the clocks.  Obviously, it's possible to have a 80MHz and 57MHz clock that always have some phase difference, but the DCM/PLL will ensure that for one pair of rising edges, there will be a 0deg phase relationship.

2) This is static timing analysis.  People get caught up thinking "well okay, this works on cycle 0 because I'll assume my clocks are edge aligned, but on cycle 1 they begin to diverge."  You have to forget about this.  There is no concept of "previous cycle" or "next cycle" - just delay.

 

So, as I mentioned before, forget about frequency and just assume that for any given cycle you'd want to analyze, the 80MHz and 57MHz are edge aligned.

 

Therefore, for this situation and assuming clock insertion delay has been removed (I have to keep applying that disclaimer because it's critical), you can stop thinking:

"My 57Mbps data will be available at the input pin 3ns before my 80MHz rising clock edge hits its input pin"

and start thinking

"My 57Mbps data will be available at the input pin 3ns before my 57MHz rising clock edge hits the clock input of my capture flop. (Furthermore, I am actively ignoring the fact that the actual clock I'm referencing in the OFFSET IN constraint is a different frequency.)"

 

So finally, that's a long way of saying "it should work for any M/D combination, not just 'natural ratios.'"

 

Regards,

-Hobson

 

View solution in original post

15 Replies
drjohnsmith
Teacher
Teacher
14,114 Views
Registered: ‎07-09-2009

Hi

 

You generate MClk inside the FPGA, I assume from another clock. 

 

why can't you use offset in ? The user guide only seems to need the net name and set up time needed. You seem to have effectively the design on page 11, where data comes out on a clock, and is sampled on the same clock, the data is delayed in between. fig 2-1.

 

http://www.xilinx.com/itp/xilinx10/books/docs/timing_constraints_ug/timing_constraints_ug.pdf

 

It might ( I say might ) be a help, but I seem to remember this problem, in relation to DLL's, and board synchronisation designs. I'm certain there was an app note on it.

 

 

Or have I got this completely wrong ?

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
ronaldschreiber
Visitor
Visitor
14,085 Views
Registered: ‎08-06-2009

Hello drjohnsmith,

 

 

thank you for your answer.

 

You are right, MClk is generated inside the FPGA from an external 20MHz clock ClkIn:

 

ClkIn pin -> programmable clock divider ->  PLL (DCM) -> programmable clock divider -> MClk net

 

MClk is not available on a pad. For simplicity I specified MClk without any phase relation to ClkIn:

 

  # 80MHz master clock frequency
  NET "XLXI_1/ClkRtBlk/ClkDivider_3p5_1/MSM/QA" TNM_NET = "TG_MClk";
  NET "XLXI_1/ClkRtBlk/ClkDivider_3p5_1/dQB" TNM_NET = "TG_MClk";
  TIMESPEC "TS_MClk" = PERIOD "TG_MClk" 12.5 ns HIGH 50 %;

 

You suggested to use the OFFSET IN and OFFSET OUT constraint to specify the RAM timing. This requires the splitting of the 12.5ns cycle time in 3 parts: 

1) The time between the active clock edge and the output of valid control signals at the FPGA pins.

    As far as I understand this can be done with OFFSET OUT.

2) The time which is needed by the RAM to provide valid output data.

    My RAM needs 10ns to provide valid data after receiving valid control signals.

3) The time between valid input signals at the FPGA pins and the capturing clock edge.

    This can be done with OFFSET IN.

 

The sum of these 3 parts must be equal or lower the clock cycle time.

For my opinion this approach is pretty inconvenient: I have 2.5ns available for the sum (!) of output and input delay and I do not want to agonize how to split this time in parts.

 

Be that as it may, I tried the OFFSET IN/OUT approach. But I failed because MClk is not at a pin:

 

NET RAM_IO<*> OFFSET = IN 1 ns VALID 2 ns BEFORE "TG_MClk";
NET RAM_A<*>  OFFSET = OUT 500 ps AFTER "TG_MClk";
NET RAM_IO<*>  OFFSET = OUT 500 ps AFTER "TG_MClk";
NET RAM_BC_N<*>  OFFSET = OUT 500 ps AFTER "TG_MClk";
NET RAM_CE_N  OFFSET = OUT 500 ps AFTER "TG_MClk";
NET RAM_WE_N  OFFSET = OUT 500 ps AFTER "TG_MClk";
NET RAM_OE_N  OFFSET = OUT 500 ps AFTER "TG_MClk";

 

Translate says:

 

ERROR:ConstraintSystem:59 - Constraint <NET RAM_IO<*> OFFSET = IN 1 ns VALID 2

ns BEFORE "TG_MClk";> [NGD_AV.ucf(411)]: NET "TG_MClk" not found. Please

verify that:

1. The specified design element actually exists in the original design.

2. The specified object is spelled correctly in the constraint source file.

 

WARNING:ConstraintSystem:168 - Constraint <NET RAM_IO<*> OFFSET = IN 1 ns VALID

2 ns BEFORE "TG_MClk";> [NGD_AV.ucf(411)]: This constraint will be ignored

because NET "TG_MClk" could not be found or was not connected to a PAD.

 

ERROR:ConstraintSystem:59 - Constraint <NET RAM_A<*> OFFSET = OUT 500 ps AFTER

"TG_MClk";> [NGD_AV.ucf(414)]: NET "TG_MClk" not found. Please verify that:

1. The specified design element actually exists in the original design.

2. The specified object is spelled correctly in the constraint source file.

 

WARNING:ConstraintSystem:168 - Constraint <NET RAM_A<*> OFFSET = OUT 500 ps

AFTER "TG_MClk";> [NGD_AV.ucf(414)]: This constraint will be ignored because

NET "TG_MClk" could not be found or was not connected to a PAD.

 

(and so on)

 

 Okay, it seams to be wrong to use a timing group. So I made an experiment and used the net name for the first constraint:

 

 

NET RAM_IO<*> OFFSET = IN 1 ns VALID 2 ns BEFORE "XLXI_1/ClkRtBlk/ClkDivider_3p5_1/MSM/QA";

 

Translate answers:

 

WARNING:ConstraintSystem:168 - Constraint <NET RAM_IO<*> OFFSET = IN 1 ns VALID

2 ns BEFORE "XLXI_1/ClkRtBlk/ClkDivider_3p5_1/MSM/QA";> [NGD_AV.ucf(412)]:

This constraint will be ignored because NET

"XLXI_1/ClkRtBlk/ClkDivider_3p5_1/MSM/QA" could not be found or was not

connected to a PAD.

 

The error disappeared but the constraint is still ignored because the clock is not connected on a PAD. To be sure that the clock was found I put a "typing error" in the name of the clock net - after that the "NET not found" error appeared again.

 

Do I use the constraints in a wrong way?

Do I have to make MClk an input pad as seen in the timing constraints guide?

 

 

Best Regards,

Ronald

 

 

 

0 Kudos
ronaldschreiber
Visitor
Visitor
14,071 Views
Registered: ‎08-06-2009

Please excuse me if I do not answer your messages for the next 2 weeks. I am on vacation.

0 Kudos
drjohnsmith
Teacher
Teacher
14,062 Views
Registered: ‎07-09-2009

Hi

 

to be honest your on the limit of my knowledge i can answer with 100 % confidence. I'd have to play to check.

 

I think  ( see above ) that timming specs are carried through PLL / DCM etc. 

 

 

i.e. you specify in relation to the origginal clock pin, in your case the 20 MHz.

 

Timming analizer is clever enough to recognise the clock divides etc, and work back from there.

 

BTW: Why  8 MHz clock ? I'd have been inclined to run the design at 20 MHz probably more,  and used a divided clock enable. Trying to make multiple clocks work is always 'fun'.  

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
xilinxbert
Visitor
Visitor
13,943 Views
Registered: ‎02-17-2009

Hi Ronald,

 

I have been looking into this issue a short time ago, since I have a similar problem. I never found the anwser. Even Xilinx couldn't provide me a good solution.

 

I changed my FPGA design to deal with this. I can no dynamically choose to clock in the external signals on four different clock phases (0deg, 90deg, 180deg, 270deg). And then I can also move the data around the edge with idelays.

 

Maybe this is a solution you can use. We now adjust these settings when we create a new PCB. When your FPGA can check data quality itself (which it can, by writing and reading to/from the RAM), then you can put in a picoblaze, for example, to dynamically adjust these settings. Then you don't even have to worry about constraints, it'll always work!

 

I know this is not the anwser you are looking for, but I hope it helps.

 

Kind regards,

Bert

hobson
Xilinx Employee
Xilinx Employee
13,930 Views
Registered: ‎04-15-2008

Ronald,

 

Drjohnsmith is on the right track here.  I agree with him that you should avoid inserting clock dividers between the clock input pin and the PLL.  Likewise, avoid putting them between the PLL and your clocked logic.  Rather, you would ideally have something that looks like this:

 

<your_clkin_net> => IBUFG => PLL => BUFG => MClk

 

All synchronous elements should be clocked by MClk.  You can also use the MClk net to clock your clock dividers, which then control the clock enable signals of any design elements you want running slower.

 

There are a number of benefits to doing this:

1) You'll only need 1 PERIOD constraint, which will be attached to your input clock net.  This PERIOD constraint will trace through the PLL and constrain all the downstream synchronous elements.  If desired, you can then identify any logic being enabled by your clock dividers as being part of multicycle paths.

2) Since everything is clocked off of MClk, there is no need to cross clock domains, which makes your timing analysis much easier.

3) Clock insertion delay can be removed from the design (i.e., a rising edge at an internal flip-flop can be phase aligned to the rising edge at the input clock pin).

4) You can successfully use OFFSET IN/OUT constraints to constrain your RAM interface. BTW, to answer your question, all OFFSET constraints must be related to an input clock net. They cannot be related to internally generated clocks. However, if clock insertion delay is removed, then this restriction doesn't matter.


Now, in regard to your RAM interface, I'd suggest placing the output registers in the IOBs.  This minimizes your clock-to-output pin delay.  If you do this, then placing an OFFSET OUT on these paths won't do much to reduce the output delay since the path from the output flops to the output pins is fixed, but it is nice to see the delays reported in the timing report.  It also adds predictability to your RAM interface from run to run.

 

The delay through the RAM is what it is - you can't change it - which is why there is no way to put a constraint on this part of the path.

 

Ideally, you'd also place your capture flip flops in the IOBs as well.  This minimizes your capture setup time and adds timing predictability from run to run.  Again, if you place the flops in the IOBs, OFFSET IN won't do much to reduce your setup time, but the delays will show up in the timing report.

 

As mentioned by xilinxbert, you may wish to instantiate IDELAYs between your input pins and your capture flops to allow you to add delay to the RAM signals before they're captured by MClk.  Alternatively (or in addition), you may want to have the PLL create a 90deg (or some other phase) version of MClk, which you can use instead to capture the RAM signals.  However, you should immediately re-clock this info with MClk (0deg) inside the device so that your internal datapaths are all running off the same clock.

 

Regards,

-Hobson

xilinxbert
Visitor
Visitor
13,927 Views
Registered: ‎02-17-2009

Hobson,

 

Although the techniques you described are good to use, I think that the major issue is not resolved.

 

The issue is (for as I understand), that there are numerous delays outside the FPGA, which you cannot constrain. It would be nice if you could calculate the static delays of the external signals and then use an OFFSET IN constraint, against the outgoing clock (to the external device), to tell ISE the timing of the signal. ISE could then try to match this timing, by instantiating delay components, which are available in the IOB, or even by placing routing delays.

 

This delay is quite easy to calculate against the outgoing clock, but can be very difficult against the input clock (phase differences, frequency differences, routing delays, ...).

 

Kind regards,

Bert

0 Kudos
hobson
Xilinx Employee
Xilinx Employee
13,907 Views
Registered: ‎04-15-2008

Hi Bert,

 

I'll admit I may have misunderstood, but I think the OP described an async interface that didn't forward a clock, so that's what I was trying to respond to.  I think you're describing something pretty similar, but slightly different.  I think you're describing a typical source sync output interface in which the FPGA forwards data & clock to an external device.  However, the external device simply replies with data and does not forward a clock/strobe back to the FPGA.  If that's correct, I can certainly see why something like this would be helpful. Unfortunately, I simply don't know if that's on the constraints roadmap.

 

However, although you can't currently constrain based on an output clock, constraining using the input clock really isn't too bad IF you design your clock network to remove clock insertion delay.  Granted, if you aren't removing the insertion delay, this becomes much more difficult.

 

I apologize if this is repetitive or you're already familiar with all of this, but let me just cover all the bases.  Let's assume that you *do* remove the delay by using a PLL or DCM and feeding the buffered clock back around to the PLL/DCM. As I described in my previous post, you now have a situation where there is a 0deg phase difference between a rising clock edge at the clock pin of the FPGA and a rising edge at the clock input of any synchronous element inside the FPGA (assuming you didn't intentionally apply a phase shift using the PLL/DCM).

 

For an output interface, all output data flops should be placed in the IOBs, which minimizes your clock-to-output pin for your data bits. Pretty straightforward. Now, when forwarding the clock, do not route the clock directly to the pin. Instead, use the output DDR (ODDR) clock forwarding technique.  Specifically, route the clock to the clock inputs of a set of output DDR (ODDR) registers, which will reside in the IOB of the pin you're using to forward the clock. By tying the posedge flop's D input high and the negedge flop's D input low, you've now just replicated the clock signal on the output of the ODDR, which takes a dedicated route to the output pin.  There is code for doing this in the ISE Language Templates.

 

But why do this?  Well, it has to do with the subtleties of how clock net gets routed to asynchronous elements, which includes output pins. If the clock is routed directly to the pin, it has to jump off global (low skew) routing onto local routing to get there. Where and how it jumps off the global routing can vary from route to route.  In addition, the delays on local routing vary much more over PVT than global routing.  So... basically it makes it a lot harder to create a known phase relationship between your clock and data on your output pins. By using the ODDR technique, the clock stays on global routing all the way up to the ODDR register, so you can ensure that clock and data will leave the device with a known phase relationship.

 

Now, if you know your trace flight times and know the clock-to-out delay(s) of the external device, you can provide this info to the OFFSET IN constraint. You'll be relating this OFFSET IN constraint to the FPGA's clock input pin, which is not coming from the external device, but still has a direct and known relationship with the data coming back from the external device. Because clock insertion delay has been removed, there is a 0deg phase difference between the rising edge at the pin and the rising edge at the clock pins of the capture flops.  If the capture flops are in the IOBs, then you really just have to worry about the fixed delay from the pin to the flop.

 

So... the point of all that is that there are really no concerns about clock or data path routing differences inside the FPGA. Clock phase differences can be tightly controlled by the PLL/DCM, as necessary, to allow the external device or FPGA capture flops to correctly clock the data.  You want to forward a 90deg clock with 0deg data? Fine.  You want to capture data on a 180deg clock? No problem.  Also, in this type of setup, there shouldn't be any frequency differences, at least not on the I/O interface.

 

Now just as an aside, if the external device *does* forward a clock to the FPGA, then capture timing makes a lot more sense since you're capturing with a clock directly associated with the incoming data and you don't have to worry about many of the delays on the external device.  You just have to worry about the phase relationship between the data it's sending and the clock/strobe it's sending.

 

Also, just to comment on ISE making placement routing decisions based on OFFSET constraints... The software currently does this if the input and/or output flops are *not* placed in the IOBs.  This is how it meets the OFFSET constraints.  Obviously, everything is still related back to an input clock though - not an output clock. I could be wrong about this, but I don't think we'll ever have the software instantiate an IDELAY block or change the tap setting of an existing IDELAY block because this could be considered a change to the original design, which many users think is a bad thing.  The software does (sort of) make suggestions about tap settings, however.  If you write your OFFSET IN constraint correctly using the VALID keyword (important for source sync designs), the timing report will report how far the capture clock is from the center of the data eye in picoseconds. It's simple math to relate this to a tap setting based on 78ps(avg) tap sizes.

 

Anyway, sorry for the long post, but hopefully some of it is helpful.

 

Best Regards,

-Hobson

xilinxbert
Visitor
Visitor
13,889 Views
Registered: ‎02-17-2009

Hi Hobson,

 

Very good explanation! I'm am aware of these techniques you've described. I only have one difficulty with this approach.

 

What if the input clock and internal clock have frquency differences. Let's say my input clock is 80MHz and my clock to the external device and synchronous elements is 57MHz. Really strange combination, but that's the point of this question :-).

 

I can't use clk0, in this case I have to use clkfx, not the best output, but just for the purpose of this question.

 

I hope you can clearify this last obstacle.

 

Kind regards,

Bert

hobson
Xilinx Employee
Xilinx Employee
8,667 Views
Registered: ‎04-15-2008

Hi Bert,

 

An OFFSET constraint requires specification of the input clock pin because it needs to know the delay on the clock path.  It uses this to calculate what the delay on the data path should be so that setup and hold times are met.  If you use a PLL/DCM to remove insertion delay, then you can see in the timing report that the clock path delay is pretty negligible.  But what if you didn't remove insertion delay and your clock path is 5ns?  It needs to know this, obviously.

 

Interestingly, it doesn't care about frequency.  It only cares about the difference between the clock and data paths and whether the setup & hold times are met.  Let's say you're clocking data in at 100MHz on a Virtex-5 -2C device.  You could put an OFFSET IN constraint on this input that says data will arrive 5ns before the clock edge and will be valid for 50ns.  This constraint would pass since setup and hold times would be met, even though you'd really get 5 rising edges in that data valid window (maybe you're oversampling?).  My point is that frequency doesn't come into the calculation.

 

This makes it easy to think about the timing for OFFSET IN, but you have to remember to calculate your frequency and data valid window correctly yourself when supplying the information to the constraint.  You can just think of it as saying (for example): "I promise that data will be available at the data input pin 3ns before the clock edge arrives at the capture flip flop and the data will be valid for 17.5ns (~57MHz)."  By doing this, you are ensuring that you won't get 2 clock edges in your data valid window since you know your period is ~17.5ns.

 

I know it's strange to hear "don't worry about input frequency vs. generated frequency" when talking about timing constraints, but for the purposes of OFFSET constraints, I think you can do that.

 

Regards,

-Hobson

xilinxbert
Visitor
Visitor
8,651 Views
Registered: ‎02-17-2009

Hi Hobson,

 

So you don't even have to care about the input frequency of the clock, that's brilliant!

 

Thanks a lot for taking the time to explain this.

 

But I think this only works if the two clocks have a "natural" (1, 2, 3, 4, ....) ratio, am I right? Otherwise the data will slowly move towards or away from the input clock edge in time.

 

Kind regards,

Bert

Message Edited by xilinxbert on 08-21-2009 09:34 AM
0 Kudos
hobson
Xilinx Employee
Xilinx Employee
11,935 Views
Registered: ‎04-15-2008

Hi Bert,

 

Technically, in a situation like you've described (80MHz creating 57MHz), yes.  The DCM/PLL will edge align its outputs, so the 2 clocks will be edge aligned for 1 cycle, but since they're different frequencies, their edges will diverge over the next few cycles.  Eventually, enough cycles will pass until their edges are aligned for one cycle again... and then the divergence begins again.

 

Since data is coming into the device at 57Mbps (after all, that's the speed you clocked it out at), the same phenomenon will occur when comparing it to the input 80MHz clock.

 

However, all of that doesn't really matter.  You're not clocking the data into the device with the 80MHz clock.  You're using the 57MHz clock to capture the 57Mbps data.  The 57MHz clock and the data coming in will not diverge.  They will have a constant phase relationship, which is why you can position the clock edge in the data eye using OFFSET IN constraints, IDELAYs, etc. and have it capture data correctly cycle after cycle.

 

I know this is confusing because with the OFFSET IN constraint, you essentially say "my 57Mbps data will be available at the input pin 3ns before my 80MHz rising clock edge hits its input pin."  But you must remember 2 things:

1) The DCM/PLL will edge align the clocks.  Obviously, it's possible to have a 80MHz and 57MHz clock that always have some phase difference, but the DCM/PLL will ensure that for one pair of rising edges, there will be a 0deg phase relationship.

2) This is static timing analysis.  People get caught up thinking "well okay, this works on cycle 0 because I'll assume my clocks are edge aligned, but on cycle 1 they begin to diverge."  You have to forget about this.  There is no concept of "previous cycle" or "next cycle" - just delay.

 

So, as I mentioned before, forget about frequency and just assume that for any given cycle you'd want to analyze, the 80MHz and 57MHz are edge aligned.

 

Therefore, for this situation and assuming clock insertion delay has been removed (I have to keep applying that disclaimer because it's critical), you can stop thinking:

"My 57Mbps data will be available at the input pin 3ns before my 80MHz rising clock edge hits its input pin"

and start thinking

"My 57Mbps data will be available at the input pin 3ns before my 57MHz rising clock edge hits the clock input of my capture flop. (Furthermore, I am actively ignoring the fact that the actual clock I'm referencing in the OFFSET IN constraint is a different frequency.)"

 

So finally, that's a long way of saying "it should work for any M/D combination, not just 'natural ratios.'"

 

Regards,

-Hobson

 

View solution in original post

xilinxbert
Visitor
Visitor
8,625 Views
Registered: ‎02-17-2009

Hi Hobson,

 

Thank a lot for your anwser. It is totally clear now!

 

For me, this was one of the hardest things to do. This new insight makes it a lot easier.

 

Thanks again,

Bert

0 Kudos
ronaldschreiber
Visitor
Visitor
8,592 Views
Registered: ‎08-06-2009
Hi Hobson,
Hi Bert,
Hi drjohnsmith,


I am back from vacation and pleasantly surprised about the things happened in this forum! Many thanks for the discussion and your help. Especially Hobson's answers made a lot of things clear to me:

1) My design suffers from the clock dividers (state machines) between ClkIn and the DCM and between the DCM and MClk. These dividers make a predictable phase relation between ClkIn and MClk impossible. In the past I did not care about this phase relation (because it was not required by the system) but now it is needed for constraining the RAM interface.
The programmable dividers came in the design on request of my customer: he could not find a decision what crystal he will use and how fast the design must run. I like such specifications! I will push him to a decision and than I will generate MClk with a DCM without any additional divider.

2) I will use the OFFSET constraint referenced to ClkIn. ClkIn has a different frequency than the interface but as Hobson explained the timing analyzer only cares about phases and delays and not about frequency.

I will do the changes as soon as possible and tell you if it works.

Again many thanks for your support!!!!!!!!!!


Best Regards,
Ronald
0 Kudos
ronaldschreiber
Visitor
Visitor
8,582 Views
Registered: ‎08-06-2009

It works. My problem is solved. Thank you.

 

Regards,

Ronald

0 Kudos