3

I am a VHDL coder, and haven't coded much with Verilog. I am going through someone else's code, and I came across this:

always@(posedge asix_clk_bufg or negedge pll_asix_locked)
begin
    if (~pll_asix_locked)
        asix_rst <= 0;
    else if (timer[5])  // 355us between asix_clk and asix_rst (min is 200us)
        asix_rst <= 1;
end

I am not sure if I agree with the above code ! Isn't a possible latch scenario ? I see it is waiting for the pll to lock and then bring the system out of reset, but is this coded correctly?

I don't like to combine sequential and combinatorial code together, but what is the value of "asix_rst" when timer[5] = 0 ?!?

Thanks, --Rudy

Rudy01
  • 1,027
  • 5
  • 18
  • 32
  • How `asix_rst` is defined? – osgx Mar 12 '14 at 02:38
  • When timer[5] = 0 then asix_rst gets left alone. I got confused by that when I started doing verilog. You don't have to specify the value of every register in every case of a control structure, you just have to say when you want a value to be set. This code gives you something (conceptually) like a flip-flop with conditions for set and clear. It gets set when pll_asix_locked goes low, or on a positive edge of asix_clk_bufg but only if asix_clk_bufg is low. Asix_rst gets cleared when asix_clk_bufg goes high AND pll_asix_locked is high (because of the first if/else) AND timer[5] is high. – Will Mar 12 '14 at 14:07

2 Answers2

2

This is the way to infer a flip-flop with a positive edge clock (asix_clk_bufg) an asynchronous active low reset (pll_asix_locked) and a clock enable (timer[5]). There is a D input (tied to 1) and a Q output (asix_rst).

I assume that the PLL starts off not locked so asix_rst is 0 until the first clock edge when timer[5] == 1. It will then stay high until the PLL loses lock. The reset must be asynchronous since the clock will stop when the PLL loses lock.

I am guessing that the timer[5] bit goes high 5 or 6 clock cycles after the PLL is locked ensuring that there is a stable clock before the rest of the system comes out of reset.

This would be a latch if instead of the clock you had timer[5] in the sensitivity list like this:

always@(timer[5] or pll_asix_locked)
begin
    if (~pll_asix_locked)
        asix_rst <= 0;
    else if (timer[5])  // 355us between asix_clk and asix_rst (min is 200us)
        asix_rst <= 1;
end
nguthrie
  • 2,615
  • 6
  • 26
  • 43
  • This is a really good answer. It also shows why always @(*) can get you into trouble. – Will Mar 12 '14 at 14:02
1

Latches are only generated with combinational always blocks. Since the signal in the sensitivity list is looking for the posedge of the clock, the code is generating sequential logic. Sequential logic will never generate a latch.

For more information read about how transparent latches are created and how to avoid inferring latches

Russell
  • 3,384
  • 4
  • 31
  • 45