Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

state machine with asynchronous reset?

892 views
Skip to first unread message

glen herrmannsfeldt

unread,
Oct 4, 2004, 9:13:35 PM10/4/04
to

I am trying to figure out how to write a synthesizable state
machine with async. reset. I have a fine synchronous reset,
which starte something like:

always @(posedge clk) begin
if(reset) state <= s0;
else case (state)

I have tried

always @(posedge clk or posedge reset) begin
if(reset) state <= s0;
else case (state)

but it doesn't work, at least it doesn't synthesize an asynchronous
reset, and it doesn't seem to simulate right, either.

I have also tried separate always @(posedge clock) and
always @(posedge reset) blocks, which usually get complaints
about driving the same net two different places.

Is there a nice way to do this?

-- glen

mk

unread,
Oct 5, 2004, 3:59:58 AM10/5/04
to
On Mon, 04 Oct 2004 18:13:35 -0700, glen herrmannsfeldt
<g...@ugcs.caltech.edu> wrote:
>I have tried
>
>always @(posedge clk or posedge reset) begin
> if(reset) state <= s0;
> else case (state)
>
>but it doesn't work, at least it doesn't synthesize an asynchronous
>reset, and it doesn't seem to simulate right, either.

That's the definition of not working all right :-) The problem is that
it should because it seems to be the right way of inferring an async
reset. What is the synthesis report saying ? What result are you
getting from the simulation ? One issue which may complicate the
things is the definition of s0. Is it constant resolvable at compile
time ?

J o h n _ E a t o n (at) hp . com (no spaces)

unread,
Oct 5, 2004, 7:56:19 PM10/5/04
to

Try replacing if(reset) state <= 'b0; to see if that works.
It has to be known at compile time or you will get some really
gross logic.


Why do you want to use an asynchronous reset? You have to filter
the leading edge or have the first runt pulse on your reset_pad
send your SM off to la-la land. You also have to filter the
trailing edge to guarentee your setup/hold on reset to clk.
You'll wind up with a sync reset anyway.


The only flops that really NEED an async reset are those that
directly drive an output pad and those should also have an
additional sync reset to prevent clk reset setup issues.

John Eaton


glen herrmannsfeldt

unread,
Oct 6, 2004, 12:56:20 PM10/6/04
to

J o h n _ E a t o n (at) hp . com (no spaces) wrote:

> glen herrmannsfeldt wrote:

>> I am trying to figure out how to write a synthesizable state
>> machine with async. reset.

(snip)

>> I have tried

>> always @(posedge clk or posedge reset) begin
>> if(reset) state <= s0;
>> else case (state)

>> but it doesn't work, at least it doesn't synthesize an asynchronous
>> reset, and it doesn't seem to simulate right, either.

>> I have also tried separate always @(posedge clock) and
>> always @(posedge reset) blocks, which usually get complaints
>> about driving the same net two different places.

(snip)

> Try replacing if(reset) state <= 'b0; to see if that works.
> It has to be known at compile time or you will get some really
> gross logic.

I should have included that before. The states are described
in parameter statements. This is compiled by Quartus II, where
Altera recommends parameter statements for state machine states.

I believe the compiler is supposed to recognize that it is a
state machine and compile it appropriately.

> Why do you want to use an asynchronous reset? You have to filter
> the leading edge or have the first runt pulse on your reset_pad
> send your SM off to la-la land. You also have to filter the
> trailing edge to guarentee your setup/hold on reset to clk.
> You'll wind up with a sync reset anyway.

Well, I probably don't need it. Since all the FF's have
reset inputs it seemed nice to use them. I am adding this
to an existing design which does have async. resets (for
logic that is not a state machine).

> The only flops that really NEED an async reset are those that
> directly drive an output pad and those should also have an
> additional sync reset to prevent clk reset setup issues.

I will stick with the synchronous reset for now. At some point
it would be nice just to understand why it didn't work, though.

thanks,

-- glen

glen herrmannsfeldt

unread,
Oct 6, 2004, 2:30:03 PM10/6/04
to

mk wrote:

>>I have tried

parameter s0=3'b000;

Altera recommends parameters for state machine states.

Without posedge reset in the dependency list it seems to
simulate and synthesize a synchronous reset just fine.

Just adding posedge reset, and with the if(reset) still there,
the simulation doesn't seem to change state at all.
RTL viewer shows little blocks with sm_reset inputs, instead
of the normal FF's that were generated before. Also, inverted
reset is added as an enable input on all other FF's, such as
a counter used by the state machine.

If I do:

always @(posedge reset) state <= s0;

always @(posedge clk) begin
case (state)

I get:

Error: Can't resolve multiple constant drivers for net
state.s3 at output_state.v(84)
Error: Constant driver at output_state.v(155)

as it realized that both could happen at the same time.

(The line numbers are the end statement of the appropriate
always block.)

This is for ACEX 1K where all FF's have asynchronous reset
inputs, as in most FPGA's. Though probably synchronous
reset will work just fine.

-- glen

Chris Alexander

unread,
Oct 7, 2004, 7:17:23 PM10/7/04
to
Your code looks correct. Without seeing anything else, I would have
to assume it is either a synthesis problem or a problem with your
target technology (ie, the device _doesn't allow_ async resets.

I have some questions that maybe will help find the answer:

- What version of Quartus are your running?
- What happens if you target a different device, say a Cyclone EP1C3?
- Can you try a different synthesis tool? Either Synplify or the
Xilinx XST tool from the webpack distribution will give you a second
data point / different wording of the error message.

Chris

glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote in message news:<cjss5i$ccf$1...@gnus01.u.washington.edu>...

glen herrmannsfeldt

unread,
Oct 7, 2004, 8:15:55 PM10/7/04
to

Chris Alexander wrote:

> Your code looks correct. Without seeing anything else, I would have
> to assume it is either a synthesis problem or a problem with your
> target technology (ie, the device _doesn't allow_ async resets.

> I have some questions that maybe will help find the answer:

> - What version of Quartus are your running?

4.0

> - What happens if you target a different device, say a Cyclone EP1C3?

I haven't tried that. Good question.

> - Can you try a different synthesis tool? Either Synplify or the
> Xilinx XST tool from the webpack distribution will give you a second
> data point / different wording of the error message.

(snip regarding async. reset on state machines)

One more question.

It seems that some Altera examples I see have two state
variables, where one is assigned to and the other is used
in the case statement. It seems that isn't ordinarily
necessary, clutters up the code, and otherwise doesn't
help.

Something like:

always @(posedge clk or posedge reset) begin
if(reset) state <= s0;

else state <= next_state;
end

always @(state) case(state)
s0: if(something) next_state <= s1;

I suppose it is less confusing to some people
not to assign to the state variable, but, at least in
the synchronous reset case it seems to be fine.
(Putting the case statement inside an
always @(posedge clk) block seems enough for me.)

Under some conditions, I would get errors relating to
multiple assignments to the same net, even though I had
appropriate if statements, yet other times Quartus would not
complain about it.


Say, for example:

always @(posedge reset) state <- s0;

always @(posedge clk) case(state)
s0: state <= s1;

Now, theoretically posedge clk and posedge reset
could occur at the same time, and it would be
ambiguous, but then that is true of async. reset
in any case.

Well, I have started to get used to synchronous reset
now, though the FF's do still have a reset input.

-- glen

Rob Dekker

unread,
Oct 12, 2004, 11:29:11 PM10/12/04
to
Hi Glen,

I dont think your problem has anything to do with async/sync reset.

You assign reg 'state' from two different always statements simultaneously.
That's two concurrent assignments, which is the cause of the synthesis error,
and the mismatch in simulation.

If you code up your state machine in two always statements (register in one,
and state-transition (case) statement in the other, you have to use two variables.
Use 'state' and 'next_state' just like Quartus's manual subscribes.

I am actually surprised that you did not get the error in the 'synchronous' case.

Cheers

Rob


"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:ck4m51$f4q$1...@gnus01.u.washington.edu...

glen herrmannsfeldt

unread,
Oct 13, 2004, 2:30:07 AM10/13/04
to
Rob Dekker wrote:

> I dont think your problem has anything to do with async/sync reset.

> You assign reg 'state' from two different always statements simultaneously.
> That's two concurrent assignments, which is the cause of the synthesis error,
> and the mismatch in simulation.

> If you code up your state machine in two always statements (register in one,
> and state-transition (case) statement in the other, you have to use two variables.
> Use 'state' and 'next_state' just like Quartus's manual subscribes.

> I am actually surprised that you did not get the error in the 'synchronous' case.

(snip)

>>always @(posedge clk or posedge reset) begin
>> if(reset) state <= s0;
>> else state <= next_state;
>>end
>>
>>always @(state) case(state)
>>s0: if(something) next_state <= s1;

Well, in most cases there is an if to separate them.

The synchronous case is something like:

always @(posedge clk) begin
if(reset) state <= s0;
else case(state)

As only one branch of the if can be taken, only
one assignment applies, and the simulator seems
to figure that out. For the asynchronous case,
adding posedge reset to the always statement,
it doesn't figure it out. (That is, still with
one always statement.)

Depending on exactly the way I arrange it, sometimes
it would complain even though there was an if, and sometimes
not even without an if. (Some with one, some with two
always statements.)

>>I suppose it is less confusing to some people
>>not to assign to the state variable, but, at least in
>>the synchronous reset case it seems to be fine.
>>(Putting the case statement inside an
>>always @(posedge clk) block seems enough for me.)

Until recently, most of my verilog was structural model,
except for registers. Lately I have been doing state
machines and am becoming more comfortable with what the
synthesizer can do with behavioral code.

thanks,

-- glen

Chris Alexander

unread,
Oct 13, 2004, 3:38:02 PM10/13/04
to
Rob - I think you misread his post. The 2 always statements are
assigning different variables. The first is "state", the second is
"next_state"...

"Rob Dekker" <r...@verific.com> wrote in message news:<bi1bd.29256$QJ3....@newssvr21.news.prodigy.com>...

glen herrmannsfeldt

unread,
Oct 13, 2004, 4:51:15 PM10/13/04
to

Chris Alexander wrote:
> Rob - I think you misread his post. The 2 always statements are
> assigning different variables. The first is "state", the second is
> "next_state"...

I have done many different combinations of always
statements, if statements, and assignments.

My preference is one always statement and one state
variable, and it works fine for the synchronous case.

At one point I thought it was confused between the
clock and reset lines, so I tried two always blocks.

I have been just about convinced that synchronous reset
is better, though it would still be nice to know how to
do asynchronous reset.

always @(posedge clk or posedge reset) if(reset) out <= 0;
else if(enable) begin
if(up) out <= out+1;
else out <= out-1;
end

Does seem to generate a counter with asynchronous reset,
as I thought it should.

-- glen

Rob Dekker

unread,
Oct 14, 2004, 1:09:04 AM10/14/04
to

"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:ckk45g$7e5$1...@gnus01.u.washington.edu...

>
>
> Chris Alexander wrote:
> > Rob - I think you misread his post. The 2 always statements are
> > assigning different variables. The first is "state", the second is
> > "next_state"...

You are right. I read the two alternatives as a single piece of code...

>
> I have done many different combinations of always
> statements, if statements, and assignments.
>
> My preference is one always statement and one state
> variable, and it works fine for the synchronous case.

The trouble with a FSM with async reset in a single always statement are the output assignments.

The outputs are automatically clocked (since they are in the single case statement), so they create registers.
But if you forgot to also async reset them in the same always statement, you get a tricky circuit
(with the state register asyncronously reset, but the output registers in 'hold' state (probably synchronous) when the reset
occurs.

That problem is not there if you use two always statements, since the outputs are not clocked.
You can still decide to clock them in a separate other always statement, where they will be clearly visible.

>
> At one point I thought it was confused between the
> clock and reset lines, so I tried two always blocks.
>
> I have been just about convinced that synchronous reset
> is better, though it would still be nice to know how to
> do asynchronous reset.
>
> always @(posedge clk or posedge reset) if(reset) out <= 0;
> else if(enable) begin
> if(up) out <= out+1;
> else out <= out-1;
> end
>
> Does seem to generate a counter with asynchronous reset,
> as I thought it should.

Glen, are you willing to share the entire single always statement with us ?

If you get a counter with async reset from the above example, you should get a FSM with async reset also...

>
> -- glen
>


0 new messages