Coding style, wait statement, sensitivity list and synthesis.

J

Jim Lewis

Rob,
Interesting, I just investigated this last month :
I personally find the 'multiple edge' feature in 1076.6 extremely confusing, and potentially incorrect.

The example given in 1076.6 is this :
Example 1:

process (reset, clk1, clk2) begin
if (reset) then
Q <= '0' ;
elsif rising_edge(clk1) then
Q <= data1 ;
elsif rising_edge(clk2) then
Q <= data2 ;
end if ;
end

Clearly, no hardware element (that I am aware of) can update its output on multiple rising edges,
so you should get a synthesis error.

Let me help you find a couple pieces of hardware that
need this coding style.

Xilinx register with both rising and falling edges:
http://toolbox.xilinx.com/docsan/xilinx7/books/data/docs/lib/lib0130_116.html

Xilinx dual port memory with separate clocks:
http://www.xilinx.com/ipcenter/catalog/logicore/docs/dp_block_mem.pdf
But 1076.6 now proposes to accept this style, and that we
should ignore the second (clk2) edge.
So, a Flip-flop should be synthesized which triggers on 'clk1' only.

My read on the standard is different from yours.
The standard has the following three statements:
1: "The clock edge conditions shall be mutually exclusive."

If you don't make this assumption, then the first clock
will have higher precedence than the second clock. This
may work for some hardware and may not for others. There
will be a potential RTL and gate simulation mismatch if
both clocks do happen at the same time. The standard
shows a way to handle this using synthesis pragmas.


2: "For each clock edge expression, when the remaining clock
edge expressions are replaced by FALSE in all statements
of the process, the transformed process must fulfill the
conditions of 6.1.3.1 or 6.1.3.2."

Basically this makes the effect of each clock independent of
the others. Make all branches except for the current clock
false and calculate what the current clock does. Repeat
for all clocks and combine their effect.


3: "The signal in the first clock edge expression
(textually) shall be taken as the functional clock."

If there is a precedence relationship in the target hardware,
then the higher precedence clock must be coded first.

So, I would recommend NOT promoting this 1076.6 rule.
Verific will continue to error out on example1. It is really not synthesizable.

I disagree with this. I showed the intended read of
the standard and showed real hardware that would be the
target of this type of code.
Just stick with a single clock per process, since that is supported by every vendor,
prevents any simulation-synthesis mismatch and does not violate any 1076.6 rules.

And if we do this, how do you propose that we code
the Xilinx hardware referenced above?
The standard is there to help you find the way.

If you still think there is an issue with the standard,
please file an issue/bug report against the standard.
You can do this by going to the VASG web page and following
the link for "bugs / enhancement requests":

http://www.eda.org/vasg/

You can also use the above to request an
interpretation of the standard.

Cheers,
Jim Lewis
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

Rob Dekker

Jim Lewis said:
Rob,

Let me help you find a couple pieces of hardware that
need this coding style.

Xilinx register with both rising and falling edges:
http://toolbox.xilinx.com/docsan/xilinx7/books/data/docs/lib/lib0130_116.html

Xilinx dual port memory with separate clocks:
http://www.xilinx.com/ipcenter/catalog/logicore/docs/dp_block_mem.pdf

Well, if there were synthesizable descriptions for these (which there are not),
or 1076.6 would define this Xilinx intended hardware should be synthesized (which is
does not, since it defines that the second clock should be ignored), then we would at
least assume that XST supports this style and create this hardware. But it does not :
ERROR:Xst:827 - dual_edge.vhd line 12: Signal Q cannot be synthesized, bad synchronous description.

I think XST (and all other synthesis tools) are right and 1076.6 is wrong.
So none of the assumptions you are making seemed to be holding.
My read on the standard is different from yours.
The standard has the following three statements:
1: "The clock edge conditions shall be mutually exclusive."

If you don't make this assumption, then the first clock
will have higher precedence than the second clock. This
may work for some hardware and may not for others. There
will be a potential RTL and gate simulation mismatch if
both clocks do happen at the same time. The standard
shows a way to handle this using synthesis pragmas.


2: "For each clock edge expression, when the remaining clock
edge expressions are replaced by FALSE in all statements
of the process, the transformed process must fulfill the
conditions of 6.1.3.1 or 6.1.3.2."

Basically this makes the effect of each clock independent of
the others. Make all branches except for the current clock
false and calculate what the current clock does. Repeat
for all clocks and combine their effect.


3: "The signal in the first clock edge expression
(textually) shall be taken as the functional clock."

If there is a precedence relationship in the target hardware,
then the higher precedence clock must be coded first.

Right, and the other clocks should be ignored if you read the other text :
"The signal in the first clock edge expression (textually) shall be taken as the functional clock".

Which is my point exactly.
I disagree with this. I showed the intended read of
the standard and showed real hardware that would be the
target of this type of code.

I don't think so. The intent was to allow unsynthesizable constructs to be accepted.
If they intended to have the Xilinx hardware synthesized, then they would have said so :
"the synthesis tool should infer a dual-edge sensitive register to be created.."
But there is none of this. Only that we should ignore the second edge.
And if we do this, how do you propose that we code
the Xilinx hardware referenced above?

Only a simulatable model can be written.
And that is what Xilinx intended also (that is why thei made these models instantiatable).
The standard is there to help you find the way.

If you still think there is an issue with the standard,
please file an issue/bug report against the standard.
You can do this by going to the VASG web page and following
the link for "bugs / enhancement requests":

http://www.eda.org/vasg/

You can also use the above to request an
interpretation of the standard.

Thanks for the advice.
 
J

Jim Lewis

Rob,
Well, if there were synthesizable descriptions for these (which there are not),
or 1076.6 would define this Xilinx intended hardware should be synthesized (which is
does not, since it defines that the second clock should be ignored), then we would at
least assume that XST supports this style and create this hardware. But it does not :
ERROR:Xst:827 - dual_edge.vhd line 12: Signal Q cannot be synthesized, bad synchronous description.

I think XST (and all other synthesis tools) are right and 1076.6 is wrong.
So none of the assumptions you are making seemed to be holding.

The intent of the 1076.6 is that it creates a double edge register.
I understand this because I was part of the committee and attended
the meetings. Unfortunately now we have obviously confused at least
one of the implementers and this is a situation we need to correct.

Right, and the other clocks should be ignored if you read the other text :
"The signal in the first clock edge expression (textually) shall be taken as the functional clock".

Which is my point exactly.

First to understand what is being said here, you have to
re-read the previous points and understand that each clock
contributes to the hardware creation.

As I read this statement, I can see why it troubles it,
however, we did not get any corrective action relative to
it during balloting. It is hard to identify these issues
myself as I know the intent, so it is not confusing to me.

The statement that troubles you refers to ASIC hardware where
there are two clocks: one is a functional clock and one is a
scan clock. In this case, there is a priority relationship
in the hardware.

The assumptions in 1076.6-2004 about multiple edge register
coding states that the clocks are mutually exclusive.
This governs the coding style. Hence what the statement is
intended to say is that if the code is mapped to hardware
that has precedence in it, give the first clock in the code
the highest precedence in the implementation. By requiring
something specific, it gives the user the most control over
the resulting implementation.

For the case where the hardware implementation has mutually
exclusive clocks, this statement does not apply.
Only a simulatable model can be written.
And that is what Xilinx intended also (that is why thei made these models instantiatable).
I think I remember seeing that Xilinx had a coding
style for this using shared variables.

Instantiation and/or non-portable code is a great solution
from a FPGA-Vendor perspective as once you use this part,
you are stuck with them. This is not so good for users.

Is instantation your best proposal?

I would suggest that you understand the coding style
put forward by 1076.6-2004 as a multi-edge storage
device and lets get the wording you object to fixed so
all can understand the intent of the standard.

Although this is a non-offical interpretation of the
standard, it is unlikely you will hear anything in
official interpretation.

Best Regards,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

Rob Dekker

Hi Jim, Happy New Year !

A few more notes below.

Rob

Jim Lewis said:
Rob,

The intent of the 1076.6 is that it creates a double edge register.
I understand this because I was part of the committee and attended
the meetings.

I already thought your name looked familiar. We might have met at
one of the meetings. I was also part of the 1076.6 committee, at least
in the early days, when we were still talking about the numeric_std/bit packages.
I even wrote the original (magnitude/equal) comparator functions
for these packages, but that was about the last I did for 1076.6.
Unfortunately now we have obviously confused at least
one of the implementers and this is a situation we need to correct.

It that was the real intent, then I think you confused more than one
implementer. Or they decided collectively not to implement the
double-edge hardware feature to was that 1076.6 recommended it.
I don't know of any synthesis tool that accepts this style and creates
a double-edge sensitive register.
First to understand what is being said here, you have to
re-read the previous points and understand that each clock
contributes to the hardware creation.

Additional confusion is in the note(2) :

"The determination of the functional clock is made on a process-by-process basis;
the intended functional clock has to be coded first in each process."

There is hardly any other way to interpret that than to assume that
there is only one clock per process, and also that is that clock
is the first one in any (mutually exclusive) if conditions.
As I read this statement, I can see why it troubles it,
however, we did not get any corrective action relative to
it during balloting. It is hard to identify these issues
myself as I know the intent, so it is not confusing to me.

The statement that troubles you refers to ASIC hardware where
there are two clocks: one is a functional clock and one is a
scan clock. In this case, there is a priority relationship
in the hardware.

I vaguely remember that in 1076.6 early days, we talked about
modeling the IBM style separate master-slave register hardware,
which also allowed some pretty exotic scan/functional clock designs.
But I do not remember any talk about double-edge sensitive registers.
The assumptions in 1076.6-2004 about multiple edge register
coding states that the clocks are mutually exclusive.
This governs the coding style. Hence what the statement is
intended to say is that if the code is mapped to hardware
that has precedence in it, give the first clock in the code
the highest precedence in the implementation. By requiring
something specific, it gives the user the most control over
the resulting implementation.

Understood. I think the text fucusses way too much on this assumption
(of mutual exclusive clocks) and misses the point : that double-edge
sensitive registers are allowed to be synthesized.

Now there is still major confusion with the 1076.6 text regarding
this coding style :

process (reset, clk1, clk2) begin
if (reset) then
Q1 <= '0' ;
Q2 <= '0' ;
elsif rising_edge(clk1) then
Q1 <= data1 ;
elsif rising_edge(clk2) then
Q2 <= data2 ;
end if ;
end


Where does it state that this is a process with two clocks, which should
synthesize to two separate (single-edge) DFFs ?
For the case where the hardware implementation has mutually
exclusive clocks, this statement does not apply

The 'mutually exclusiveness' of the clocks is a minor issue
The text I miss very much is :

"Each assigned signal in a process should be clocked to at one and only edge to be synthesized to a regular DFF".

possibly extended with :

If a signal is sensitive to multiple edges, a multiple-edge hardware element should be synthesized.
If a signal is sensitive to no edges (only to combinational signal events), then no edge-sensitive hardware
should be synthesized.

I think I remember seeing that Xilinx had a coding
style for this using shared variables.

Do you have an example of that that XST accepts ?
And does this match the style proposed in 1076.6 ?
Instantiation and/or non-portable code is a great solution
from a FPGA-Vendor perspective as once you use this part,
you are stuck with them. This is not so good for users.

Is instantation your best proposal?

For these very rare dual-edge sensitive register, yes, I think instantiation
is probably the best (safest) solution. Couple of reasons :

(1) Dual-(or multi-)edge sensitive register elements is not common practice in hardware design.
Many technologies will NOT have general purpose multi-edge sensitive registers.
So writing HDL in such form will already restrict the target technology you can map too.

(2) Many RTL designers are novice. Opening them up to dual-edge sensitive hardware
design is like opening a can of worms. If you accept HDL coding style that models
exotic hardware behavior, many RTL designs will start to contain it. And this makes
HDL coding technology dependent (see reason (1)) and in general makes RTL models
harder to understand, and possibly riskier: Many company RTL design rules include
single-edge sensitive design only. How can we protect such rules if 1076.6 opens the
lid of the vast number of designs possible with multiple edges ?

(3) So much for synthesis creating a dual/multi-edge hardware primitive.
How about timing analyzers, equivalence-checkers, model-checkers, test pattern generators,
hardware accellerators, and a whole spectrum of other tools.
Are they supposed to all of a sudden deal with multi-edge sensitive hardware elements ?
I do not think the EDA market is ready for that.

I would suggest that you understand the coding style
put forward by 1076.6-2004 as a multi-edge storage
device and lets get the wording you object to fixed so
all can understand the intent of the standard.

I would suggest to clarify that there is only one edge allowed per assigned signal :
(1) Each assigned signal in a process should be clocked to one and only edge to be synthesized to a regular DFF.
(2) It is an error if a signal depends on two independent clock edges.

Anything short of that is opening up a can of worms.

My 2 cts.
Although this is a non-offical interpretation of the
standard, it is unlikely you will hear anything in
official interpretation.

I know. It takes a long time to get commitee approval.
But is takes probably more efford to convince implementers and the design community
if you try to standardize something that has the risk of creating more problems that it solves.
 
M

Marcus Harnisch

Hi Rob,

Rob Dekker said:
Now there is still major confusion with the 1076.6 text regarding
this coding style :

process (reset, clk1, clk2) begin
if (reset) then
Q1 <= '0' ;
Q2 <= '0' ;
elsif rising_edge(clk1) then
Q1 <= data1 ;
elsif rising_edge(clk2) then
Q2 <= data2 ;
end if ;
end


Where does it state that this is a process with two clocks, which should
synthesize to two separate (single-edge) DFFs ?

I'd be interested in what that would be expected to synthesize to. Q2
assignment depends on the absence of a rising edge on clk1.

-- Marcus
 
J

Jim Lewis

Rob,
Happy New Year.
If that was the real intent, then I think you confused more than one
implementer. Or they decided collectively not to implement the
double-edge hardware feature to was that 1076.6 recommended it.
I don't know of any synthesis tool that accepts this style and creates
a double-edge sensitive register.

Not sure which, but I do agree where there is lack of clarity, all
would benefit from cleaning it up. What we need to do next is
write a summary of the issues and perhaps suggested changes/additions
and then post it to the SIWG reflector.

Historically support of standards has always been a fuzzy thing.
On one side, why should a vendor spend money to implement a
feature if users are not demanding it?
On the other, why would a user consider using a coding style if
all tools they use or possibly use don't support it?
And another, there is a standard for coding styles?
And yet another, is it in a vendor's business interest to support
portable coding styles? Doesn't that make it easy to switch to
use a different FPGA or synthesis vendor?

Add to that the confusion of finding a standard on IEEE's
webpage. Took me a couple of tries to find it because I
went to the subscription page rather than the standards
page. I have the advantage in that I know it is there.

I vaguely remember that in 1076.6 early days, we talked about
modeling the IBM style separate master-slave register hardware,
which also allowed some pretty exotic scan/functional clock designs.

I think they solved this with their scan insertion tool.
But I do not remember any talk about double-edge sensitive registers.
It is only in 1076.6-2004 and not in 1076.6-1999

1076.6-1999 was template based.

When we started 1076.6-2004 we realized it would be limiting
if we continued in this methodology. It would be much easier
to let the hardware semantics specify what gets created rather
than a template. With templates were were bound to accidentally
leave something out. Hence, what we ended up were are a set of
algorithmic rules rather than templates.

This is good in that it enables many good coding styles.
It also enables some bad coding styles.
The purpose of the standard is to elaborate on what is
and is not synthesizable so people can create compliant
code that will work on compliant tools.

I think the job of a synthesis tool is to create
semantically correct hardware. Due to the diversity
of design methodologies, I think it would be a mistake
to make a synthesis tool a methodology cop unless it
is configurable (like a lint tool is configurable).
Now there is still major confusion with the 1076.6 text regarding
this coding style :

process (reset, clk1, clk2) begin
if (reset) then
Q1 <= '0' ;
Q2 <= '0' ;
elsif rising_edge(clk1) then
Q1 <= data1 ;
elsif rising_edge(clk2) then
Q2 <= data2 ;
end if ;
end

Although I would strongly discourage this coding style
(if I am reviewing your code, you will have to fix it),
I suspect that this is permitted by 1076.6-2004.
I think the mutual exclusion/independence of the clocks
allows me to re-write this as follows.

process (reset, clk1, clk2)
begin
if rising_edge(clk2) then
Q2 <= data2 ;
end if ;
if rising_edge(clk1) then
Q1 <= data1 ;
end if ;
if (reset) then
Q1 <= '0' ;
Q2 <= '0' ;
end if ;
end process ;

As a result, I believe this creates two separate registers
each clocked by a single clock: data1 clocked into register Q1
by clk1 and data2 clocked into Q1 by clk2.

In a design review, I require all multiple clock and clock
domain crossings to be reviewed. As coded, this process
has multiple clocks and would be required to reviewed.
It would not pass and would be required to be fixed.
I would also expect this code to be flagged as a multiple
clock situation by a properly configured lint tool.

For these very rare dual-edge sensitive register, yes, I think instantiation
is probably the best (safest) solution. Couple of reasons :

... snip ...

I would suggest to clarify that there is only one edge allowed per assigned signal :
(1) Each assigned signal in a process should be clocked to one and only edge to be synthesized to a regular DFF.
(2) It is an error if a signal depends on two independent clock edges.

What you suggest offers minimal protection to new
designers and inhibits advanced designers from coding
the hardware they need.

New designers need design rules and perhaps lint tools to
address the range of bad things they can do. Eliminating
this coding style does not solve the the issues with multiple
clocks. Every clock domain crossing must be analyzed and
reviewed. Multiple clock designs are a reality. I hope the
tools out there are dealing with them correctly.

If you really want to be paranoid about "safe" and new engineers,
what about:
gating clocks,
clocking registers with data signals,
mixing asynchronous and synchronous resets in the same clock domain
forgetting to reset a register that needs reset
accidentally coding two registers where only one is needed
. . .

The list could go on and on. I think a synthesis tool needs to
create semantically correct hardware based on some rules and
assumptions. You can't build in the lint tool into the synthesis
tool unless it is configurable. For example, for low power design,
clock gating is necessary, however, random clock gate insertion
can cause enough clock skew to break a design. So if I was not
doing a low power design (and I was worried) I would have a
lint tool checking for clock gates.

Do you have an example of that that XST accepts ?
I would have to look it up in the XST coding style docs.
I have a print of it somewhere, but I cannot find it right
now. If I remember correctly it uses separate processes
and global variables - yikes!
And does this match the style proposed in 1076.6 ?
No. 1076.6-2004 is far simpler.


Cheers,
Jim

BTW, there is a significant work being done on VHDL.
It is being done through a teaming of the Accellera VHDL
TC and IEEE VASG. Currently this is targeted for to be
an Accellera standard revision in July, 2006 and become
an IEEE standard revision sometime later. Note it is
possible that Accellera will do several revisions before
releasing it for IEEE balloting.

See www.accellera.org

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
D

Dave Higton

In message <[email protected]>
Rob Dekker said:
For these very rare dual-edge sensitive register, yes, I think
instantiation is probably the best (safest) solution. Couple of reasons :

Please, one of the aims of VHDL is to create platform-neutral designs.
(1) Dual-(or multi-)edge sensitive register elements is not common practice
in hardware design. Many technologies will NOT have general purpose
multi-edge sensitive registers. So writing HDL in such form will already
restrict the target technology you can map too.

I demonstrated a few posts back that multi-edge-sensitive register
"elements" can be synthesised from common elements like D type FFs
and S-R FFs. Thus you can design them in almost any target device.
The limitation is the synthesis tools, which, so far, have not been
able to do this synthesis. Contrast that with synthesis of complex
state machines, for example.
(2) Many RTL designers are novice. Opening them up to dual-edge sensitive
hardware design is like opening a can of worms. If you accept HDL coding
style that models exotic hardware behavior, many RTL designs will start to
contain it. And this makes HDL coding technology dependent (see reason (1))
and in general makes RTL models harder to understand, and possibly riskier:
Many company RTL design rules include single-edge sensitive design only.
How can we protect such rules if 1076.6 opens the lid of the vast number of
designs possible with multiple edges ?

DDR is very common nowadays and becoming increasingly so. We're all
going to have to get used to it - if we aren't already.

Novices make all sorts of mistakes. (Mostly they learn from them!)
Mistakes can be made with state machines, counters, combinatorial
logic - anything, basically. If you remove everything that a novice
can get wrong, there will be nothing left - then we can all go home.

I object to being told that I can't use a technology because someone
else might make a mistake using it.

Dave
 
A

Andy

I can name that tune in... (for those of you old enough to recognize
that line!)

Example 1 can be implemented using two d flops and three two-input xor
gates, and the output is glitch free if minimum timing between the two
clocks is observed (even verifiable with STA). Thus it can be produced
with almost any standard hardware.

process (reset, clk1)
begin
if reset then
q1 <= '0';
elsif rising_edge(clk1) then
q1 <= data1 xor q2;
end if;
end process;

process (reset, clk2)
begin
if reset then
q2 <= '0';
elsif rising_edge(clk2) then
q2 <= data2 xor q1;
end if;
end process;

q <= q1 xor q2; -- decode output

Essentially, the "state" of the DDR "flop" is encoded in two bits. The
value is '1' if the two bits differ, and is '0' if the two bits are the
same. Either bit can determine the next value based on the input and
the other bit.

It would be nice if this were synthesized automatically from a two
clock process description, so that integers, enumerated types, etc.
could also be used.

For a really wild exercise, this can even be expanded to n clocks!

Alas, I cannot take credit for this design; I saw it here on c.l.v a
while back...

Andy
 
R

Rob Dekker

Marcus Harnisch said:
Hi Rob,



I'd be interested in what that would be expected to synthesize to. Q2
assignment depends on the absence of a rising edge on clk1.

Currently, we (Verific provides HDL front-end for some 40 EDA tools)
still error out on this during RTL elaboration. Just to be safe.

But if anything, I would synthesize this to two single-edge DFFs, with separate clocks.
There is only the assumption that clk1 and clk2 are never rising at the SAME delta-time.
Other than that, simulator and synthesis behavior are the same.

But in the context of this thread, we used this example to find out what
the RTL synthesis standard 1076.6 says we should do.
From the 1076.6-2004 text, I assumed they want us to ignore the second clock
(which would lead to incorrect behavior).

Jim just wrote that the intent of 1076.6 was to indeed allow this and create
indeed the two separate DFFs.

Rob
 
R

Rob Dekker

Jim Lewis said:
Rob,
Happy New Year.


Not sure which, but I do agree where there is lack of clarity, all
would benefit from cleaning it up. What we need to do next is
write a summary of the issues and perhaps suggested changes/additions
and then post it to the SIWG reflector.

Historically support of standards has always been a fuzzy thing.
On one side, why should a vendor spend money to implement a
feature if users are not demanding it?
On the other, why would a user consider using a coding style if
all tools they use or possibly use don't support it?
And another, there is a standard for coding styles?
And yet another, is it in a vendor's business interest to support
portable coding styles? Doesn't that make it easy to switch to
use a different FPGA or synthesis vendor?

Well, after 15 years doing HDL synthesis implementation, I can tell you some stories....
It's a battlefield out there (at least it used to be).

But seriously, this is how it works :
We typically want to accept as much of language features as possible,
as long as we can guarantee functional equivalence between synthesis and simulation.
That makes my customers happy (they can write in their own style)
and reduces the number of bug and enhancement reports, and gives
competitors less of a chance to code-up examples that do not run
on my tools. Thus all that makes my life easier too.

One thing we (implementers) all have seemed to agree on is that the
hardware elements we synthesize have one DFF style : the one with
a single-edge.
Add to that the confusion of finding a standard on IEEE's
webpage. Took me a couple of tries to find it because I
went to the subscription page rather than the standards
page. I have the advantage in that I know it is there.

I totally agree. 1076.6 should be freely available and a URL click away.
I think they solved this with their scan insertion tool.

It is only in 1076.6-2004 and not in 1076.6-1999

1076.6-1999 was template based.

When we started 1076.6-2004 we realized it would be limiting
if we continued in this methodology. It would be much easier
to let the hardware semantics specify what gets created rather
than a template. With templates were were bound to accidentally
leave something out. Hence, what we ended up were are a set of
algorithmic rules rather than templates.

This is good in that it enables many good coding styles.
It also enables some bad coding styles.
The purpose of the standard is to elaborate on what is
and is not synthesizable so people can create compliant
code that will work on compliant tools.

I think the job of a synthesis tool is to create
semantically correct hardware. Due to the diversity
of design methodologies, I think it would be a mistake
to make a synthesis tool a methodology cop unless it
is configurable (like a lint tool is configurable).

I think it is a great thing that you focused (in 1076.6-2004) more
on the 'algorithm' than on the style template.
Implementers do not want to be a methodology cop.
See my story above : they just want to support as much of the language
features as possible (within the limitations of the hardware that is synthesized),
because that makes their life easier.

But, purely anecdotal, let me give you one of our 'open' bug-reports.
There is this guy who wants us to synthesize a flip-flop from this :

subtype TWOBIT is a std_logic_vector(0 to 1) ;

process(CP, Q, D)
begin
case TWOBIT'(CP'last_value & CP) is
when "01" => Q <= D;
when others => Q <= Q;
end case;
end process;

It behaves as a flip-flop !
Now, 1076.6 or not, what do we do with this customer request ?
Although I would strongly discourage this coding style
(if I am reviewing your code, you will have to fix it),
I suspect that this is permitted by 1076.6-2004.
I think the mutual exclusion/independence of the clocks
allows me to re-write this as follows.

process (reset, clk1, clk2)
begin
if rising_edge(clk2) then
Q2 <= data2 ;
end if ;
if rising_edge(clk1) then
Q1 <= data1 ;
end if ;
if (reset) then
Q1 <= '0' ;
Q2 <= '0' ;
end if ;
end process ;

As a result, I believe this creates two separate registers
each clocked by a single clock: data1 clocked into register Q1
by clk1 and data2 clocked into Q1 by clk2.

In a design review, I require all multiple clock and clock
domain crossings to be reviewed. As coded, this process
has multiple clocks and would be required to reviewed.
It would not pass and would be required to be fixed.
I would also expect this code to be flagged as a multiple
clock situation by a properly configured lint tool.

Interesting.
Given that (you would seriously discourage the preceding example style),
what did you want us to synthesize for this (following) again, and does this
pass through the 'design review' phase ?

process (reset, clk1, clk2) begin
if (reset) then
Q <= '0' ;
elsif rising_edge(clk1) then
Q <= data1 ;
elsif rising_edge(clk2) then
Q <= data2 ;
end if ;
end

What you suggest offers minimal protection to new
designers and inhibits advanced designers from coding
the hardware they need.

New designers need design rules and perhaps lint tools to
address the range of bad things they can do. Eliminating
this coding style does not solve the the issues with multiple
clocks. Every clock domain crossing must be analyzed and
reviewed. Multiple clock designs are a reality. I hope the
tools out there are dealing with them correctly.

Multiple clocks OK. But on the same signal ?
If you really want to be paranoid about "safe" and new engineers,
what about:
gating clocks,
clocking registers with data signals,
mixing asynchronous and synchronous resets in the same clock domain
forgetting to reset a register that needs reset
accidentally coding two registers where only one is needed
. . .

The list could go on and on. I think a synthesis tool needs to
create semantically correct hardware based on some rules and
assumptions. You can't build in the lint tool into the synthesis
tool unless it is configurable. For example, for low power design,
clock gating is necessary, however, random clock gate insertion
can cause enough clock skew to break a design. So if I was not
doing a low power design (and I was worried) I would have a
lint tool checking for clock gates.

Mmm. I think this (multi-edge register) issue is still different than other design checks.
The FUNCTION of the design cannot be guaranteed to stay the same
(through synthesis) if we do not have hardware elements that are sensitive to multiple edges.
That is why synthesis tools error out.

Now, Dave Higton came up with this creative way to model dual-edge registers with standard primitives.
Is that what 1076.6 wants us to synthesize ?

Alternatively, we could issue a warning and ignore one clock or the other.
But personally I find that dangerous for beginners (since they tend to ignore warnings),
and it does not help advanced designers either (since they still get a single-edge flip-flop).
 
R

Rob Dekker

Dave Higton said:
In message <[email protected]>


Please, one of the aims of VHDL is to create platform-neutral designs.


I demonstrated a few posts back that multi-edge-sensitive register
"elements" can be synthesised from common elements like D type FFs
and S-R FFs. Thus you can design them in almost any target device.
The limitation is the synthesis tools, which, so far, have not been
able to do this synthesis. Contrast that with synthesis of complex
state machines, for example.


DDR is very common nowadays and becoming increasingly so. We're all
going to have to get used to it - if we aren't already.

OK. You have my interest. Tell me about Double Data Rate design !

Does it use both edges of the same clock ? or two separate clock lines that are fixed-phase-shifted ?
How would you write a DDR design in VHDL for simulation ?
How do you get one through a synthesis tool right now ?
Novices make all sorts of mistakes. (Mostly they learn from them!)
Mistakes can be made with state machines, counters, combinatorial
logic - anything, basically. If you remove everything that a novice
can get wrong, there will be nothing left - then we can all go home.

I object to being told that I can't use a technology because someone
else might make a mistake using it.

It is not like that. Sorry if I gave you that impression.

As I explained to Jim in a side-thread :
I think this (multi-edge register) issue is still different than other design 'mistakes'.

A mistake in a state machine or combinational logic (if accepted by the synthesis tool)
would show up the same way in the RTL simulation as it does in the synthesized netlist.
The RTL still behaves the same as the netlist implementation, abeit not what the designer 'wanted'.
Synthesis does not try to guess what you want. It just does what you wrote in VHDL.

But if we do not have hardware elements that are sensitive to multiple edges,
synthesis cannot guarantee functional equivalence synthesizing a simulation model that
depends on multiple edges, and thus has to error out.

If there is a good understanding in the design community about how to implement
multi-edge dependent registers, then I am open to synthesize it.
 
J

Jerry Coffin

Rob Dekker wrote:

[ ... ]
OK. You have my interest. Tell me about Double Data Rate design !

Does it use both edges of the same clock ? or two separate clock lines that are fixed-phase-shifted ?

That depends. Just for one obvious example, DDR2 SDRAM defines both DQS
and DQS# signals, but makes use of the DQS# signal optional, so a
design might use both rising and falling edges of DQS, or it might use
a single edge each of DQS and DQS# (oh, I should add that the DDR2
standard calls them DQS and /DQS).

Micron has some applicable information at:

http://download.micron.com/pdf/technotes/ddr2/TN4711.pdf
How would you write a DDR design in VHDL for simulation ?

I doubt they're synthesizable, but most of the usual DRAM manufacturers
have simulation models available for free download. I haven't looked
through them to see exactly how they deal with the DQS and DQS# lines
though. Hynix has models for various sizes here:

http://www.hynix.com/eng/02_products/08_technical/02_06_03.jsp

I've usually gotten models from Micron in the past, but they don't have
VHDL models available for their current parts (at least any I've looked
at) -- though if you want Verilog, IBIS or HSpice models, you can get
them, such as here:

http://www.micron.com/products/dram/ddr2sdram/part.aspx?part=MT47H256M4BT-5E

This is for a 1 Gb part, but I believe the strobe logic should be
constant across sizes, widths, etc.
 
J

Jim Lewis

Rob,
One thing we (implementers) all have seemed to agree on is that the
hardware elements we synthesize have one DFF style : the one with
a single-edge.
Well then ya-all just need to get with it.

I totally agree. 1076.6 should be freely available and a URL click away.

I was saying easy to find. I didn't say free.
Someone needs to fund some part of IEEE standards.
Although IEEE includes standards in their core values,
they do not fund standards in any way. Caution, this is
one of my hot buttons - in the US they fund IEEE USA (a
lobbying organization) but they don't fund standards.

But, purely anecdotal, let me give you one of our 'open' bug-reports.
There is this guy who wants us to synthesize a flip-flop from this :

subtype TWOBIT is a std_logic_vector(0 to 1) ;

process(CP, Q, D)
begin
case TWOBIT'(CP'last_value & CP) is
when "01" => Q <= D;
when others => Q <= Q;
end case;
end process;

It behaves as a flip-flop !
Now, 1076.6 or not, what do we do with this customer request ?

You should hire me as a consultant. :)
The simulation semantics say it is a latch. D is on
the sensitivity list. If D changes and CP is 1, then
CP'last_value is 0 and Q gets updated. Most RTL simulations
will not notice the difference between a latch and a
register, however, in most cases latches are bad for
static timing analysis.

What if you remove D from the senstivity list above?
The following by simulation semantics is a register.
process (Clk)
begin
if (Clk = '1') then
Q <= D ;
end if ;
end process ;

1076.6-1999 was silent on what to do with this.

In 1076.6-2004 it is an error and shall not produce hardware.
This happens since, 1076.6-2004 requires all register coding
styles to have edge semantics within the body of the process.
1076.6-2004 also requires all latch and combinational
logic code to have a complete sensitivity list.
Since the above example does not have edge semantics it
cannot be a register and since it does not have a complete
sensitivity list, it cannot be a latch or combinational logic,
and, hence, it is an error.

Error and no logic is the right answer since some synthesis
tools produce registers for this code and some produce latches.

I suggest that you close your issue by explaining the above
and citing 1076.6-2004.

Interesting.
Given that (you would seriously discourage the preceding example style),
what did you want us to synthesize for this (following) again, and does this
pass through the 'design review' phase ?

process (reset, clk1, clk2) begin
if (reset) then
Q <= '0' ;
elsif rising_edge(clk1) then
Q <= data1 ;
elsif rising_edge(clk2) then
Q <= data2 ;
end if ;
end process ;

Multiple clocks targeting a single register are a necessity.
It would get reviewed to make sure that it was a correct
usage of multiple clocks.

Multiple clocks OK. But on the same signal ?
Methodology wise, multiple clocks are only ok
when they target the same signal.
Mmm. I think this (multi-edge register) issue is still different than other design checks.
The FUNCTION of the design cannot be guaranteed to stay the same
(through synthesis) if we do not have hardware elements that are sensitive to multiple edges.
That is why synthesis tools error out.

If the hardware does not exist, error out.

This is consistent with the 1076.6-2004 interpretation
of sensitivity lists. Have you considered the true
hardware implication of signals missing from the sensitivity
list?

Now, Dave Higton came up with this creative way to model dual-edge registers with standard primitives.
Is that what 1076.6 wants us to synthesize ?
Alternatively, we could issue a warning and ignore one clock or the other.
But personally I find that dangerous for beginners (since they tend to ignore warnings),
and it does not help advanced designers either (since they still get a single-edge flip-flop).

1076.6 does not specify the implementation, but
as I suggested above, I think you should error out
and not produce hardware.

Designers need to be aware of technology specific
code and provide an alternate architecture when the
current code does not have a correct implementation.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
J

Jim Lewis

Rob
As I explained to Jim in a side-thread :
I think this (multi-edge register) issue is still different than other design 'mistakes'.

A mistake in a state machine or combinational logic (if accepted by the synthesis tool)
would show up the same way in the RTL simulation as it does in the synthesized netlist.
The RTL still behaves the same as the netlist implementation, abeit not what the designer 'wanted'.
Synthesis does not try to guess what you want. It just does what you wrote in VHDL.

I respectfully disagree with your claim above.

One of the most common errors in RTL design is to leave
a signal off a sensitivity list. Have you considered
the true hardware implication of an incomplete
sensitivity list? I saw a great analysis in a paper
by Egbert Molenkamp and Gerhard E. Mekenkamp from VIUF 1997
titled, "Processes with 'incomplete' sensitivity lists
and their synthesis aspects." Anyway the real hardware is
scary and contains one or more registers. If you need a
copy you should be able to find Egbert on the net.

The most common synthesis tool result is to treat the
sensitivity list as if it were complete and generate
the hardware and issue a warning. BTW, I agree with you
that warnings are bad since many users overlook them.

1076.6-1999 is silent on incomplete sensitivity lists.
1076.6-2004 says incomplete sensitivity lists are an
error and no hardware should be produced.

This is a much more likely beginner mistake than multiple
clock edges. The resulting hardware is at least as incorrect
as anything you could produce for multiple clock edges.

But if we do not have hardware elements that are sensitive to multiple edges,
synthesis cannot guarantee functional equivalence synthesizing a simulation model that
depends on multiple edges, and thus has to error out.

If there is a good understanding in the design community about how to implement
multi-edge dependent registers, then I am open to synthesize it.

If there is appropriate hardware in the target technology, map it,
and if not, error out and don't produce any hardware. I just posted
more on this in my response in the other thread.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
R

Rob Dekker

Jim Lewis said:
Rob,
Well then ya-all just need to get with it.

See below: So it is a 'target technology' issue, and anyone using it will
be writing technology-dependent HDL code.
At least with technology-specific instantiation you know exactly what you get...
I was saying easy to find. I didn't say free.
Someone needs to fund some part of IEEE standards.
Although IEEE includes standards in their core values,
they do not fund standards in any way. Caution, this is
one of my hot buttons - in the US they fund IEEE USA (a
lobbying organization) but they don't fund standards.

We should drink a beer over this some day..
You should hire me as a consultant. :)
The simulation semantics say it is a latch. D is on
the sensitivity list. If D changes and CP is 1, then
CP'last_value is 0 and Q gets updated. Most RTL simulations
will not notice the difference between a latch and a
register, however, in most cases latches are bad for
static timing analysis.

Lo and behold !
I will run some more simulations, but I think you are right.
It should be a latch... and .... we currently synthesize a latch for it too !
Thanks !!
What if you remove D from the senstivity list above?
The following by simulation semantics is a register.
process (Clk)
begin
if (Clk = '1') then
Q <= D ;
end if ;
end process ;

The only hardware that will be correct (without sens-list warnings) is a flip-flop.
1076.6-1999 was silent on what to do with this.

In 1076.6-2004 it is an error and shall not produce hardware.
This happens since, 1076.6-2004 requires all register coding
styles to have edge semantics within the body of the process.
1076.6-2004 also requires all latch and combinational
logic code to have a complete sensitivity list.
Since the above example does not have edge semantics it
cannot be a register and since it does not have a complete
sensitivity list, it cannot be a latch or combinational logic,
and, hence, it is an error.

Seems a bit harch to error out, considering that a correct
implementation is possible (with a flip-flop).

I thought we should not be a 'methodology cop' ?

Sorry, but I cannot change this to an error. Customers will kill me.
Error and no logic is the right answer since some synthesis
tools produce registers for this code and some produce latches.

I know what you mean.
I suggest that you close your issue by explaining the above
and citing 1076.6-2004.

Thanks for the tip.
[...]
Mmm. I think this (multi-edge register) issue is still different than other design checks.
The FUNCTION of the design cannot be guaranteed to stay the same
(through synthesis) if we do not have hardware elements that are sensitive to multiple edges.
That is why synthesis tools error out.

If the hardware does not exist, error out.

So the HDL would be target-technology dependent ?
Runs if you map to one technology, but not is run to another ?

Oh, one other thing : which ASIC or FPGA technology HAS general purpose
dual-edge sensitive registers in their library ? I mean separate cells, not
special-purpose registers that are embedded inside some memory or so ?
This is consistent with the 1076.6-2004 interpretation
of sensitivity lists. Have you considered the true
hardware implication of signals missing from the sensitivity
list?

Yes. I know all about that.
I used to error out (rather than warn) about missing signals on sens list.
But overwelming customer complaints pushed me to the warning.
I will not change it back to an error any more...
1076.6 does not specify the implementation, but
as I suggested above, I think you should error out
and not produce hardware.

Designers need to be aware of technology specific
code and provide an alternate architecture when the
current code does not have a correct implementation.

I really strongly disagree with you here.

If you include this as a RTL coding style, then how is a designer supposed to
know that it is technology dependent rule ?
It may work for one technology, but not for another.
I think this contracts everything about the purpose of defining RTL coding rules.

Otherwize, we have gained nothing over technology specific instantiations....

I'm sorry Jim, you did not convice me.
 
R

Rob Dekker

Jim Lewis said:
Rob

I respectfully disagree with your claim above.

One of the most common errors in RTL design is to leave
a signal off a sensitivity list. Have you considered
the true hardware implication of an incomplete
sensitivity list? I saw a great analysis in a paper
by Egbert Molenkamp and Gerhard E. Mekenkamp from VIUF 1997
titled, "Processes with 'incomplete' sensitivity lists
and their synthesis aspects." Anyway the real hardware is
scary and contains one or more registers. If you need a
copy you should be able to find Egbert on the net.

The most common synthesis tool result is to treat the
sensitivity list as if it were complete and generate
the hardware and issue a warning. BTW, I agree with you
that warnings are bad since many users overlook them.

1076.6-1999 is silent on incomplete sensitivity lists.
1076.6-2004 says incomplete sensitivity lists are an
error and no hardware should be produced.

As I mentioned in the side-thread:
I used to error (12 years age) out (rather than warn) about missing signals on sens list.
But overwelming customer complaints pushed me to the warning.
I think on this issue, the cat is out of the bag. We cannot change it any more.

On the plus-side, Verific has a feature where any message can be up- or down-graded.
Errors can be turned to warnings or info messages, warnings to errors, or suppressed etc.
That means that my customers (EDA compaties and other EDA tool developers)
now carry the burden to make the decision. Or they can export the feature
to their customers, so designers can decide themselves to make this an error,
depending on their in-house HDL design rules.
Now THAT is user friendly, right :eek:).
This is a much more likely beginner mistake than multiple
clock edges. The resulting hardware is at least as incorrect
as anything you could produce for multiple clock edges.

True. But so are other 'controversial' issues :

Take initialization values on signals/variables. How should these be treated ?
Or the absense thereof (integer gets implicitly initialized to integer'low, and that
might affect the behavior of the model, since in netlists we simulate with 'X' and 'U').

Actually, I did not find a good overview in 1076.6 on initialization values, and
which ones should be synthesized and which ones should not. For example, if
a signal is never assigned, and has an initial value, I synthesize that initial value and
put it on the signal. Other tools don't do that (leave the signal dangling or tie the nets to
ground or so).

Or synthesis of 'L' and 'H' values, and how to interpret these. 1076.6 has a decent rule
for that (interpret as '0' and '1'), but reality is that they are not really 'synthesizable'.
After all, the target hardware does not have 'L' and 'H' values.
Pullup/pulldown elements are closest, but these are not in all technologies.
And since the rule should be technology independent, I agree with the 1076.6 rule.

Or timing (delay in general) and how ignoring that affects the model behavior.
Synthesis tools don't even warn about ignoring these, since customers complained that
the log files were too long with these 'useless' messages.

Face it, there are various language constructs which are not 'synthesizable' but for
which 1076.6 has a rule how synthesis should interpret it, but do not error out on it.

I think the 'sensitivity list' warning or error issue is one of these. Warning is OK..
If there is appropriate hardware in the target technology, map it,
and if not, error out and don't produce any hardware. I just posted
more on this in my response in the other thread.

No, no, no. Cannot do that. It would create technology dependency in RTL code.
Designer can then no longer rely on their code to run on different tools, with
different target technologies, and that would be like going back to
promoting proprietary data types and non-portable HDL code.

Now we ask : "is the code synthesizable".
After introducing technology-specific coding rules, we would need to ask :
"is the code synthesizable to XYZ technology".

I thought we were beyong that point.
 
J

Jonathan Bromley

No, no, no. Cannot do that. It would create technology dependency in RTL code.
Designer can then no longer rely on their code to run on different tools, with
different target technologies, and that would be like going back to
promoting proprietary data types and non-portable HDL code.

Sorry, I emphatically disagree with you here.

It is absolutely NOT the purpose of synthesisable HDL to guarantee
that your code will synthesise on any platform. FPGA users (at least,
the non-naive ones) already know this - they understand how to write
behavioural code that will synthesise, for example, to dual-port RAM
that may or may not exist in a certain target. The code is completely
valid even if the target can't implement it. This is essentially
no different from a piece of HDL code that is too big to fit into a
certain device - there's nothing wrong with the code, but it needs
a different device to make it work. On the other hand, we DO want
our synthesisable code to behave the same way on any tool; nothing
I'm asking precludes that.

Register initialisation is one example of an entirely reasonable
hardware-specific feature that I want to be able to use; if I try
to map such code to a device that doesn't support it, I would
like my tools to tell me. DDR cells are another example. In both
cases, it is pretty much impossible to replicate the *exact*
functionality using other general-purpose logic; however, in both
cases it's probably possible to design your way around the lack.
I want such workarounds to be explicit, and controllable -
perhaps with generics, perhaps with some kind of conditional
compilation arrangement. But I certainly take a very dim view
of tools that forbid me from using constructs that BOTH make
sense AND map successfully to a good proportion of available
devices. The key point here is that there is nothing proprietary,
non-standard or ambiguous about the code - it's simply that a
certain target doesn't support the operation. Plenty of FPGAs
don't reliably support latches; synthesis tools should be ashamed
of themselves if they don't ERROR (*not* warn) when trying
to synthesise a latch into such parts.
Now we ask : "is the code synthesizable".
After introducing technology-specific coding rules, we would need to ask :
"is the code synthesizable to XYZ technology".

Absolutely. But I think you are looking at this from the point of
view of a writer of an HDL front-end. That is absolutely the wrong
place to ask technology-specific questions. It is the right place to
decide what hardware the HDL implies, leaving it up to a later
stage of the synthesis to decide whether the target technology
can implement that function. That later stage is perfectly capable
of issuing fatal errors on its own account. The front end should
only ask "is the code synthesisable in principle, given the standard
synthesis subset". That subset can, and should, include stuff that
is synthesisable to some hardware platforms but not to others.

Once again I ask: what is different about saying "register
initialisation is OK, but this device can't do it" and saying
"a megabit of embedded RAM is OK, but this device can't
fit it"? In both examples, the front end should correctly
infer the desired function and a mapper should correctly
determine that it can't be done.
I thought we were beyong that point.

Not while there are cost/performance/size/power/time-to-market
tradeoffs, no, we're not. Until you can provide us with a tool that
will, without designer intervention, translate a spec into an
optimised design on an automatically-chosen optimal target,
please support us properly in our efforts to explore those tradeoffs.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd,, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Email: (e-mail address removed)
Web: http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 Email: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
A

Andy

YES THERE IS!!!

As I pointed out in post 20 to this thread, there is a simple
implementation of a two-clock flop (or both edges of the same clock),
that uses ONLY two D flops and three XOR gates, with NO combinatorial
feedback loops!!!

The output is glitch free so long as timing between clocks is met
(similar to issue with setup/hold on normal flops). The implementation
is even verifiable with STA, as long as the relationship between the
clocks is defined.

Thus we do have the capability to implement DDR functions in any fpga,
cpld, or asic, whether a DDR primitive exists for that architecture or
not. But as long as we users have to code it explicitly for targets
that don't have DDR primitives, we cannot use integers (unless you
write an XOR function for integers), enums, etc. (for DDR state
machines). Ditto with instantiation of primitives.

Please start implementing DDR (and/or two-clock) functions, using
either single-edge flops and gates, or primitives, as the target
architecture allows.

Thanks,

Andy Jones
 
M

Mike Treseler

Andy said:
Example 1 can be implemented using two d flops and three two-input xor
gates, and the output is glitch free if minimum timing between the two
clocks is observed (even verifiable with STA). Thus it can be produced
with almost any standard hardware.
Essentially, the "state" of the DDR "flop" is encoded in two bits. The
value is '1' if the two bits differ, and is '0' if the two bits are the
same. Either bit can determine the next value based on the input and
the other bit.

It looks like quartus does what you expect with your code.
See:
http://home.comcast.net/~mike_treseler/ddr.pdf

-- Mike Treseler
_____________________________
library ieee;
use ieee.std_logic_1164.all;
entity ddr is
port (
reset, clk1, clk2, data1, data2
: in std_ulogic;
q : out std_ulogic);
end entity ddr;

architecture synth of ddr is
signal q1, q2 : std_ulogic;
begin -- architecture synth
process (reset, clk1)
begin
if reset = '1' then
q1 <= '0';
elsif rising_edge(clk1) then
q1 <= data1 xor q2;
end if;
end process;
process (reset, clk2)
begin
if reset = '1' then
q2 <= '0';
elsif rising_edge(clk2) then
q2 <= data2 xor q1;
end if;
end process;
q <= q1 xor q2;
end architecture synth;
 
R

Rob Dekker

Andy,

I'm sorry I did not respond to your post yet, but this was not for a lack of interest.

In short : I like your solution !

I did some simulations on the original and replacement patterns, and apart
from metalogic state handling (U, X etc) and the assumption that the two
clock edges occur mutually-exclusive in time (a reasonable assumption),
the two patterns are behaving the same. At least as far as I can see for now.

It is also cool, for many reasons :

- It would satify designers (like you?) to code up DDR designs easier ?
- the proposed coding style matches 1076.6-2004 proposed multi-edge register coding.
- because we can implement this without the need of technology-specific
primitives or library cells. Just standard DFFs and some XORs.

So : I WILL consider this as a possible implementation for double-edge sensitive registers.
I will file an enhancement request for this in our internal issue-tracking system.
That means it will be a fix for it (unless we find some fundamental issues with it).

Still, since you already coded up the RTL replacement pattern, this enhancement request
DOES have a work-around. That often lowers the priority on it for synthesis vendors.
So, I am looking for more advantages (apart from the above 3) to add some weight to this request.

Some notes :
- We will recognize this dual-edge sensitive register only from VHDL descriptions
which have signals that depend on two explict clock ('edge') conditions.
We will NOT recognize this from 'implicit' multiple edge conditions (like missing
signals on sensitivity lists. That is too risky in my opinion (since it is most likely a design mistake).
- We will issue a warning that this double-edge sensitive register is recognized, so
that designers are aware of what we are doing.
- I recommend that you file an enhancement request with your synthesis vendor,
so that we get some pressure on this (use the coding style of the 1076.6 dual-edge register
- Now please note that there is no guarantee that this will ever show up in an
actual synthesis tool. Verific provides the front-end for some 40 EDA tools,
but only one well-known synthesis tool : Altera's Quartus II. And Altera is very much
free to ignore this enhancement if they find it too risky.

Some questions :
- Is this a standard netlist solution for DDR designs ?
- Can you give a similar example (replacement pattern) for Verilog
(as you know, Verilog is more often used than VHDL).
- Do you have a 3-edge sensitive register description (netlist or replacement pattern) ?
- What if the two clocks are each other's inversion (register sensitive to both rising and falling edge)
Is there a simpler solution for it in that case ? Or should we use the same pattern ?

Any synthesis tool vendor is still free to make their own choice about
what they accept in HDL style and what not. EDA vendors are sensitive to customer
requests. So please file enhancement requests with your corrent synthesis tool vendor.

Thanks a lot, for a constructive and practical solution !

Rob

-- double-edge sensitive register :
library ieee ;
use ieee.std_logic_1164.all ;

entity test is
port (clk1, clk2, reset, data1, data2 : in std_logic ;
q_orig, q_replace : out std_logic ) ;
end entity test ;

architecture test of test is
signal q1, q2 : std_logic ;
begin

-- original process :
process (reset, clk1, clk2) begin
if (reset='1') then
q_orig <= '0' ;
elsif rising_edge(clk1) then
q_orig <= data1 ;
elsif rising_edge(clk2) then
q_orig <= data2 ;
end if ;
end process ;

-- replacement processes :
process (reset, clk1)
begin
if reset='1' then
q1 <= '0';
elsif rising_edge(clk1) then
q1 <= data1 xor q2;
end if;
end process;

process (reset, clk2)
begin
if reset='1' then
q2 <= '0';
elsif rising_edge(clk2) then
q2 <= data2 xor q1;
end if;
end process;

q_replace <= q1 xor q2; -- decode output

end architecture ;
 

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

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top