VHDL vs. verilog question

T

Thomas Heller

I'm trying to create a phase frequency detector, like the one
in figure 1 of this article:

http://www.analog.com/library/analogDialogue/archives/33-07/phase3/

I believe the VHDL code would be something like this:

process(in_a, in_b, up, down)
begin
if up = '1' and down = '1' then
up <= '0';
down <= '0';
else
if rising_edge(in_a) then
up <= '1';
end if;
if rising_edge(in_b) then
down <= '1';
end if;
end if;
end process;

Now, what I *actually* want to do is to model this circuit in MyHDL: www.myhdl.org

MyHDL follows the verilog coding style (I understand a little bit of VHDL
but not verilog).

My question is: Is it possible to write the above code in a similar
way in verilog (or MyHDL)? Is it possible to have a 'process' or what
it's called in verilog that has two edge sensitive signals in the sensitivity list?

Hope you can understand my question and thanks,
Thomas
 
A

Andy

This can be represented in two separate processes, one clocked by
in_a, and the other by in_b.

I hope you are not planning on synthesizing this to an FPGA.

Andy
 
A

Andy

It is the race condition on the clear signal that would concern me in
an FPGA, making sure that the first flop is not cleared, thus removing
the clear signal, before the second flop is cleared. It could be made
to work reliably with a lot of fuss and analysis (assuming the FPGA
vendor provides minimum delay specifications on async clear, routing,
etc.) but it would not be a good idea for someone who needs basic help
in synthesis.

Andy
 
T

Thomas Heller

Andy said:
It is the race condition on the clear signal that would concern me in
an FPGA, making sure that the first flop is not cleared, thus removing
the clear signal, before the second flop is cleared. It could be made
to work reliably with a lot of fuss and analysis (assuming the FPGA
vendor provides minimum delay specifications on async clear, routing,
etc.) but it would not be a good idea for someone who needs basic help
in synthesis.

Ok, so what are the alternatives? The circuit from xapp028, which I found here?

http://www.eettaiwan.com/ARTICLES/2000JUN/2000JUN29_AMD_PL_AN572.PDF?SOURCES=DOWNLOAD
 
T

Thomas Heller

Andy said:
This can be represented in two separate processes, one clocked by
in_a, and the other by in_b.

Ok, so the answer to my real question seems to be: a verilog process,
different from a VHDL process, can only have one edge-sensitive signal.

Correct?
 
A

Andy

Ok, so the answer to my real question seems to be: a verilog process,
different from a VHDL process, can only have one edge-sensitive signal.

Correct?

No, I don't know what verilog will allow. I'm just pointing out that
you don't need it to handle dual-clocked processes to handle this
circuit.

Andy
 
A

Andy

A circuit designed for relatively slow FPGA families from 10 years ago
may not work as well (or be as easily made to work well) in a modern,
very fast FPGA. Quite frankly, I like the original design better than
the xapp one.

What does this phase detector drive, an external filter and VCO, or an
internal synchronous NCO, or something else? Alternatives differ
widely based on the answer. Consider whether you need an asynchronous
phase detector, or whether a more synchronous design might work with
whatever it needs to control.

What the first design needs is a way to make sure the async clear does
not go away as soon as one of the registers is cleared. You could do
this with a third flop, set (clock in a '1') when the two flops are
both set, and cleared when both are cleared. Use the output of this
third flop to clear the first two. This may cause other problems
though with dead-band issues, meta-stability, etc.

However, I must also warn you: using combinatorial circuits (remember,
these are LUTs, not ANDs and ORs) to drive causal signals (clocks and
async resets) can be risky (glitchy), especially in cases where more
than one input to the LUT is changing at a time. The muxes in the LUTS
are very well balanced to minimize this, but "there ain't nothin'
perfect".

Generally speaking, the more synchronous the design, the fewer
problems getting it to work reliably (across different die, power
supply voltages, temperatures, aging, etc.).

Andy
 
T

Thomas Heller

Andy said:
A circuit designed for relatively slow FPGA families from 10 years ago
may not work as well (or be as easily made to work well) in a modern,
very fast FPGA. Quite frankly, I like the original design better than
the xapp one.

And indeed, the circuit from xapp028 isn't recommended any more for newer
devices. Here is a thread where this is discussed:

http://groups.google.com/group/comp...82e2849011f/f89506f566d0568c#f89506f566d0568c

What does this phase detector drive, an external filter and VCO, or an
internal synchronous NCO, or something else? Alternatives differ
widely based on the answer. Consider whether you need an asynchronous
phase detector, or whether a more synchronous design might work with
whatever it needs to control.

What the first design needs is a way to make sure the async clear does
not go away as soon as one of the registers is cleared. You could do
this with a third flop, set (clock in a '1') when the two flops are
both set, and cleared when both are cleared. Use the output of this
third flop to clear the first two. This may cause other problems
though with dead-band issues, meta-stability, etc.

I'll think this idea over.
However, I must also warn you: using combinatorial circuits (remember,
these are LUTs, not ANDs and ORs) to drive causal signals (clocks and
async resets) can be risky (glitchy), especially in cases where more
than one input to the LUT is changing at a time. The muxes in the LUTS
are very well balanced to minimize this, but "there ain't nothin'
perfect".

Generally speaking, the more synchronous the design, the fewer
problems getting it to work reliably (across different die, power
supply voltages, temperatures, aging, etc.).

Thanks, Andy, for these tips. It seems that the AD9901 chip contains
a phase-frequency detector that could be implemented inside an fpga
without problems; however, I have to check if I can use it for my
application (I fear I cannot ;-).

Thomas
 
A

Andy Peters

Ok, so the answer to my real question seems to be: a verilog process,
different from a VHDL process, can only have one edge-sensitive signal.

No, both Verilog and VHDL allow processes to be sensitive to the edges
of any number of signals. Certainly for behavioral modeling this is
perfectly OK.

However, you have to realize that FPGA flip-flops are sensitive to the
edge of only one signal, so the synthesis tools will likely barf on
code that uses more than one signal's edge.

-a
 
T

Thomas Heller

Andy said:
However, you have to realize that FPGA flip-flops are sensitive to the
edge of only one signal, so the synthesis tools will likely barf on
code that uses more than one signal's edge.

I know this very well, having designed digital circuits since 35 years ;-)
And not all clock signals have to go into the same flip-flop's clock input.

Part of the question in my original post was: How would the below VHDL code
look like in a single verilog process:

process(in_a, in_b, up, down)
begin
if up = '1' and down = '1' then
up <= '0';
down <= '0';
else
if rising_edge(in_a) then
up <= '1';
end if;
if rising_edge(in_b) then
down <= '1';
end if;
end if;
end process;



Thomas
 
A

Andy

Many FPGA synthesis tools will allow more than one clock edge in a
process. They usually won't allow assignments to the same signal/
variable on more than one clock, but that is not being done in this
example.

Some FPGAs have DDR flops in the IOBs. Not sure whether any tools will
infer a DDR flop from a two clock process assigning the same var/sig
on both clocks.

Andy
 
J

Jan Decaluwe

I know this very well, having designed digital circuits since 35 years ;-)
And not all clock signals have to go into the same flip-flop's clock input.

Part of the question in my original post was: How would the below VHDL code
look like in a single verilog process:

process(in_a, in_b, up, down)
begin
  if up = '1' and down = '1' then
    up <= '0';
    down <= '0';
  else
    if rising_edge(in_a) then
      up <= '1';
    end if;
    if rising_edge(in_b) then
      down <= '1';
    end if;
  end if;
end process;

Thomas

Interesting, isn't it? You ask a question about modeling
and everyone is immediately concerned about synthesis :)

What you need is way to check, in an if statement, which
signal has just seen an event.

I'm not aware of a way to do this in Verilog, although of
course the proper forum to ask would be comp.lang.verilog.
(Who knows what can be found in the dark corners of the
standards...)

It cannot be done in MyHDL either, although it would certainly
be possible to support this, e.g. by a Signal.event attribute.
I would be reluctant to add this, because it would add
operations in the main simulation loop for an uncertain
value, given that the whole Verilog community can
perfectly live without it ... (not entirely sure about
that argument either though :))

Jan

--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Python as a HDL: http://www.myhdl.org
VHDL development, the modern way: http://www.sigasi.com
Analog design automation: http://www.mephisto-da.com
World-class digital design: http://www.easics.com
 
J

Jonathan Bromley

What you need is way to check, in an if statement, which
signal has just seen an event.

Ah. Like "rising_edge(sig)" or "sig'event" or something
really silly like that? The kind of stuff that only
dumb software wonks, writing a bloated language like
VHDL, would think of? :)
I'm not aware of a way to do this in Verilog

It's not wildly hard, but it needs care.

always @(sigA, sigB) begin
reg old_sigA, old_sigB;
if (sigA !== old_sigA) begin
// sigA has changed
end
if (sigB !== old_sigB) begin
// sigB has changed
end
old_sigA = sigA;
old_sigB = sigB;
end

Note that you must keep the "old" values IN THE
SAME SEQUENTIAL BLOCK as you used to do the test,
otherwise you're exposed to all manner of race
conditions. Tedious, because it means you must
replicate the "old-keeper" code in each place
you might need it.

Note, too, the use of !== for comparison.

The same code works fine for multi-bit signals
too, although of course you must be careful
to declare the "old_" variables to be the same
size as the signals of interest.

Needless to say, this is modelling code and
won't synthesise correctly!

SystemVerilog adds some alternative tricks for
doing similar things, with its event variables
and event .triggered property.

cheers
 
A

Andy

Jan,

So how is a DDR register (with two clocks and two data inputs) modeled
in verilog or myhdl?

Andy
 
J

Jan Decaluwe

Jan,

So how is a DDR register (with two clocks and two data inputs) modeled
in verilog or myhdl?

Andy

With Jonathans's somewhat brute-force method I guess :)
Mm, perhaps I really should consider adding an .event
attribute, or doing it like in SystemVerilog if someone
can tell me how that is exactly ...

--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Python as a HDL: http://www.myhdl.org
VHDL development, the modern way: http://www.sigasi.com
Analog design automation: http://www.mephisto-da.com
World-class digital design: http://www.easics.com
 
M

Marcus Harnisch

Jan Decaluwe said:
With Jonathans's somewhat brute-force method I guess :)

But why has nobody asked about the rationale for the requirement(?)
implementing the original function in one process? Nobody here
seriously believes that this would simulate faster?!

Regarding the DDR register above, just use two processes assigning to
the same register. As opposed to VHDL concurrent drivers, in Verilog
the last assignment wins. Should both clock edges occur
simultaneously, it is undefined which assignment is effective. I guess
that models the real world pretty well.

always @(posedge clk0, posedge reset) begin
if (reset)
q <= 0;
else
q <= d0;
end

always @(posedge clk1, posedge reset) begin
if (reset)
q <= 0;
else
q <= d1;
end


--
Marcus

note that "property" can also be used as syntactic sugar to reference
a property, breaking the clean design of verilog; [...]

(seen on http://www.veripool.com/verilog-mode_news.html)
 
J

Jan Decaluwe

But why has nobody asked about the rationale for the requirement(?)
implementing the original function in one process? Nobody here
seriously believes that this would simulate faster?!

Regarding the DDR register above, just use two processes assigning to
the same register. As opposed to VHDL concurrent drivers, in Verilog
the last assignment wins. Should both clock edges occur
simultaneously, it is undefined which assignment is effective. I guess
that models the real world pretty well.

I suspect the reason is that VHDL designers tend to care about
determinism. The fact that the real world is non-deterministic doesn't
imply that it's a good idea to make your simulations non-deterministic
also.

Jan
 
A

Andy

I suspect the reason is that VHDL designers tend to care about
determinism. The fact that the real world is non-deterministic doesn't
imply that it's a good idea to make your simulations non-deterministic
also.

Jan- Hide quoted text -

- Show quoted text -

To add to that, I would want my model to tell me if it could not
determine what the modelled behavior (i.e. hardware) would/should do.
This could be via an assertion failure and/or by assigning the output
to 'X' if both clocks occurred at the same time. Maybe there's a way
to do that in verilog and/or myhdl?

Andy
 
A

Andy

With Jonathans's somewhat brute-force method I guess :)

But why has nobody asked about the rationale for the requirement(?)
implementing the original function in one process? Nobody here
seriously believes that this would simulate faster?!

Regarding the DDR register above, just use two processes assigning to
the same register. As opposed to VHDL concurrent drivers, in Verilog
the last assignment wins. Should both clock edges occur
simultaneously, it is undefined which assignment is effective. I guess
that models the real world pretty well.

    always @(posedge clk0, posedge reset) begin
        if (reset)
          q <= 0;
        else
          q <= d0;
    end

    always @(posedge clk1, posedge reset) begin
        if (reset)
          q <= 0;
        else
          q <= d1;
    end

--
Marcus

note that "property" can also be used as syntactic sugar to reference
a property, breaking the clean design of verilog; [...]

             (seen onhttp://www.veripool.com/verilog-mode_news.html)

Aha! I keep forgetting you can do that in verilog...

Reasons a single process is desired in vhdl include that it would
simulate faster, especially since it would allow using a variable
instead of a signal.

I suppose we all assume solutions in the forms we are most used to.
Thanks for keeping us honest.

Andy
 
M

Marcus Harnisch

Jan Decaluwe said:
I suspect the reason is that VHDL designers tend to care about
determinism. The fact that the real world is non-deterministic doesn't
imply that it's a good idea to make your simulations non-deterministic
also.

But this objection only applies to the solution for Andy's
problem. Thomas wants to drive individual signals which serve as their
own asynchronous resets. BTW, at which minimal phase difference do you
consider both edges simultaneous. Here is a solution which leaves q as
unknown if both clock edges occur in the same time step and try to
assign opposite values.

For most practical purposes in simulation[1] the code (using blocking
assignments) below should suffice:

always @(posedge clk0, posedge reset) begin
if (reset)
q = 0;
else begin
q = d0;
#0;
if (q != d0)
// the other block has been executed after this one in the
// same time step and assigned a different value
q = 1'bx;
end
end

always @(posedge clk1, posedge reset) begin
if (reset)
q = 0;
else begin
q = d1;
#0;
if (q != d1)
// the other block has been executed after this one in the
// same time step and assigned a different value
q = 1'bx;
end
end

But we are drifting away from the original request.

Footnotes:
[1] Since most DDR flops are implemented using special cells you
wouldn't want to synthesize this anyway.

--
Marcus

note that "property" can also be used as syntactic sugar to reference
a property, breaking the clean design of verilog; [...]

(seen on http://www.veripool.com/verilog-mode_news.html)
 

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

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top