Forum Discussion

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

Shift registers can be dangerous!

(note: re-posted from my blog.

http://xiaoleicestustc.blogspot.sg/2013/10/shift-registers-can-be-dangerous.html

The photo mentioned in my original post is in the attachment)

During the last two days, I have been debugging an issue on FPGA, and found in the end that the root cause is a 4-bit shift register.

See the photo below, which I drew to illustrate. It is a shift right register, and there are inverters at D input of bit 3 and bit 2. These four bits will be reset to "0000", and becomes, at consecutive rising clock edges, "1100", then "1010", then "1001", and back to "0000", and repeats the pattern. Looks like a normal and safe design, right?

What went wrong on FPGA in my case was that, I observed that these four bits would be stuck at "1000" after my FPGA was running some FW code for about 20 mins. I still am not quite sure whether these four bits become "1000" due to having latched some glitches. But once they become "1000", they will stay there, for ever. You can do the logic yourself.

As a result of this stuck, one important clock signal in my hardware design would be gone, which in turn would cause the FW to hang at a particular FOR loop. (Of course I am now in hindsight. In fact it took my colleague David and me almost one working day of debugging to trace from the hang FW back to this shift register).

As I see from this incident, shift registers can be dangerous!

13 Replies

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

    Hi, Kaz,

    Yes, my RTL code resets to 1000, and does not have any inverters. But in the synthesized netlist, I see the two inverters.

    And I think in Stratix III FPGA I use, registers cannot be rest to '1'. So I believe all 4 registers reset to '0'.

    --- Quote Start ---

    Now your code does not have inverters and resets to 1000. Your first post have two inverters and resets to 0000

    --- Quote End ---

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

    --- Quote Start ---

    Yes, my RTL code resets to 1000, and does not have any inverters. But in the synthesized netlist, I see the two inverters.

    And I think in Stratix III FPGA I use, registers cannot be rest to '1'. So I believe all 4 registers reset to '0'.

    --- Quote End ---

    Yes, the same with all newer Altera FPGAs. That's why I assumed you are showing a gate level netlist.

    If the clock source itself is stable, I'm sure that the reset synchronizer will solve the problem.

    I think, it's a simple and convincing example about the necessity of reset synchronizers.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi All,

    For this problem I encountered, I tried two ways to solve it:

    1. I don't use "shift register" at all. I use a two-bit counter instead. This counter resets to 0, and, at clock rising edge, increments to 1, 2, 3, and back to 0. See the RTL code below. Note that here the RST_N signal is NOT synchronized with ADC_CLK. I found this code works for me to solve my problem. But I think it is still better to use a synchronized reset signal.

      In my original RTL, I used the 4-bit shift register as a kind of "one-hot" encoding, to generate a timing signal. Now I use this 2-bit counter as "binary" encoding, to generate the same timing signal.

      I chose to replace the 4-bit shift register with the 2-bit counter, because I think this 2-bit counter is safe (because counter never gets stuck at a particular value).

          process (ADC_CLK, RST_N)
          begin
              if RST_N = '0' then
                  cnt2 <= 0;
              elsif rising_edge(ADC_CLK) then
                  if (cnt2 = 3) then
                      cnt2 <= 0;
                  else
                      cnt2 <= cnt2 + 1;
                  end if;
              end if;
          end process;

    2. The second method I tried is to keep the 4-bit shift register and use a synchronized reset signal. The way to synchronize I have explained in my previous reply.

    I have generated two bitmaps using each of the two methods, and tested using the same test FW that exposed this problem in the beginning. I see that both bitmaps can pass my test.

    Thank you for all your replies :)