completing IF and CASE statements to avoid inferring latchs

M

mr

Guest
Hi,

I have a problem in completing the IF or CASE statements and avoid
inferring latchs. My design should retain the previous values of
registers for the ELSE or DEFAULT case conditions. What values should
I assign to the regs in the ELSE and DEFAULT to avoid creating the
latchs and still retain the old value.

example-1:

if (sel)
out <= in1;
end //cretaes latch for not having "else" part

example-2

if (sel)
out <= in1;
else
out <= out; // retains the old value but still creates the latch
end

Any help is greatly appreciated.

Thanx in advance
mr
 
Since you said your registers need to retain values, I can assume one
of two things from your code: Either it is enclosed in a clocked
(synchronous) block, or it is in a combinatorial block whose output
feeds a register. In a synchronous block, you won't get a latch anyway
(it will infer a clock enable or feedback mux if necessary). In a
combinatorial block, you should reassign out (which I'm assuming feeds
a register input somewhere) not with itself, but with the output of
that register.

On combinatorial blocks, latches and completing if/case statements, I
find it is much easier to make sure that anything assigned anywhere in
the block is also unconditionally assigned a default value at the top
of the block, just to make sure there are no paths through the block
that won't assign a value to it. This technique is much easier to
review/audit as well.

However, the best way to avoid latches is to avoid combinatorial
blocks whenever possible. Use synchronous blocks and fold the
combinatorial logic into them, and you won't get any latches.

Andy
 
On May 25, 6:16 pm, Andy <jonesa...@comcast.net> wrote:
Since you said your registers need to retain values, I can assume one
of two things from your code: Either it is enclosed in a clocked
(synchronous) block, or it is in a combinatorial block whose output
feeds a register. In a synchronous block, you won't get a latch anyway
(it will infer a clock enable or feedback mux if necessary). In a
combinatorial block, you should reassign out (which I'm assuming feeds
a register input somewhere) not with itself, but with the output of
that register.

On combinatorial blocks, latches and completing if/case statements, I
find it is much easier to make sure that anything assigned anywhere in
the block is also unconditionally assigned a default value at the top
of the block, just to make sure there are no paths through the block
that won't assign a value to it. This technique is much easier to
review/audit as well.

However, the best way to avoid latches is to avoid combinatorial
blocks whenever possible. Use synchronous blocks and fold the
combinatorial logic into them, and you won't get any latches.

Andy
Thanks Andy. This is my always stmt

always @ (posedge clk, negedge reset, negedge CS)

I didn't have anything to do with when chip select CS = 1. I have the
logic coded for reset = 0/1 and CS = 0 but when CS = 1 nothing to do;
just retain the current state. I think this causing all the regs I
used in this always block to infer latchs.


Thanks
mr
 
On Mon, 25 May 2009 07:20:34 -0700 (PDT), mr <mahenreddy@gmail.com>
wrote:
always @ (posedge clk, negedge reset, negedge CS)

I didn't have anything to do with when chip select CS = 1. I have the
logic coded for reset = 0/1 and CS = 0 but when CS = 1 nothing to do;
just retain the current state. I think this causing all the regs I
used in this always block to infer latchs.
I'm not sure if you really meant to include 3 edge page conditions in
your always time control. Normally you include only clocks and
asynchronous control signals in the your timing control exprression.
The above expression will generate a DFF with two async set/reset
signals (do you have them in your library?).
If this is not your intention, ie if you only wanted an async reset
register and CS as a control signa, you can remove it from the
sensitivity list:

always @(posedge clk, negedge reset)
begin
if (!reset)
begin
// reset all regs here
end
else if (!CS) // ie CS==0 on posedge clk
begin
// update your regs here
end
end

this should give you clean DFFs in your design.

One thing I need to say here even though you may realize it but when
you have an edge based sensitivity list, you will get DFFs as storage
to store the current value of your registers. It's very rare to get
latches in addition to DFFs.
Maybe you can reduce your code just to one register which shows a DFF
and a latch and post here so to be commented.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On May 26, 12:51 am, Muzaffer Kal <k...@dspia.com> wrote:
On Mon, 25 May 2009 07:20:34 -0700 (PDT), mr <mahenre...@gmail.com
wrote:



always @ (posedge clk, negedge reset, negedge CS)

I didn't have anything to do with when chip select CS = 1. I have the
logic coded for reset = 0/1 and CS = 0 but when CS = 1 nothing to do;
just retain the current state. I think this causing all the regs I
used in this always block to infer latchs.

I'm not sure if you really meant to include 3 edge page conditions in
your always time control. Normally you include only clocks and
asynchronous control signals in the your timing control exprression.
The above expression will generate a DFF with two async set/reset
signals (do you have them in your library?).
If this is not your intention, ie if you only wanted an async reset
register and CS as a control signa, you can remove it from the
sensitivity list:

always @(posedge clk, negedge reset)
begin
        if (!reset)
        begin
                // reset all regs here
        end
        else if (!CS)   // ie CS==0 on posedge clk
        begin
                // update your regs here
        end
end

this should give you clean DFFs in your design.

One thing I need to say here even though you may realize it but when
you have an edge based sensitivity list, you will get DFFs as storage
to store the current value of your registers. It's very rare to get
latches in addition to DFFs.
Maybe you can reduce your code just to one register which shows a DFF
and a latch and post here so to be commented.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
Muzaffar, Thanks. I am still learning HDL and experimenting to
understand the cases where a FF or latch gets created. Please look at
the code below.

always @(posedge clk, negedge reset, negedge CS)
begin
if (!reset) // Line-1
treg <= 8'b0; // Line-2
else if (!CS) // Line-3
datao <= treg; // Line-4
else // Line-5
treg <= 8'b0; // Line-6
end // Line-7


The above code is creating a FF for treg though treg needs to retain
its value when reset = 1 and CS= 0; But when I comment Line -5 and
Line -6 I get a warning “Latch inferred for treg as it needs to retain
its previous value in one of the paths”.

In both the above cases treg needs to retain its previous value when
reset = 1 and CS= 0 but I get “Latch inferred” warning only in the 2nd
case for treg. Why?

As you said, If I remove CS from sensitivity list and I don’t get the
Latch inferred warning at all. In the aboev code, like CS, Reset is
also asynchroous but I don't get latch inferred warning if treg needs
to retain its value when Reset = 1.

What am I missing?

-mr
 
On Tue, 26 May 2009 03:37:19 -0700 (PDT), mr.mahenreddy@gmail.com
wrote:
always @(posedge clk, negedge reset, negedge CS)
begin
if (!reset) // Line-1
treg <= 8'b0; // Line-2
else if (!CS) // Line-3
datao <= treg; // Line-4
else // Line-5
treg <= 8'b0; // Line-6
end // Line-7

As you said, If I remove CS from sensitivity list and I don’t get the
Latch inferred warning at all. In the aboev code, like CS, Reset is
also asynchroous but I don't get latch inferred warning if treg needs
to retain its value when Reset = 1.

What am I missing?
You are missing the right way to infer FFs. To infer FFs correctly you
need as many 'if/else if's as you have async set/resets and a final
'else' for the clock event so the above code generates a DFF with the
caveat that CS async event will cause you problems. Async set/resets
should be constants.
If you remove line 5,6 you don't have a clocked process anymore so
only reset & cs are controlling the storage and this gives you a latch
for storage not a FF. The latch is transparent while CS==0 and
remembers while CS==1.


Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services
http://www.dspia.com
 
On May 26, 3:37 am, mr.mahenre...@gmail.com wrote:
On May 26, 12:51 am, Muzaffer Kal <k...@dspia.com> wrote:



On Mon, 25 May 2009 07:20:34 -0700 (PDT), mr <mahenre...@gmail.com
wrote:

always @ (posedge clk, negedge reset, negedge CS)

I didn't have anything to do with when chip select CS = 1. I have the
logic coded for reset = 0/1 and CS = 0 but when CS = 1 nothing to do;
just retain the current state. I think this causing all the regs I
used in this always block to infer latchs.

I'm not sure if you really meant to include 3 edge page conditions in
your always time control. Normally you include only clocks and
asynchronous control signals in the your timing control exprression.
The above expression will generate a DFF with two async set/reset
signals (do you have them in your library?).
If this is not your intention, ie if you only wanted an async reset
register and CS as a control signa, you can remove it from the
sensitivity list:

always @(posedge clk, negedge reset)
begin
        if (!reset)
        begin
                // reset all regs here
        end
        else if (!CS)   // ie CS==0 on posedge clk
        begin
                // update your regs here
        end
end

this should give you clean DFFs in your design.

One thing I need to say here even though you may realize it but when
you have an edge based sensitivity list, you will get DFFs as storage
to store the current value of your registers. It's very rare to get
latches in addition to DFFs.
Maybe you can reduce your code just to one register which shows a DFF
and a latch and post here so to be commented.
--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com

Muzaffar, Thanks. I am still learning HDL and experimenting to
understand the cases where a FF or latch gets created. Please look at
the code below.

always @(posedge clk, negedge reset, negedge CS)
begin
        if (!reset)                    // Line-1
           treg <= 8'b0;       // Line-2
        else if (!CS)               // Line-3
           datao <= treg;     // Line-4
        else                            // Line-5
          treg <= 8'b0;        // Line-6
end                            // Line-7

The above code is creating a FF for treg though treg needs to retain
its value when reset = 1 and CS= 0; But when I comment Line -5 and
Line -6 I get a warning “Latch inferred for treg as it needs to retain
its previous value in one of the paths”.

In both the  above cases treg needs to retain its previous value when
reset = 1 and CS= 0 but I get “Latch inferred” warning only in the 2nd
case for treg. Why?

As you said,  If I remove CS from sensitivity list and I don’t get the
Latch inferred warning at all. In the aboev code, like CS, Reset is
also asynchroous but I don't get latch inferred warning if treg needs
to retain its value when Reset = 1.

What am I missing?

-mr
a) What tool are you using that is giving you the latch warning?

b) You should not have CS in the sensitivity list. There are two
basic templates for
creating a resetable register in Verilog, one for async reset and one
for sync reset:

// async reset:
always @(posedge clk or negedge reset)
if (!reset)
treg <= 8'b0;
else if (!CS)
treg <= new_data

// sync reset:
always @(posedge clk)
if (!reset)
treg <= 8'b0;
else if (!CS)
treg <= new_data

Of course, if have a positive true reset, you need to change the async
version to say posedge reset and delete the ! in the logic.

Note that for clocked logic, the only things should should appear in
the sensitivity
list are the clock and the reset/preset (if async set/clr). You
should not put
data or chip selects in the sensitivity list - you won't be
describing the logic
you probably want.

John Providenza
 

Welcome to EDABoard.com

Sponsor

Back
Top