When are two clock domains actually considered asynchronous?


B

Beppe

Consider the following system:

inp_clk -- Input clock to FPGA (Xilinx Spartan 3A DSP)
-- directly routed to DCM
-- PERIOD constraint attached to it
-- Frequency: 125 MHz

clk_25 -- CLKDV_OUT from DCM
-- Frequency: 25 MHz

clk_28 -- CLKFX_OUT from DCM
-- Frequency: inp_clk*7/31 MHz

clk_250k -- Output from a VHDL-module that divides the clk_25 with
100
-- Frequency: 250 kHz

CTRL_PROC : process (clk_250k)
begin
if rising_edge(clk_250k) then
if reset = '1' then
reg1 <= '0';
else
if byte_received = '1' then
if data_in = “10101010” then
reg1 <= '1';
else
reg1 <= '0';
end if;
end if;
end if;
end if;
end process;

CNT_PROC : process (clk_28)
begin
if rising_edge(clk_28) then
if reset = '1' then
cnt <= (others => ‘0’);
else
if reg1 = '1' then
cnt <= cnt + 1;
else
cnt <= cnt - 1;
end if;
end if;
end if;
end process;

reg1 is assigned a value in CTRL_PROC and read in CNT_PROC and thus it
is crossing clock domains. Do I need to worry about that in the above
situation and apply some asynchronous clock domain techniques? I’m
asking since the two clocks actually are related to each other. So,
main question:

When are two clock domains actually considered asynchronous?

Some related questions. How does ISE/XST handle the situation? As I
understand the Xilinx software automatically derives a new PERIOD for
each of the DCM output clocks and determines the clock relationships
between the output clock domains. There will probably be moments where
the edges of the two clocks are so close that the timing won’t be met.
Do I need to insert a FALSE PATH constraint in this case?

And, last question, should I put the clk_250k on a global clock path?

Regards
Beppe
 
Ad

Advertisements

K

KJ

Consider the following system:

inp_clk   -- Input clock to FPGA (Xilinx Spartan 3A DSP)
          -- directly routed to DCM
          -- PERIOD constraint attached to it
          -- Frequency: 125 MHz

clk_25    -- CLKDV_OUT from DCM
          -- Frequency: 25 MHz

clk_28    -- CLKFX_OUT from DCM
          -- Frequency: inp_clk*7/31 MHz

clk_250k   -- Output from a VHDL-module that divides the clk_25 with
100

clk_250k will be a problem in an FPGA. In an FPGA environment, you
basically almos never want to generate a clock with logic. Even when
it comes out of a flip flop you're most likely doomed.
          -- Frequency: 250 kHz

CTRL_PROC : process (clk_250k)
begin
 if rising_edge(clk_250k) then

Yep...doomed

  end if;
 end if;
end process;

CNT_PROC : process (clk_28)
begin
 if rising_edge(clk_28) then
  if reset = '1' then
   cnt <= (others => ‘0’);
  else
   if reg1 = '1' then
    cnt <= cnt + 1;
   else
    cnt <= cnt - 1;
   end if;
  end if;
 end if;
end process;

reg1 is assigned a value in CTRL_PROC and read in CNT_PROC and thus it
is crossing clock domains. Do I need to worry about that in the above
situation and apply some asynchronous clock domain techniques?

Yes and no.
- Since you created two clocks, then yes you should treat them as if
they are unrelated.
- What you should do is generate a clock enable for rather than a
clock for the 250k. Then both processes are running in the same clock
domain...no clock crossings at all.

Instead of this...
process(clk_250k)
begin
if rising_edge(clk_250k) then
...
end if;
end process;

Do this...
process(clk)
begin
if rising_edge(clk) then
if (clkenable_250k) then
...
end if;
end if;
end process;

Where clkenable_250k is generated by your VHDL code to be exactly one
clock cycle in your 0 to 99 counter.

And, last question, should I put the clk_250k on a global clock path?
No...because you should be getting rid of it as a clock and using it
as a clock enable instead.

Kevin Jennings
 
R

rickman

I can't say I totally agree with the doom and gloom predictions of
KJ...


clk_250k will be a problem in an FPGA. In an FPGA environment, you
basically almos never want to generate a clock with logic. Even when
it comes out of a flip flop you're most likely doomed.

I agree that generating a clock from a counter is not a good idea.
But it is not a fatal flaw if handled correctly. But you are better
off using a clock enable unless there is a reason.

Yep...doomed

Isn't that a bit dramatic? If the tools properly recognize this
signal as a clock and routes it on a clock spline, and you treat it as
a separate clock with no clear timing relation to the clock it is
generated from, then there shouldn't be any problem. Actually, I have
seen the tools not use a clock spline and they seem to handle it
correctly, recognizing it as a clock but routing it on the local
interconnect.

Yes and no.
- Since you created two clocks, then yes you should treat them as if
they are unrelated.
- What you should do is generate a clock enable for rather than a
clock for the 250k. Then both processes are running in the same clock
domain...no clock crossings at all.

Instead of this...
process(clk_250k)
begin
if rising_edge(clk_250k) then
...
end if;
end process;

Do this...
process(clk)
begin
if rising_edge(clk) then
if (clkenable_250k) then
...
end if;
end if;
end process;

Where clkenable_250k is generated by your VHDL code to be exactly one
clock cycle in your 0 to 99 counter.




No...because you should be getting rid of it as a clock and using it
as a clock enable instead.

I don't think you can easily put a signal on a global clock line. If
the tools recognize it as a clock, because it drives the clock input
of a FF, it will consider if it needs to use a global clock line to
control skew. If so it will use one. If not it won't.

There are times when you don't want to use an enable. A design I did
generates a clock enable to control some circuitry. But the input and
output of the data signals need to be done on the actual clock edges
to optimize the setup and hold times of the external signals. So the
data input and output are run through a FF clocked by the clock I am
generating and then I deal with the data timing as required.

Rick
 
K

KJ

I can't say I totally agree with the doom and gloom predictions of
KJ...

I agree that generating a clock from a counter is not a good idea.
But it is not a fatal flaw if handled correctly.  

The only way to 'handle it correctly' will be to treat it as an
independent clock domain and design in clock domain crossing logic.
Without that, you'll be running into hold time issues with any signal
originating from the high speed clock domain that enters the generated
clock domain. You can't do anything about those issues except re-
route, cross your fingers and hope. Yes you can hand hold a design
and get it to work, but before you do so there should be a compelling
reason to do so. No such reason was posted.
Isn't that a bit dramatic?  

No. I would characterize the OP's odds of success as 'low'. At best,
he would find that he is never able to get the design working right
out of the shoot, abandon the approach and will end up with more
knowledge. That would be a good outcome. At worst, the design would
be going into production when there starts to become a growing pile of
boards that seem to have a 'temperature sensitivity' or 'date code
issue'.

What is your definition of 'doomed'?
If the tools properly recognize this
signal as a clock and routes it on a clock spline, and you treat it as
a separate clock with no clear timing relation to the clock it is
generated from,

But the OP clearly doesn't know this if you read the post.
There are times when you don't want to use an enable.  A design I did
generates a clock enable to control some circuitry.  But the input and
output of the data signals need to be done on the actual clock edges
to optimize the setup and hold times of the external signals.  So the
data input and output are run through a FF clocked by the clock I am
generating and then I deal with the data timing as required.

But in those situations, you don't have any logic being implemented in
the clock domain crossing as was in the OP. In the posted code, the
signals reset, byte_received and data_in probably originate in some
other domain and are crossing; reg1, as noted by the OP definitely
does come from a foreign clock domain and is not treated properly.

The clock domain crossing looks like this...

Synced_To_Clock_Signal <= Synced_To_Other_Clock_Signal when
rising_edge(Clock);

Kevin Jennings
 
B

Beppe

Thanks for the answers.

An enable won’t solve the problem of crossing clock domains. With an
enable the CTRL_PROC would be clocked by clk_25, but the CNT_PROC
would still be clocked by clk_28. clk_28 = 35/31*clk_25.

I’m aware of the problem with logic generated clocks, but I hope that
Rick is right here. Putting the clock on a low skew global clock net
should be enough to ensure that hold and setup times are met.
Actually, when synthesizing the design, XST infers a BUFG on the
clk_250k, as you predicted Rick, and the design seems to be working
fine in hardware although I haven’t made any extensive tests yet.

I was first thinking that it would be okay to put the clk_250k on a
non-dedicated clock net because of its low frequency, but the
frequency doesn’t matter here if I’m right when rethinking it. The
output of a flip-flop (as a result of the flip-flop being clocked by a
clock edge) could be propagating to the next flip-flop before the same
clock edge clocks the next flip-flop and thus leading to a hold time
violation no matter the frequency. Right?

On a side note, a solution for clocks with excessive skew (on non-
global clock nets) should be to alternate between positive and
negative clock edges on every other register. That would cut the
performance by half, but if it’s applied on low frequency clocks it
doesn’t really matter. Is this a no, no technique or would I be fine
using it?

As for the original question I guess I could simply find the minimum
distance between a clk_28 edge and a clk_25 edge (Hm, exactly this is
what ISE/XST should do if I understand the documentation correctly).
That time would be the “new” timing constraint. If it’s impossible to
meet this new timing I need to use asynchronous clock domain
techniques, otherwise it would be just fine.
In the posted code, the
signals reset, byte_received and data_in probably originate in some
other domain and are crossing; reg1, as noted by the OP definitely
does come from a foreign clock domain and is not treated properly.

data_in and byte_received are registers clocked by clk_250k and
originate from a MIDI UART. The clk_250k frequency is eight times the
31.25 kbaud rate of the MIDI interface and used to retrieve the
asynchronous serial MIDI data.

Beppe
 
B

Beppe

(Hm, exactly this is
what ISE/XST should do if I understand the documentation correctly).

And it does. Another good reason for using clock enables in this
particular case (and probably in other cases as well) and not the
derived clock is that XST sees the relationship between clk_25 and
clk_28 when a source register is clocked by the first and the
destination register is clocked by the second.

A test (not with the exact processes above) reveals this. Timing
report:

Slack: -5.319ns (requirement –
(data path - clock path skew + uncertainty))
Source: test_cnt_1 (FF)
Destination: led_2 (FF)
Requirement: 1.140ns
Data Path Delay: 6.059ns (Levels of Logic = 10)
(Component delays alone exceeds constraint)
Clock Path Skew: -0.400ns (1.832 - 2.232)
Source Clock: clk_25 rising at 1169000.000ns
Destination Clock: clk_28 rising at 1169001.140ns
Clock Uncertainty: 0.000ns

So, the minimum distance is 1.140 ns and that’s the new requirement,
which of course is not met.

/B
 
Ad

Advertisements

R

rickman

The only way to 'handle it correctly' will be to treat it as an
independent clock domain and design in clock domain crossing logic.
Without that, you'll be running into hold time issues with any signal
originating from the high speed clock domain that enters the generated
clock domain.  You can't do anything about those issues except re-
route, cross your fingers and hope.  Yes you can hand hold a design
and get it to work, but before you do so there should be a compelling
reason to do so.  No such reason was posted.

I expect there are tons of facts involve that he didn't post. Why not
assume the guy has a brain in his head and discuss the issue without
being extreme about it?

No.  I would characterize the OP's odds of success as 'low'.  At best,
he would find that he is never able to get the design working right
out of the shoot, abandon the approach and will end up with more
knowledge.  That would be a good outcome.  At worst, the design would
be going into production when there starts to become a growing pile of
boards that seem to have a 'temperature sensitivity' or 'date code
issue'.

What is your definition of 'doomed'?


But the OP clearly doesn't know this if you read the post.

I think you are missing the point. The OP is asking the question. Of
course he doesn't "know" for sure that he has to treat the new clock
as an independent clock, otherwise he wouldn't be asking the
question. But clearly he is aware of the issues involved. So yes,
"doomed" is being overly dramatic.

But in those situations, you don't have any logic being implemented in
the clock domain crossing as was in the OP.  In the posted code, the
signals reset, byte_received and data_in probably originate in some
other domain and are crossing; reg1, as noted by the OP definitely
does come from a foreign clock domain and is not treated properly.

The clock domain crossing looks like this...

Synced_To_Clock_Signal <= Synced_To_Other_Clock_Signal when
rising_edge(Clock);

Kevin Jennings

Yes, the OP is asking if he needs to add that sort of code. The
answer is "yes". No need to say his design is "doomed" or otherwise
be dramatic about it. If the guy didn't have a clue, he wouldn't have
asked the question.

Rick
 
R

rickman

Thanks for the answers.

An enable won’t solve the problem of crossing clock domains. With an
enable the CTRL_PROC would be clocked by clk_25, but the CNT_PROC
would still be clocked by clk_28. clk_28 = 35/31*clk_25.

I’m aware of the problem with logic generated clocks, but I hope that
Rick is right here. Putting the clock on a low skew global clock net
should be enough to ensure that hold and setup times are met.
Actually, when synthesizing the design, XST infers a BUFG on the
clk_250k, as you predicted Rick, and the design seems to be working
fine in hardware although I haven’t made any extensive tests yet.

Don't count on the fact that the design works on your lab bench as
proof that it works in any real sense! You can never prove a design
works by testing it!!! You can only use test to prove that a design
doesn't work. To prove that it works requires that you test all
possible conditions and that's not really possible much less
practical.

I was first thinking that it would be okay to put the clk_250k on a
non-dedicated clock net because of its low frequency, but the
frequency doesn’t matter here if I’m right when rethinking it. The
output of a flip-flop (as a result of the flip-flop being clocked by a
clock edge) could be propagating to the next flip-flop before the same
clock edge clocks the next flip-flop and thus leading to a hold time
violation no matter the frequency. Right?

On a side note, a solution for clocks with excessive skew (on non-
global clock nets) should be to alternate between positive and
negative clock edges on every other register. That would cut the
performance by half, but if it’s applied on low frequency clocks it
doesn’t really matter. Is this a no, no technique or would I be fine
using it?

Yes, I think you understand the issue here. I've never considered
using a low speed clock in this manner, but I expect it would work ok
as long as you account for ***ALL*** possible logic paths. For
example, if you have any sort of counter, you would need to use two
sets of FFs in the feedback loop, one positive edge triggered and one
negative edge triggered. Otherwise clock skew can cause one output to
change before another bit that depends on the first is clocked. As
you say, clock skew causes hold time problems.

As for the original question I guess I could simply find the minimum
distance between a clk_28 edge and a clk_25 edge (Hm, exactly this is
what ISE/XST should do if I understand the documentation correctly).
That time would be the “new” timing constraint. If it’s impossible to
meet this new timing I need to use asynchronous clock domain
techniques, otherwise it would be just fine.

I'm not sure what you are getting at. If the clocks are not simply
related, I'm not sure you can assume there is any useful relationship
between their timing. To generate the 28 MHz clock the 125 MHz input
clock is multiplied up to 825 before being divided down to 28.xxx.
How would you expect the tools to consider the timing relationship
between two clocks divided down from an 825 MHz (~1.2 ns period)
clock?

data_in and byte_received are registers clocked by clk_250k and
originate from a MIDI UART. The clk_250k frequency is eight times the
31.25 kbaud rate of the MIDI interface and used to retrieve the
asynchronous serial MIDI data.

I recently discussed a multiple clock design with my customer. He
said he had more than 50 clocks in this design and wanted details on
how I deal with syncing multiple clock domains. I explained that I do
all my work in one clock domain and use a particular logic circuit to
transport clocks, enables and data into that one domain. I solve the
synchronization problem once at the interface and never have to worry
about it again.

That logic uses two processes, one in each clock domain. If the FROM
domain uses a clock enable, the data is registered in the FROM
domain. Data is normally also registered in the TO domain but it
depends on the rates. Clocks and/or clock enables run through a
simple circuit that deals with metastability and provides a clock
enable in the new domain that suits the situation. The circuit is
just three FFs, one in the FROM clock domain and two in the TO clock
domain. The FROM domain FF and one of the TO domain FFs have the data
inputs and outputs connected in a feedback loop with one inverter in
the loop. If syncing a clock the FROM domain FF has no enable. If
syncing a clock enable, that enable is used on the FROM domain FF.
The TO domain FF in the feedback loop feeds the second FF for
metastability minimization. Every FROM domain clock edge or clock
enable causes the feedback loop to toggle state. An XOR gate on the
output of the two TO FFs gives you a clock enable in the TO domain.
The FROM domain clock can be faster than the TO domain clock as long
as the FROM clock enable is less frequent than half the TO domain
clock rate. It may even be possible to have an enable rate up to the
TO domain clock rate, but I won't swear to that unless I analyzed this
carefully.

This is a lot simpler to think about looking at a diagram. Maybe I
need to write this up. I didn't think of this circuit myself. A co-
worker told me about it and it was given to him by his brother I
think. It is very versatile and is the only circuit I use for clock
domain crossing with varying data registers depending on the
particulars.

My customer found this to work for him with his 50+ clocks.

Rick
 
A

Alessandro Basili

Thanks for the answers.
[snip]

Don't count on the fact that the design works on your lab bench as
proof that it works in any real sense! You can never prove a design
works by testing it!!! You can only use test to prove that a design
doesn't work. To prove that it works requires that you test all
possible conditions and that's not really possible much less
practical.

I am sorry but I disagree with you on this point. There are "good
practices" that help a lot in guaranteeing the quality of your project.
I believe that coding is just part of the story. Having the possibility
to test the design by a different team from the designers one will make
a huge difference. To do that a very precise (not necessarily detailed)
documentation is of course mandatory, since the verification team should
not go in the rtl details, or even the timing constraints and place &
route details of the project (the concept behind the design will also
benefit of a well structured documentation).

This is why there are standardized procedures, for avionics, space
applications, military applications (to mention some of them), which go
beyond the vhdl and define a work flow that should be as much
independent as possible from the individual skills of the designers team.

And also limiting the focus only on the coding side, there are a lot of
dos and don'ts that should be followed thoroughly.
Here for instance a good article on common hdl mistakes (and IMHO
misconceptions):

http://www.designabstraction.co.uk/Articles/Common HDL Errors.PDF

Why do you need to go in such a complicated pathway when you don't need
to? It has been already suggested a very easy and robust solution that
will avoid any of the problems you mentioned:

> - What you should do is generate a clock enable for rather than a
> clock for the 250k. Then both processes are running in the same clock
> domain...no clock crossings at all.
>

In my opinion the use of both rising and falling edges should have a
stronger motivation (like to minimize the peak current during clock
transitions in large SoC).

Even though your solution may work, that doesn't mean it is the right
one. I would recommend going through a clock domain crossing technique
as already suggested.
Again, following "good practices" not only help us having better chances
our systems work, it also (and more important) helps spreading the use
of them with invaluable returns to the whole community.
I'm not sure what you are getting at. If the clocks are not simply
related, I'm not sure you can assume there is any useful relationship
between their timing. To generate the 28 MHz clock the 125 MHz input
clock is multiplied up to 825 before being divided down to 28.xxx.
How would you expect the tools to consider the timing relationship
between two clocks divided down from an 825 MHz (~1.2 ns period)
clock?

That is data_in and byte_received are from a different clock domain and
they should by resync'ed to be used in the clk_25 domain.
I recently discussed a multiple clock design with my customer. He
said he had more than 50 clocks in this design and wanted details on
how I deal with syncing multiple clock domains. I explained that I do
all my work in one clock domain and use a particular logic circuit to
transport clocks, enables and data into that one domain. I solve the
synchronization problem once at the interface and never have to worry
about it again.

I would recommend an alternative to the 50 clocks domains, instead.

Al
 
B

Beppe

Don't count on the fact that the design works on your lab bench as
proof that it works in any real sense! You can never prove a design
works by testing it!!! You can only use test to prove that a design
doesn't work. To prove that it works requires that you test all
possible conditions and that's not really possible much less
practical.

Of course you’re right. “It’s working in hardware” was more of a hint
that it might not be totally doomed.
How would you expect the tools to consider the timing relationship
between two clocks divided down from an 825 MHz (~1.2 ns period)
clock?

Maybe I wasn’t clear enough, but the two clocks are related by a known
fraction. They are both derived from the 125 MHz input clock. clk_28 =
125*7/31 and clk_25 = 125/5 and hence clk_28 = 35/31*clk_25. And I
expect the tools to consider the timing relationship because the ISE/
XST/DCM documentation states that the software derives a new PERIOD
for each of the DCM output clocks and determines the clock
relationships between the output clock domains. And that is also what
the timing report in my previous post reflects.
I solve the synchronization problem once at the interface
and never have to worry about it again.
Seems like a good idea.
This is a lot simpler to think about looking at a diagram. Maybe I
need to write this up.
Please do that! I lost you somewhere in between the domains..., but I
would very much like to see how you solve the clock domain crossing.

/B
 
B

Beppe

Why do you need to go in such a complicated pathway when you don't need
to? It has been already suggested a very easy and robust solution that
will avoid any of the problems you mentioned:

I don’t intend to. As I said it was just a side note. And as I also
have said, that solution doesn’t help since I still need to cross
domains. With an enable the CTRL_PROC would be clocked by clk_25, but
the CNT_PROC would still be clocked by clk_28.
That is data_in and byte_received are from a different clock domain and
they should by resync'ed to be used in the clk_25 domain.

If you read the original post you will notice that the clk_25 domain
isn’t used in either of the two processes. data_in and byte_received
are read in the CTRL_PROC, which is clocked by clk_250k and thus they
don't cross domains and they don’t need to be resynchronized. At least
not in the given example.

/B
 
Ad

Advertisements

A

Alessandro Basili

I don’t intend to. As I said it was just a side note. And as I also
have said, that solution doesn’t help since I still need to cross
domains. With an enable the CTRL_PROC would be clocked by clk_25, but
the CNT_PROC would still be clocked by clk_28.

That is the reason why you need to resync.
If you read the original post you will notice that the clk_25 domain
isn’t used in either of the two processes. data_in and byte_received
are read in the CTRL_PROC, which is clocked by clk_250k and thus they
don't cross domains and they don’t need to be resynchronized. At least
not in the given example.

My fault, indeed it seems to me you do not need the clk_250k at all and
can have data_in and byte_received directly in clk_25 domain (800 pulses
per bit).
 
B

Beppe

That is the reason why you need to resync.

Exactly. And the reason why an enable doesn't help. However, an enable
will get rid of the logic generated clk_250k although I haven't been
convinced why it's so bad with a logic generated clock even when it is
put on the low skew global clock line.

My fault, indeed it seems to me you do not need the clk_250k at all and
can have data_in and byte_received directly in clk_25 domain (800 pulses
per bit).

That's right. So in any case I need to use a clock domain crossing
technique unless I rewrite the MIDI UART and clock it with the clk_28.

/B
 
K

KJ

Exactly. And the reason why an enable doesn't help. However, an enable
will get rid of the logic generated clk_250k although I haven't been
convinced why it's so bad with a logic generated clock even when it is
put on the low skew global clock line.

Because of the potential for hold time problems on a signal coming
from the high speed clock domain into the generated clock domain. The
low skew that you are talking about is between different flops clocked
by that same clock. It does not address the skew between the two
clock domains. The timing analysis will report it...but it won't fix
it. While this is true of all timing problems, the solution to this
particular timing problem is to add delays into the data path so that
the minimum data delay is still faster than the clock (plus setup).
Then ask yourself, how do you insert delays into an FPGA design? Do
you want to be adding this delay potentially every time you re-route
the design for some reason?

Plus, when you get right down to it, it will likely take exactly the
same amount of logic to generate the lower speed clock as it would to
generate the clock enable...so ask yourself, other than more work and
potential headaches what do you expect to get by using a generated
clock?

Kevin Jennings
 
B

Beppe

Because of the potential for hold time problems on a signal coming
from the high speed clock domain into the generated clock domain.

But if there’s no data coming from the high speed clock domain into
the generated clock domain I don’t see the problem. That is actually
the case in the given example. The clock domain crossing is between
clk_250k and clk_28 not between clk_250k and clk_25.
Then ask yourself, how do you insert delays into an FPGA design?

Clocking on both positive and negative clock edge...! Ok, I won’t do
that I will use enables.
what do you expect to get by using a generated clock?

Lower power consumption?

/B
 
R

rickman

Thanks for the answers.
[snip]

Don't count on the fact that the design works on your lab bench as
proof that it works in any real sense! You can never prove a design
works by testing it!!! You can only use test to prove that a design
doesn't work. To prove that it works requires that you test all
possible conditions and that's not really possible much less
practical.

I am sorry but I disagree with you on this point. There are "good
practices" that help a lot in guaranteeing the quality of your project.

I never said testing isn't useful. I said that testing can't assure
that something works unless you test every possible condition and that
is not possible in an absolute sense.

Besides, you snipped the OP's comment I was responding to...

"the design seems to be working fine in hardware although I haven’t
made any extensive tests yet."

The problem we are discussing is ***exactly*** the sort of thing you
may not find in testing. The way the OP has constructed the circuit
it may work in 99.99% of the systems he builds. Or it may work 99.99%
of the time in all of the systems. But testing can't validate timing
since you can't control all of the variables.

The only thing testing can really do is to verify that your design
meets your requirements... if your requirements are testable! I've
been trained in quality process development and after seeing it in
action, I realize that much of it is not a better than intelligent
thinking. Just like many of the tools provided in engineering, this
is one that seems to provide benefit when used by the "masses" rather
than by the skilled.

I believe that coding is just part of the story. Having the possibility
to test the design by a different team from the designers one will make
a huge difference.

"a huge difference"... I understand there are lots of ways to improve
testing, but that doesn't change the fundamental limitation of
testing.

To do that a very precise (not necessarily detailed)
documentation is of course mandatory, since the verification team should
not go in the rtl details, or even the timing constraints and place &
route details of the project (the concept behind the design will also
benefit of a well structured documentation).

This is why there are standardized procedures, for avionics, space
applications, military applications (to mention some of them), which go
beyond the vhdl and define a work flow that should be as much
independent as possible from the individual skills of the designers team.

And also limiting the focus only on the coding side, there are a lot of
dos and don'ts that should be followed thoroughly.
Here for instance a good article on common hdl mistakes (and IMHO
misconceptions):

http://www.designabstraction.co.uk/Articles/Common HDL Errors.PDF

I'm not sure what to say about this article. It is actually a bit
shallow in my opinion. But it also contains errors! Much of it is
really just the opinion of the author.

Even though your solution may work, that doesn't mean it is the right
one. I would recommend going through a clock domain crossing technique
as already suggested.
Again, following "good practices" not only help us having better chances
our systems work, it also (and more important) helps spreading the use
of them with invaluable returns to the whole community.

I think that terms like "good practices" are some of the least useful
concepts I've ever seen. First, where are "good practices" defined?
Without a clear, detailed definition of the term, it doesn't
communicate anything. Usually it is used to mean "what I do". It may
be defined within a company, in some limited ways it may be defined
within a sector. But in general this is a term that has little
meaning as used by most people. This is much like recommending to
design "carefully". I can't say how many times I have seen that word
used in engineering without actually saying anything.

I would recommend an alternative to the 50 clocks domains, instead.

What alternative would that be??? Is that different than the solution
I recommended?

Rick
 
Ad

Advertisements

R

rickman

Of course you’re right. “It’s working in hardware” was more of a hint
that it might not be totally doomed.


Maybe I wasn’t clear enough, but the two clocks are related by a known
fraction. They are both derived from the 125 MHz input clock. clk_28 =
125*7/31 and clk_25 = 125/5 and hence clk_28 = 35/31*clk_25. And I
expect the tools to consider the timing relationship because the ISE/
XST/DCM documentation states that the software derives a new PERIOD
for each of the DCM output clocks and determines the clock
relationships between the output clock domains. And that is also what
the timing report in my previous post reflects.


Seems like a good idea.


Please do that! I lost you somewhere in between the domains..., but I
would very much like to see how you solve the clock domain crossing.


I don't have time to draw a diagram, but here is some code. I've had
to edit out a lot of support circuitry which is not related, I hope I
didn't screw this up.

Scfg_Sync : process (SysClk, SysRst) begin
if (SysRst = '1') then
Scfg_SysClk <= '0';
elsif (falling_edge(SysClk)) then
if (Clk_en = '1') then
Scfg_SysClk <= not Scfg_StbLatch; -- Sync across clock domains
end if;
end if;
end process Scfg_Sync;

-- Control register interface
-- Clock interface and synchronize to system clock
CntrlReg : process (Scfg_Str, IF_EN) begin
if (IF_EN = '1') then
Scfg_StbLatch <= '0';
Scfg_StbLatch_D <= '0';
elsif (rising_edge(Scfg_Str)) then
Scfg_StbLatch <= Scfg_SysClk; -- Sync across clock domains
Scfg_StbLatch_D <= Scfg_StbLatch;
end if;
end process CntrlReg;

Scfg_clk_en <= Scfg_StbLatch xor Scfg_StbLatch_D;

Every time the clock enable in the SysClk domain is asserted, the loop
signal Scfg_SysClk toggles generating an edge which is detected by the
concurrent statement at the end. That logic can also be registered to
help with metastability issues since Scfg_StbLatch will go
metastable.

To convey the clock SysClk to the other domain, just remove the if
(Clk_en = '1') and let every rising edge send an transition to the
other domain. The Scfg_Str domain has to be clocked at least as fast
as the edge rate of Scfg_SysClk for an enable or twice as fast for a
clock.

Getting data across just requires that the data be held stable until
it is clocked into the receiving domain. Sometimes this does not
require an interface register at all depending on the particulars of
the interface timing, etc.

Rick
 
B

Beppe

I don't have time to draw a diagram, but here is some code.

That makes it easier. Here’s the XST RTL schematic of the circuit:

http://www.mypicx.com/uploadimg/1078299247_12152010_1.jpg

And a wave diagram:

http://www.mypicx.com/uploadimg/694346392_12152010_2.jpg

Any particular reason for using the negative edge in the Scfg_Sync
process? I used the positive edge. data_in is clocked on the positive
sysclk edge without enable. data_out is clocked on the positive
scfg_str edge when scfg_clk_en is high.

Am I using this in a way you recognize?

/B
 
R

rickman

That makes it easier. Here’s the XST RTL schematic of the circuit:

http://www.mypicx.com/uploadimg/1078299247_12152010_1.jpg

And a wave diagram:

http://www.mypicx.com/uploadimg/694346392_12152010_2.jpg

This is why I hate these machine drawn schematics. The machine has no
clue about the logical flow. Scfg_StbLatch should be in the same line
with the other blocks clearly showing the flow with the feedback loop
back to the other clock domain. The feedback loop is what makes it
work (each side is not armed until the other acknowledges) and the
following logic is just to reconstruct the enable or clock.

Any particular reason for using the negative edge in the Scfg_Sync
process? I used the positive edge. data_in is clocked on the positive
sysclk edge without enable. data_out is clocked on the positive
scfg_str edge when scfg_clk_en is high.

Am I using this in a way you recognize?

Yes, Scfg_Sync was required to use the falling edge in my design as it
is an external interface. This looks exactly as it should look for a
clock enable circuit. Metastability precautions are required for the
signal Scfg_StbLatch. The only other note is to make sure the data is
held stable long enough for it to be registered in the destination
domain. This may require a register in the data path driven by
SysClk. There are a lot of details dependent on the relative clock
speeds.

If you need to convey a clock enable just add that to the Scfg_SysClk
register.

Rick
 
Ad

Advertisements

A

Alessandro Basili

On 12/14/2010 4:56 AM, rickman wrote:
[snip]
I never said testing isn't useful. I said that testing can't assure
that something works unless you test every possible condition and that
is not possible in an absolute sense.

I don't get that. What you call as "every possible condition" is
intended as every possible state of a particular set of logic. If your
logic cannot be described as a well defined number of states then I
agree that testing will never be enough (but in this case I suggest a
rework of the design).
If your states are not controllable (i.e. by an external control signal)
then there's little you can do in testing. If your states are even not
observable then I believe you are "doomed" (as somebody said earlier...).
Besides, you snipped the OP's comment I was responding to...

"the design seems to be working fine in hardware although I haven’t
made any extensive tests yet."

I snipped the OP's comment because didn't add anything that wasn't
already said in your sentence.
The problem we are discussing is ***exactly*** the sort of thing you
may not find in testing. The way the OP has constructed the circuit
it may work in 99.99% of the systems he builds. Or it may work 99.99%
of the time in all of the systems. But testing can't validate timing
since you can't control all of the variables.

This is why the way OP constructed the circuit was suboptimal and that
is why it was suggested not to use a generated clock, but an enable
signal (or even clock the UART with the original 25MHz clock).
The only thing testing can really do is to verify that your design
meets your requirements... if your requirements are testable!

If something cannot be testable, how would you accept those
requirements? And how can than be said the system doesn't work?
according to which requirement violation?
"a huge difference"... I understand there are lots of ways to improve
testing, but that doesn't change the fundamental limitation of
testing.

The fundamental limitation of testing are most probably due to a very
poor description of the device under test. That is why documentation
should be the first step in a work flow, rather then the last one where
the designer tend to leave out all the "unnecessary" details which
eventually lead to misunderstanding. How hard is to test one single
flip-flop? Not much, only because if fully described.
I'm not sure what to say about this article. It is actually a bit
shallow in my opinion. But it also contains errors! Much of it is
really just the opinion of the author.
Could you please post the errors? Since I haven't found them, most
probably your reading was deeper than mine and it would be very helpful
to me.
The author not only gives an opinion, it lays down an approach which is
at a higher level of abstraction than the flops and gates.
I think that terms like "good practices" are some of the least useful
concepts I've ever seen. First, where are "good practices" defined?

In many books, standards, proceedings, articles and you may be lucky
that your company has already defined a set of them.
Without a clear, detailed definition of the term, it doesn't
communicate anything. Usually it is used to mean "what I do". It may
be defined within a company, in some limited ways it may be defined
within a sector. But in general this is a term that has little
meaning as used by most people. This is much like recommending to
design "carefully". I can't say how many times I have seen that word
used in engineering without actually saying anything.

Usually it means "what most of the people do" as opposed of what you
suggested. Of course circumstances and requirements maybe some how very
demanding but an alternative architectural approach will surely have an
higher impact.
What alternative would that be??? Is that different than the solution
I recommended?

As in the OP example, instead of suggesting how to control the timing of
the clk_250k I would recommend not to use it at all (that means one
clock less).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top