about the always block in verilog

Y

yu zhou

Guest
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin end block??
 
On 2/23/2013 8:38 AM, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin end block??
You can't. You can only test the current state of the variables
in the sensitivity list. Luckily this isn't generally necessary
for common synthesis constructs, and my guess is that anything
with more than two edge events in the sensitivity list won't
synthesize. For simulation, you would typically work around
this by using multiple processes, since you don't have the
same constraint of driving a signal from only one process like
you would for synthesis.

-- Gabor
 
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
...
So,how can i determine what event does really happen in begin end block??
First of all begin is a reserved verilog keyword so "negedge begin" is going to give you heartache; change the identifier.

Secondly if you want to synthesize this, you have to check if your target library supports two asynchronous inputs simultaneously. Some (asic) libraries have async set & reset flops so, it might synthesize if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to get the right behavior, you have to follow the (set/reset) priority of your library flop to get the simulation behavior to match it.

Lastly if you are just trying to get it to simulate it, you can write some complicated case/if-else statements to check the state of every variable to see which event has actually fired but you should realize that there is no way this will be synthesis friendly.
 
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
...
So,how can i determine what event does really happen in begin end block??

First of all begin is a reserved verilog keyword so "negedge begin" is going to give you heartache; change the identifier.

Secondly if you want to synthesize this, you have to check if your target library supports two asynchronous inputs simultaneously. Some (asic) libraries have async set & reset flops so, it might synthesize if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to get the right behavior, you have to follow the (set/reset) priority of your library flop to get the simulation behavior to match it.

Lastly if you are just trying to get it to simulate it, you can write some complicated case/if-else statements to check the state of every variable to see which event has actually fired but you should realize that there is no way this will be synthesis friendly.
The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

For simulation, it is more typical to use multiple processes
to describe a flop with multiple asynchronous controls. Also
note that to describe for example a D FF with async set and reset,
you really need to be sensitive to both edges of the set and
reset inputs to handle the case where both were asserted at the
same time and then one of them released. I don't know of
any synthesizers that allow you to infer this sort of flop,
so I've always instantiated them if necessary.

-- Gabor
 
yu zhou <zydgyy@gmail.com> wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin
end block??
If you can't figure it out, how would the synthesis tool or
actual FF figure it out?

In a more usual case, you see something like:

always @(posedge clk or posedge reset) begin
if(reset) q <= 0;
else q<=d;
end

(I might have that wrong, but maybe you see the idea.)

If reset goes high, it resets.

If reset is high on a clock positive edge, it stays reset.

If reset is not high on a clock positive edge, it clocks data in.

There are four cases here to consider. clk high or low on
posedge reset, and reset high or low on posedge clk.

(The tools usually don't know that there is the case that
both change at once. In actual logic, it would usually be
a setup/hold violation and/or race condition.)

If you have three edge events, then you have to consider the
state of the other two signals on any of the three events,
for 12 combinations.

Note the use of posedge reset, though the FF reset is not edge
triggered. The only interesting thing happens on the posedge.
The rest of the state has to depend on the current values of the
other signals on the transition. (If reset is high, it stays reset
even when a clk event occurs.)

On the other hand:

always @(posedge clk) begin
if(reset) q <= 0;
else q<=d;
end

generates a synchronous reset FF.

-- glen
 
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
...
So,how can i determine what event does really happen in begin end
block??

First of all begin is a reserved verilog keyword so "negedge begin" is
going to give you heartache; change the identifier.

Secondly if you want to synthesize this, you have to check if your
target library supports two asynchronous inputs simultaneously. Some
(asic) libraries have async set & reset flops so, it might synthesize
if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to
get the right behavior, you have to follow the (set/reset) priority of
your library flop to get the simulation behavior to match it.

Lastly if you are just trying to get it to simulate it, you can write
some complicated case/if-else statements to check the state of every
variable to see which event has actually fired but you should realize
that there is no way this will be synthesis friendly.

The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.
This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.


For simulation, it is more typical to use multiple processes
to describe a flop with multiple asynchronous controls. Also
note that to describe for example a D FF with async set and reset,
you really need to be sensitive to both edges of the set and
reset inputs to handle the case where both were asserted at the
same time and then one of them released. I don't know of
any synthesizers that allow you to infer this sort of flop,
so I've always instantiated them if necessary.
I don't follow what you mean. I'm not as familiar with Verilog. In
VHDL you would just include both the set and reset signal in the
sensitivity list which runs the process anytime any of those signals
change state. Then in the logic the states are checked to describe what
the logic should do about it. Sometimes that will be nothing, for
example on the falling edge of the rising edge sensitive clock signal.
The process will be activated by the falling edge, but the code will not
execute any assignments.

A D FF with both set and reset async inputs is not hard to describe in
VHDL. I can't imagine this is hard to describe in Verilog either. I
don't understand what you mean by "I don't know of any synthesizers that
allow you to infer this sort of flop". Is that really a limitation in
Verilog?

process(Clk, Reset, Set) begin
if (Reset) then
Q <= '0';
elsif (Set) then
Q <= '1';
elsif (rising_edge(Clk)) then
Q <= Dinput;
end if;
end process;

In this case the Reset input has priority over the Set which has
priority over the Clk. How do you do this in Verilog? I just realized
that I need to download a Verilog cheat sheet. I have a couple for
VHDL, but none for Verilog... my bad!

Wouldn't you just write...

always@(posedge Clk or Reset or Set)
if (Reset)...

--

Rick
 
On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote:
yu zhou<zydgyy@gmail.com> wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin
end block??

If you can't figure it out, how would the synthesis tool or
actual FF figure it out?

In a more usual case, you see something like:

always @(posedge clk or posedge reset) begin
if(reset) q<= 0;
else q<=d;
end

(I might have that wrong, but maybe you see the idea.)

If reset goes high, it resets.

If reset is high on a clock positive edge, it stays reset.

If reset is not high on a clock positive edge, it clocks data in.

There are four cases here to consider. clk high or low on
posedge reset, and reset high or low on posedge clk.

(The tools usually don't know that there is the case that
both change at once. In actual logic, it would usually be
a setup/hold violation and/or race condition.)

If you have three edge events, then you have to consider the
state of the other two signals on any of the three events,
for 12 combinations.

Note the use of posedge reset, though the FF reset is not edge
triggered. The only interesting thing happens on the posedge.
The rest of the state has to depend on the current values of the
other signals on the transition. (If reset is high, it stays reset
even when a clk event occurs.)
Yes, that is the part I'm not clear on. What if the simulation starts
with reset at '1'. Is an event generated on reset anyway so that the
process runs and q is reset?

--

Rick
 
rickman wrote:
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
...
So,how can i determine what event does really happen in begin end
block??

First of all begin is a reserved verilog keyword so "negedge begin" is
going to give you heartache; change the identifier.

Secondly if you want to synthesize this, you have to check if your
target library supports two asynchronous inputs simultaneously. Some
(asic) libraries have async set & reset flops so, it might synthesize
if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to
get the right behavior, you have to follow the (set/reset) priority of
your library flop to get the simulation behavior to match it.

Lastly if you are just trying to get it to simulate it, you can write
some complicated case/if-else statements to check the state of every
variable to see which event has actually fired but you should realize
that there is no way this will be synthesis friendly.

The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.


For simulation, it is more typical to use multiple processes
to describe a flop with multiple asynchronous controls. Also
note that to describe for example a D FF with async set and reset,
you really need to be sensitive to both edges of the set and
reset inputs to handle the case where both were asserted at the
same time and then one of them released. I don't know of
any synthesizers that allow you to infer this sort of flop,
so I've always instantiated them if necessary.

I don't follow what you mean. I'm not as familiar with Verilog. In
VHDL you would just include both the set and reset signal in the
sensitivity list which runs the process anytime any of those signals
change state. Then in the logic the states are checked to describe what
the logic should do about it. Sometimes that will be nothing, for
example on the falling edge of the rising edge sensitive clock signal.
The process will be activated by the falling edge, but the code will not
execute any assignments.

A D FF with both set and reset async inputs is not hard to describe in
VHDL. I can't imagine this is hard to describe in Verilog either. I
don't understand what you mean by "I don't know of any synthesizers that
allow you to infer this sort of flop". Is that really a limitation in
Verilog?

process(Clk, Reset, Set) begin
if (Reset) then
Q <= '0';
elsif (Set) then
Q <= '1';
elsif (rising_edge(Clk)) then
Q <= Dinput;
end if;
end process;

In this case the Reset input has priority over the Set which has
priority over the Clk. How do you do this in Verilog? I just realized
that I need to download a Verilog cheat sheet. I have a couple for
VHDL, but none for Verilog... my bad!

Wouldn't you just write...

always@(posedge Clk or Reset or Set)
if (Reset)...

The problem in Verilog is that you can't place the edge dependancy
in the if statements within the always block. A clocked block in
Verilog has the edge dependencies in the sensitivity list itself
and you use the if statement to check the current (post event) state
of the signals. So you don't really have the equivalent of the VHDL
code where the if statements for the set/reset are level triggered
but the if statement for the clock is edge triggered. There was a
prolonged discussion of this in comp.lang.verilog where the bottom
line was that you need two processes to properly describe a D-FF
with two asynchronous controls.

Regarding your suggestion, the block would trigger on either
edge of set or reset, and only on the rising edge of clk. Now
if you wrote:

always @ (posedge clk or reset or set)
if (reset)
Q <= 0;
else if (set) Q <= 1;
else Q <= D;

Then the problem is that the final else cannot really check that you
got here because of the rising clock edge. You could add:

else if (clk) Q <= D;

But even that would not work in the case where you released the
last asynchronous input while the clock was already high. And
since you don't get to this point until after the event that
triggered the block, you can't say else @ (posedge clk) Q <= D;
because that would say to wait for another rising edge.

Bottom line, for Verilog to model this properly you need two processes:

always @ (set or reset)
if (reset) Q = 0;
else if (set) Q = 1;

always @ (posedge clk)
Q <= D;

Which works fine for simulation, but gives you a "multisource" error
for synthesis.

-- Gabor
 
rickman wrote:
On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote:
yu zhou<zydgyy@gmail.com> wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin
end block??

If you can't figure it out, how would the synthesis tool or
actual FF figure it out?

In a more usual case, you see something like:

always @(posedge clk or posedge reset) begin
if(reset) q<= 0;
else q<=d;
end

(I might have that wrong, but maybe you see the idea.)

If reset goes high, it resets.

If reset is high on a clock positive edge, it stays reset.

If reset is not high on a clock positive edge, it clocks data in.

There are four cases here to consider. clk high or low on
posedge reset, and reset high or low on posedge clk.

(The tools usually don't know that there is the case that
both change at once. In actual logic, it would usually be
a setup/hold violation and/or race condition.)

If you have three edge events, then you have to consider the
state of the other two signals on any of the three events,
for 12 combinations.

Note the use of posedge reset, though the FF reset is not edge
triggered. The only interesting thing happens on the posedge.
The rest of the state has to depend on the current values of the
other signals on the transition. (If reset is high, it stays reset
even when a clk event occurs.)

Yes, that is the part I'm not clear on. What if the simulation starts
with reset at '1'. Is an event generated on reset anyway so that the
process runs and q is reset?

The simulation always starts with everything undriven. So initial
statements at time zero, or initial values in a reg declaration
will always create an edge. Thus I typically start my simulation
with:

initial begin
reset = 1;
clk = 0;
. . .
#100 reset = 0;
. . .
end

And all of my asynchronous reset processes trigger at time zero. Note
that a clock is typically initialized to zero which would trigger any
negedge processes at time zero as well.

-- Gabor
 
On 3/1/2013 4:35 PM, GaborSzakacs wrote:
rickman wrote:
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
...
So,how can i determine what event does really happen in begin end
block??

First of all begin is a reserved verilog keyword so "negedge begin" is
going to give you heartache; change the identifier.

Secondly if you want to synthesize this, you have to check if your
target library supports two asynchronous inputs simultaneously. Some
(asic) libraries have async set & reset flops so, it might synthesize
if you write "if (!nrst) foo <= 0; if (!brst) foo <= 1;" etc. But to
get the right behavior, you have to follow the (set/reset) priority of
your library flop to get the simulation behavior to match it.

Lastly if you are just trying to get it to simulate it, you can write
some complicated case/if-else statements to check the state of every
variable to see which event has actually fired but you should realize
that there is no way this will be synthesis friendly.

The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.


For simulation, it is more typical to use multiple processes
to describe a flop with multiple asynchronous controls. Also
note that to describe for example a D FF with async set and reset,
you really need to be sensitive to both edges of the set and
reset inputs to handle the case where both were asserted at the
same time and then one of them released. I don't know of
any synthesizers that allow you to infer this sort of flop,
so I've always instantiated them if necessary.

I don't follow what you mean. I'm not as familiar with Verilog. In
VHDL you would just include both the set and reset signal in the
sensitivity list which runs the process anytime any of those signals
change state. Then in the logic the states are checked to describe
what the logic should do about it. Sometimes that will be nothing, for
example on the falling edge of the rising edge sensitive clock signal.
The process will be activated by the falling edge, but the code will
not execute any assignments.

A D FF with both set and reset async inputs is not hard to describe in
VHDL. I can't imagine this is hard to describe in Verilog either. I
don't understand what you mean by "I don't know of any synthesizers
that allow you to infer this sort of flop". Is that really a
limitation in Verilog?

process(Clk, Reset, Set) begin
if (Reset) then
Q <= '0';
elsif (Set) then
Q <= '1';
elsif (rising_edge(Clk)) then
Q <= Dinput;
end if;
end process;

In this case the Reset input has priority over the Set which has
priority over the Clk. How do you do this in Verilog? I just realized
that I need to download a Verilog cheat sheet. I have a couple for
VHDL, but none for Verilog... my bad!

Wouldn't you just write...

always@(posedge Clk or Reset or Set)
if (Reset)...

The problem in Verilog is that you can't place the edge dependancy
in the if statements within the always block. A clocked block in
Verilog has the edge dependencies in the sensitivity list itself
and you use the if statement to check the current (post event) state
of the signals. So you don't really have the equivalent of the VHDL
code where the if statements for the set/reset are level triggered
but the if statement for the clock is edge triggered. There was a
prolonged discussion of this in comp.lang.verilog where the bottom
line was that you need two processes to properly describe a D-FF
with two asynchronous controls.

Regarding your suggestion, the block would trigger on either
edge of set or reset, and only on the rising edge of clk. Now
if you wrote:

always @ (posedge clk or reset or set)
if (reset)
Q <= 0;
else if (set) Q <= 1;
else Q <= D;

Then the problem is that the final else cannot really check that you
got here because of the rising clock edge. You could add:

else if (clk) Q <= D;
Yes, I get it. If the process was triggered by a falling edge of reset
or set the code would do the same thing as a rising edge of clk.


But even that would not work in the case where you released the
last asynchronous input while the clock was already high. And
since you don't get to this point until after the event that
triggered the block, you can't say else @ (posedge clk) Q <= D;
because that would say to wait for another rising edge.

Bottom line, for Verilog to model this properly you need two processes:

always @ (set or reset)
if (reset) Q = 0;
else if (set) Q = 1;

always @ (posedge clk)
Q <= D;

Which works fine for simulation, but gives you a "multisource" error
for synthesis.
Yes, indeed. Thanks for the info.

--

Rick
 
On 3/1/2013 4:39 PM, GaborSzakacs wrote:
rickman wrote:
On 2/25/2013 2:18 PM, glen herrmannsfeldt wrote:
yu zhou<zydgyy@gmail.com> wrote:
always @(negedge nrst or posedge PCLK or negedge begin)
begin
...
end

So,how can i determine what event does really happen in begin
end block??

If you can't figure it out, how would the synthesis tool or
actual FF figure it out?

In a more usual case, you see something like:

always @(posedge clk or posedge reset) begin
if(reset) q<= 0;
else q<=d;
end

(I might have that wrong, but maybe you see the idea.)

If reset goes high, it resets.

If reset is high on a clock positive edge, it stays reset.

If reset is not high on a clock positive edge, it clocks data in.

There are four cases here to consider. clk high or low on
posedge reset, and reset high or low on posedge clk.

(The tools usually don't know that there is the case that
both change at once. In actual logic, it would usually be
a setup/hold violation and/or race condition.)

If you have three edge events, then you have to consider the
state of the other two signals on any of the three events,
for 12 combinations.

Note the use of posedge reset, though the FF reset is not edge
triggered. The only interesting thing happens on the posedge.
The rest of the state has to depend on the current values of the
other signals on the transition. (If reset is high, it stays reset
even when a clk event occurs.)

Yes, that is the part I'm not clear on. What if the simulation starts
with reset at '1'. Is an event generated on reset anyway so that the
process runs and q is reset?

The simulation always starts with everything undriven. So initial
statements at time zero, or initial values in a reg declaration
will always create an edge. Thus I typically start my simulation
with:

initial begin
reset = 1;
clk = 0;
. . .
#100 reset = 0;
. . .
end

And all of my asynchronous reset processes trigger at time zero. Note
that a clock is typically initialized to zero which would trigger any
negedge processes at time zero as well.
I have a fuzzy recollection that in VHDL they either changed or are
discussing changing rising_edge so that it only triggers on a logic edge
rather than triggering from a non-logic state like 'U' or 'X' or I
assume even 'Z'. Maybe I'm only hallucinating, but I think I read this.

In any event, I'm pretty sure that initialization happens prior to the
start of the simulation so that it can't cause edges, but I'm not
certain. I think I would have a clear recollection if it could because
I would have been doing that...

--

Rick
 
rickman <gnuarm@gmail.com> wrote:
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)

So,how can i determine what event does really happen in begin end
block??
(snip)
The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.
But are there any useful cases where that is true?

Now, you can write plenty of things that don't make any sense
in actual logic.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.
OK, now consider:

always @(posedge clk or posedge reset) begin
if(reset) q<=0;
else q<=d;
end

There are two cases where the block is executed, when either
clk or reset goes high. If (asynchronous) reset is high,
then q goes to zero, even if the block was entered by clk.

For simulation, it is more typical to use multiple processes
to describe a flop with multiple asynchronous controls. Also
note that to describe for example a D FF with async set and reset,
you really need to be sensitive to both edges of the set and
reset inputs to handle the case where both were asserted at the
same time and then one of them released. I don't know of
any synthesizers that allow you to infer this sort of flop,
so I've always instantiated them if necessary.

I don't follow what you mean. I'm not as familiar with Verilog. In
VHDL you would just include both the set and reset signal in the
sensitivity list which runs the process anytime any of those signals
change state. Then in the logic the states are checked to describe what
the logic should do about it. Sometimes that will be nothing, for
example on the falling edge of the rising edge sensitive clock signal.
The process will be activated by the falling edge, but the code will not
execute any assignments.
In verilog, you might do something, but it might be the same
thing that was done before.

A D FF with both set and reset async inputs is not hard to describe in
VHDL. I can't imagine this is hard to describe in Verilog either. I
don't understand what you mean by "I don't know of any synthesizers that
allow you to infer this sort of flop". Is that really a limitation in
Verilog?

process(Clk, Reset, Set) begin
if (Reset) then
Q <= '0';
elsif (Set) then
Q <= '1';
elsif (rising_edge(Clk)) then
Q <= Dinput;
end if;
end process;

In this case the Reset input has priority over the Set which has
priority over the Clk. How do you do this in Verilog? I just realized
that I need to download a Verilog cheat sheet. I have a couple for
VHDL, but none for Verilog... my bad!

Wouldn't you just write...

always@(posedge Clk or Reset or Set)
if (Reset)...
I believe that would be more like a transparent latch.
Note that it will also be executed on the falling edge
of reset, and that reset will be 0 at that time.

always @(posedge clk or posedge reset) begin
if(reset) q<=0;
else q<=d;
end

I suppose it is funny, as it looks like reset is edge triggered,
but it only actually happens on the rising edge.

If you do:

always @(posedge clk) begin
if(reset) q<=0;
else q<=d;
end

then you should get a synchronous (clocked) reset.

Now, if you wrote:

always @(clk) begin
q<=d;
end

you would get a FF clocked on both edges, which is rare.
(Maybe they use them in DDR logic, but still rare.)

-- glen
 
GaborSzakacs <gabor@alacron.com> wrote:

(snip, someone wrote)
Yes, that is the part I'm not clear on. What if the simulation starts
with reset at '1'. Is an event generated on reset anyway so that the
process runs and q is reset?

The simulation always starts with everything undriven. So initial
statements at time zero, or initial values in a reg declaration
will always create an edge. Thus I typically start my simulation
with:

initial begin
reset = 1;
clk = 0;
. . .
#100 reset = 0;
. . .
end

And all of my asynchronous reset processes trigger at time zero. Note
that a clock is typically initialized to zero which would trigger any
negedge processes at time zero as well.
You could do that, but most real logic requires some clock cycles to
get into the appropriate state. I know that many microprocessors require
reset to be active for some number, maybe 50, clock cycles.

Now, for FPGAs the device usually does a global reset as it comes
out of configuration, and you might want to simulate that.

Then again, it might be that FPGA simulation doesn't do initial.

-- glen
 
On 3/1/2013 7:17 PM, glen herrmannsfeldt wrote:
rickman<gnuarm@gmail.com> wrote:
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)

So,how can i determine what event does really happen in begin end
block??

(snip)
The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

But are there any useful cases where that is true?

Now, you can write plenty of things that don't make any sense
in actual logic.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.

OK, now consider:

always @(posedge clk or posedge reset) begin
if(reset) q<=0;
else q<=d;
end

There are two cases where the block is executed, when either
clk or reset goes high. If (asynchronous) reset is high,
then q goes to zero, even if the block was entered by clk.
The problem I was concerned about with this was the case where the
simulation starts with reset at a '1' and the edge is not generated.
But I am told this does not happen. In Verilog initializations create
edges. I am fairly sure that I have initialized signals in VHDL
simulations and they do *not* result in an edge at the start of the
simulation. I am not certain because there is normally the reset
preventing a clock from being recognized.


Now, if you wrote:

always @(clk) begin
q<=d;
end

you would get a FF clocked on both edges, which is rare.
(Maybe they use them in DDR logic, but still rare.)
To the best of my knowledge there are *no* double edge FFs. DDR inputs
have separate FFs which capture the input on the opposite edges of the
clock, or they double the clock with a PLL and clock the data twice in
each clock cycle on the rising edge of the doubled clock.

--

Rick
 
rickman wrote:
On 3/1/2013 7:17 PM, glen herrmannsfeldt wrote:
rickman<gnuarm@gmail.com> wrote:
On 2/25/2013 9:05 AM, GaborSzakacs wrote:
muzaffer.kal@gmail.com wrote:
On Saturday, February 23, 2013 5:38:40 AM UTC-8, yu zhou wrote:
always @(negedge nrst or posedge PCLK or negedge begin)

So,how can i determine what event does really happen in begin end
block??

(snip)
The point I was making is that even with if/else logic,
you can't always tell which event triggered the process,
because there may be more than one signal which is in
the state it would be if it had just triggered the process.

But are there any useful cases where that is true?

Now, you can write plenty of things that don't make any sense
in actual logic.

You might be able to detect the event if you also kept track
of the previous state of each variable, but the process
won't do this for you, so you would need more registers
for this.

This is different from VHDL. The signal keeps track of the current
state, the prior state and whether or not the state changed for this
delta cycle. rising_edge(foo) checks that foo is in the '1' state (or
'high' IIRC) and if the signal had just changed, foo'event=TRUE (or is
it '1', again, I don't recall). These conditions can all be checked in
the code using IF statements.

OK, now consider:

always @(posedge clk or posedge reset) begin
if(reset) q<=0;
else q<=d;
end

There are two cases where the block is executed, when either
clk or reset goes high. If (asynchronous) reset is high,
then q goes to zero, even if the block was entered by clk.

The problem I was concerned about with this was the case where the
simulation starts with reset at a '1' and the edge is not generated. But
I am told this does not happen. In Verilog initializations create
edges. I am fairly sure that I have initialized signals in VHDL
simulations and they do *not* result in an edge at the start of the
simulation. I am not certain because there is normally the reset
preventing a clock from being recognized.


Now, if you wrote:

always @(clk) begin
q<=d;
end

you would get a FF clocked on both edges, which is rare.
(Maybe they use them in DDR logic, but still rare.)

To the best of my knowledge there are *no* double edge FFs. DDR inputs
have separate FFs which capture the input on the opposite edges of the
clock, or they double the clock with a PLL and clock the data twice in
each clock cycle on the rising edge of the doubled clock.

Xilinx allows inference of "DualEdge" flip-flops for CoolRunner II
series only. Their guide shows this template:

always @ (negedge clock or posedge clock)
.. . .

Or for VHDL

process (clock)
begin
if (clock'event) then
.. . .

It's not clear why Verilog uses both edges rather than just:

always @ (clock)

which would work for simulation, perhaps they need to tell the
difference between a "clocked" vs combinatorial process, where
the case of "always @ (clock)" would ignore the sensitivity list.

-- Gabor
 
DDR input primitives usually use separate SDR registers with separate outputs for the rising and falling edge clocked values, and sometimes the negative edge clocked value is realigned with the rising edge of the clock.

DDR output registers do exist and are inferrable by some tools (at least Synplify). Synplify recommends inferring two SDR registers and a mux controlled by the clock level. Do not try this without ensuring that the synthesizer will convert it to a DDR register primitive.

The actual FPGA primitive implementation in the IOB is not clear; it could be two SDRs with an output mux selected by the clock level (and careful attention to silicon path delays to avoid glitches), or it could be a Flanter circuit. Both of these implementations can be driven to emulate either an SDR or DDR output register.

Finally, the synthesis standard 1076.6-2004 identifies the methods of describing a DDR register (two clocks or two edges of one clock). In the two-edge model, both edges are tested explicitly, so the above code would not work..

Finally, if your device does not support DDR registers, you can emulate one yourself with a Flancter circuit.

Andy
 
jonesandy@comcast.net wrote:
DDR input primitives usually use separate SDR registers with separate outputs for the rising and falling edge clocked values, and sometimes the negative edge clocked value is realigned with the rising edge of the clock.

DDR output registers do exist and are inferrable by some tools (at least Synplify). Synplify recommends inferring two SDR registers and a mux controlled by the clock level. Do not try this without ensuring that the synthesizer will convert it to a DDR register primitive.

The actual FPGA primitive implementation in the IOB is not clear; it could be two SDRs with an output mux selected by the clock level (and careful attention to silicon path delays to avoid glitches), or it could be a Flanter circuit. Both of these implementations can be driven to emulate either an SDR or DDR output register.

Finally, the synthesis standard 1076.6-2004 identifies the methods of describing a DDR register (two clocks or two edges of one clock). In the two-edge model, both edges are tested explicitly, so the above code would not work.

Finally, if your device does not support DDR registers, you can emulate one yourself with a Flancter circuit.

Andy
The CoolRunner II series from Xilinx, which is the only family where
I've seen support for dual edged flop inference, only use the dual
edge as a clock doubler, not to build a true DDR flip-flop that has
two D inputs. I've never seen a proper DDR flip-flop that you could
infer from HDL.

-- Gabor
 
jonesandy@comcast.net wrote:
On Tuesday, March 5, 2013 11:39:11 AM UTC-6, Gabor wrote:
snip...
I've never seen a proper DDR flip-flop that you could infer from HDL. -- Gabor

What synthesis tool(s) have you used?

Synplify supports HDL inference of DDR output registers for Virtex II and later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs.

Andy



I use XST because I can't afford a real synthesis tool. So what does
the code look like to infer a DDR register with D0 and D1, C0 and C1
inputs? I would think (at least for Verilog) it would need two
processes. Or can you only infer the register if the two clocks
are the complements of the same signal?

-- Gabor
 
On Tuesday, March 5, 2013 11:39:11 AM UTC-6, Gabor wrote:
snip...
I've never seen a proper DDR flip-flop that you could infer from HDL. -- Gabor

What synthesis tool(s) have you used?

Synplify supports HDL inference of DDR output registers for Virtex II and later devices, and for Spartan 3 and later devices. These DDR registers have two D inputs.

Andy
 
Gabor,

Per the reference manual, you use three processes: one for each (rise/fall)register, and one for a mux controlled by the clock level. You have to either use opposite edges of the same clock signal, or use two clocks from the same DCM that are 180 degrees apart in phase. As with most things in the reference manual, they often support additional means (e.g. a single process with two clocks or both edges of one clock, mutually exclusive, as specified in 1076.6). I know they support dual-edged processes in which the same signal/variable is not assigned on both edges, so I suppose you could do it in at most two, if not a single process (using variables for the registers and a mux assignment to the output signal after the last "end if":

process (rst, clk) is
variable qr, qf: std_logic;
begin
if rst then
qr := '0';
qf := '0';
elsif rising_edge(clk) then
qr := d;
elsif falling_edge(clk) then
qf := d;
end if;
output <= (qr and clk) or (qf and not clk);
end process;

It's been a long time since I used synplify for a xilinx platform, so I don't know if the 1076.6 method works or not (including a double-edge process with assignments on both edges to the same output signal). Note that synplify does not support inferrence for all target architectures that have DDR output registers.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top