Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Inferred latches for variables

I have problem in determine wat is the actual problem given by these two warnings:

Warning (10235): Verilog HDL Always Construct warning at decimal_to_binary.v(32): variable "count" is read inside the Always Construct but isn't in the Always Construct's Event Control

Warning (10240): Verilog HDL Always Construct warning at decimal_to_binary.v(29): inferring latch(es) for variable "b", which holds its previous value in one or more paths through the always construct

here is part of my code:

module decimal_to_binary (trigger, trigger_A, trigger_B, inputA, inputB, A, B, C, D, E, F, G, H, I, J);

input A, B, C, D, E, F, G, H, I, J;

reg [3:0] count=4'b0000;

input trigger;

input trigger_A;

input trigger_B;

output reg [31:0] inputA;

output reg [31:0] inputB;

reg [31:0] stage [9:0];

integer a, b, c, d, e, f, g, h, i, j;

always@(trigger)

begin

if(trigger == 1)

count = count + 1;

case(count)

1:

begin

if(A == 1)

a = 0000000000;

else if(B == 1)

b = 1000000000;

else if(C == 1)

c = 2000000000;

else if(D == 1)

d = 3000000000;

else if(E == 1)

e = 4000000000;

stage[0] = a + b + c + d + e + f + g + h + i + j;

a = 32'b00000000000000000000000000000000;

b = 32'b00000000000000000000000000000000;

c = 32'b00000000000000000000000000000000;

d = 32'b00000000000000000000000000000000;

e = 32'b00000000000000000000000000000000;

f = 32'b00000000000000000000000000000000;

g = 32'b00000000000000000000000000000000;

h = 32'b00000000000000000000000000000000;

i = 32'b00000000000000000000000000000000;

j = 32'b00000000000000000000000000000000;

end

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Did you possibly mean to write an edge sensitive always block? An always block without a posedge or negedge event expression generates only combinational logic. Most likely it doesn't work as you intended.

    At begin of the block, you have a counter without a clock. It will never work in hardware Verilog, although it possibly gives meaningful results in a functional simulation.

    always@(trigger)
    begin
    if(trigger == 1)
    count = count + 1;

    Consider, what you want to achieve and consult a Verilog textbook or Quartus Verilog templates about how it can be coded.

    As a first attempt, you can just try

    always @(posedge trigger)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Since I'm not exactly sure what you are trying to do I'll give this advice:

    • Don't assign anything to an integer type (I'm not sure if all synthesis tools will behave the same .... considering I've never seen someone attempt this before)

    • Don't mix case and if statements in a single always block

    • Control a-j independently (separate always blocks)

    • If you intended to use registers use a clock edge for the always block and use enables to control when values get registered by the flip flop
    I could keep making suggestions but I think it would be quicker if you just describe what you are attempting to synthesize. If you go into Quartus II with your verilog file open and select from the edit menu "Insert Template" you'll see all kinds of pre-cooked templates for writing various logic blocks. I also recommend taking a look at this document, it'll explain the various cases when you get a latch out of synthesis and how to avoid it. http://www.altera.com/literature/hb/qts/qts_qii51007.pdf
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I added in (posedge trigger) to my code, but it seems not to be working. This is because I only set trigger signal to be high only at certain period. But once I put trigger signal into repeated occurence, just like a CLK, it does give an output with a wrong result.

    Can it be possible that I use my posedge CLK as my 1st check list before proceed to check for posedge of my trigger signal? What I mean is that.. I only wan to increment the counter by 1 bit when i pressed trigger signal..

    Can it possible to use always statement twice? like

    always@(posedge CLK)

    always@(trigger)

    plz enlight me.. Thanks

    Regards,

    Robbie
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    No that is not possible.

    What is possible, and correct, is to write it like this:

    
    always@(posedge CLK) begin : detect_trigger
       if (trigger) begin : trigger_active_at_clk_rising_edge
         count <= count + 1; // count up
       end
    end
    
    This produces FPGA friendly code. But it will only work if trigger is active longer than on clk cycle period and less than two clk cycle periods.

    If you want it to also work when trigger is active for longer periods, than you need to store a auxiliary state variable trigger_d

    
    always@(posedge CLK) begin : detect_trigger
       logic trigger_d;
       if (trigger & ~trigger_d) begin : trigger_active_at_clk_rising_edge
         count <= count + 1; // count up only at the rising edge of trigger
       end
       trigger_d <= trigger; // delay it one clk cycle in order to look into the past
    end
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Sorry, but I don't exactly understand what you try to achieve. In you're above code, there is no CLK input signal. For this reason, I suggested to use trigger as a clock with a posedge condition. What's wrong when you do this?

    I forgot to mention, that the if (trigger == 1) condition must be removed with posedge trigger, otherwise it's still an asynchronous event.

    always@(trigger)
    begin
    count = count + 1;
    // ....
    end

    The event condition of an always block can be either asynchronous (creates combinational logic) or synchronous (creates flip-flops). But only one event condition can be in effect for a particular code block.

    If you want to detect a rising edge of the trigger input but not use trigger as a clock, you can perform a synchronous edge detection in your main clock domain.

    reg trigger_sync, trigger_s_prev;
    always @(posedge CLK)
    begin
      trigger_sync <= trigger;
      trigger_s_prev <= trigger_sync;
      if (trigger_sync && !trigger_s_prev)
        count <= count + 1;
      case (count)
      endcase
    end
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks to all advices that u all gave to me. My program now is working and ready to be downloaded into the DE2 board.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Guys, my search for solution shows that 74*373 chip type is not possible to model in hardware. Please confirm, or provide the working example of the transparent latch, which works IN SILICON.

    - There're lots of exapmles of the transparent latch on the web (including wikipedia, which, while is not accepted by academics as reliable source, is deemed as one of the publicly validated source);

    - FvM says "you have a counter without a clock. It will never work in hardware Verilog, although it possibly gives meaningful results in a functional simulation."

    - Some XILINX document also says "Most Xilinx FPGAs do not support latches very well. If your code includes latches either intentionally or

    by accident, you will get a warning about “latch inferred in design” and should remove them."

    I get this warning. I am not sure it works properly after FvM's comment. I need to be sure that it works as I expect.