Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

Verilog/SV: can assign + ternary produce latches?

pbernardi

Full Member level 2
Joined
Nov 21, 2013
Messages
129
Helped
27
Reputation
54
Reaction score
27
Trophy points
28
Activity points
988
Hello All,

Looking how a latch can be generated in Verilog/SV, normally the following case is cited:

- use of always@(*) where not all "reg" are updated (normally in cases where you have an "if" condition without a "else" condition when making combinational logic)

However, I have the feeling that the same condition can be achieved when using assign and ternary operator (?:), for example:

(note: code generated by head, might be inaccurate)


Code Verilog - [expand]
1
2
3
4
5
6
7
8
reg [7:0] a;
 
always@(*) 
begin
  if (res) a = 8'h00;
  else if (cond1) a = op1;
  else if (cond2) a = op2;
end



generates a latch, because there are conditions where "a" is not updated. This is equivalent of:


Code Verilog - [expand]
1
2
3
4
5
wire [7:0] a;
 
assign a = res ? 8'h00 : 
           cond1 ? op1 : 
           cond2 ? op2 : a;



But it seems the first one is always cited when generating latches and second one is never cited. Also, the tooling I use at the moment (Vivado 2018.3) does not detect latches in the second case.

I am missing something, or this is a case not covered normally, in a way even some (few? most? all?) tools cannot detect?
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
46,736
Helped
13,872
Reputation
27,992
Reaction score
12,516
Trophy points
1,393
Location
Bochum, Germany
Activity points
272,784
Yes, both codes are exactly equivalent.

Why do you need latch detection for the concurrent code, the latch condition has to be written explicitly on the R.H.S., hence it's quite obvious.
 

ThisIsNotSam

Advanced Member level 5
Joined
Apr 6, 2016
Messages
1,974
Helped
351
Reputation
702
Reaction score
344
Trophy points
83
Activity points
9,883
But it seems the first one is always cited when generating latches and second one is never cited. ?
you have to realise they are very different. in the assign case, a is explicitly assigned to itself. this is not the case in the procedural assignments... and that is why students tend to overlook it.
 

pbernardi

Full Member level 2
Joined
Nov 21, 2013
Messages
129
Helped
27
Reputation
54
Reaction score
27
Trophy points
28
Activity points
988
Thanks for the answers.

In fact, I had the idea that if I avoid using always@(*), I would avoid latches - mostly because the other case is never talked about. But now I see this is not always the case.

Also it bugs me that in some cases, I make a similar replacement from case 1 (always@(*)) to case 2 (assign) in my code, and Vivado stops generating latches - it does not show the warning during synthesis and does not show the latches in the build report. But I got some cases where the latch is correctly detected, so this bug (feature?) is not always consistent.
 

dave_59

Advanced Member level 3
Joined
Dec 15, 2011
Messages
812
Helped
361
Reputation
726
Reaction score
354
Trophy points
1,353
Location
Fremont, CA, USA
Activity points
6,239
This is one of the reason SystemVerilog has always_comb, always_latch, always_ff - to show and check your intent
 

ads-ee

Super Moderator
Staff member
Joined
Sep 10, 2013
Messages
7,531
Helped
1,763
Reputation
3,532
Reaction score
1,707
Trophy points
113
Location
USA
Activity points
55,484
Also it bugs me that in some cases, I make a similar replacement from case 1 (always@(*)) to case 2 (assign) in my code, and Vivado stops generating latches - it does not show the warning during synthesis and does not show the latches in the build report. But I got some cases where the latch is correctly detected, so this bug (feature?) is not always consistent.
This is because Vivado and previously ISE weren't always that great at language compliance. Over the years I'd seen all kinds of strange behaviors.

My recommendation is to only write code in specific proven ways that always synthesize correctly and don't diverge from that unless you've proven that a different coding style works well across multiple vendors tools. I also avoid using always@(*) a lot and anytime I use any always statement with an if statement I will write the if like this:
Code:
if () begin
end else if () begin
end else
end
and then fill in the rest of the code, makes it less likely you will forget to cover all branches.
 

vGoodtimes

Advanced Member level 4
Joined
Feb 16, 2015
Messages
1,070
Helped
304
Reputation
608
Reaction score
301
Trophy points
83
Activity points
8,520
More recently, like within the last 5-10 years, this style has started gaining traction. at least online.
Code:
always@(*) begin
  a = 0; // default.  might come from some registered version of "a" like "current_a" if desired.  or some input.  or some constant
  if (something) begin
    a = b;
  end else if (somethingelse) begin
    a = c;
  end
end
This style improves readability and avoids latches. Especially for always@(*) blocks with lots of outputs/cases.
 

Toggle Sidebar

Part and Inventory Search


Welcome to EDABoard.com

Sponsor

Sponsor

Design Fast


×
Top