Forum Discussion

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

The need for error correction codes

Hello,

I'm working on digital design for the first time since college and I'm unclear on how much error correction is needed in FPGA/CPLD systems. Here's the situation:

My design will sync the timing of 12 buck converters capable of driving 130 amps each. In other words, there is a lot of power being controlled by the design. The MAX II simply needs to give each converter a 100 ns pulse every 9.6 uS, with an 800 ns stagger between each converter.

I've already successfully implemented this in simulation. The system clock feeds a counter which is decoded to control the advancement from each state to its next state, with appropriate output generated by decoding the current state and passing through a clocked register.

The problem is that I'm so inexperienced with these systems that I'm not sure if I can expect errors to occur in registers and in transfers between them, and if these errors are seen, how sophisticated of an error correcting algorithm would be appropriate? I've read about Hamming codes and so forth, but I really need to know how this is handled in general practice.

I'd love for someone to tell me that error correction is more for noisy transmission lines than internal register transfers inside an FPGA, and to just not worry about it. The problem is what to do with the "when others" statements that won't keep me up at night thinking about what could go wrong in a system controlling almost 1600 amps.

Thanks in advance,

Jon

9 Replies

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

    I haven't heard of anyone doing error correction internal to programmable logic other than for soft errors (single event upset) caused by external radiation. Device families like Stratix III have built-in error detection for that. I expect that MAX II has an extremely low probability of this kind of error.

    Your bigger risk will be from anything that does not follow proper design practices.

    Be sure that you have full constrained the timing and run the timing analysis with both slow and fast models.

    Be extra careful with anything asynchronous in the design. If you are using asynchronous resets, run recovery and removal analysis or make certain that your design does not need this analysis. If you have more than one clock (sounds like you probably don't), be extra careful crossing between clock domains. Don't have any logic in your clock path (don't use any ripple or gated clocks). Run the Design Assistant to see whether it finds any potential problems.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I 100% agree with Brad, if all the design precautions are taken, you won't experience internal register errors due to electro-magnetic interference. Anyway, if you want sweet dreams at night, you may put your FPGA board inside a shielding box. Really not more than this...

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

    --- Quote Start ---

    The problem is what to do with the "when others" statements...

    --- Quote End ---

    Do not use latches, whether intentionally or unintentionally. See "Unintentional Latch Generation" in the Quartus handbook, Volume 1, Section II, Chapter 6.

    The "State Machines" section of that chapter says this about "when others":

    --- Quote Start ---

    Many synthesis tools (including Quartus II integrated synthesis) have an option to implement a safe state machine. The software inserts extra logic to detect an illegal state and force the state machine’s transition to the reset state.

    --- Quote End ---

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

    Thank you very much for your replies. I am relieved to hear that I won't need to expect errors in register transfers, although I should add that the "single event upsets" were my primary concern, but it looks like you guys consider this a very rare occurance.

    So then just a couple more questions: First off, would you recommend a null statement for the "when others" cases?

    Also, I ran the timing analysis in both modes as suggested, and while there were no paths that failed, I am unclear on how margin to expect in minimum slack times. For instance, the "Fast model clock hold" minimum slack is only 0.397 ns. I am running a 20 MHz clock. Is this acceptable?

    I am attaching my code below in case anyone would care to take a look.

     
    library ieee ;
    use ieee.std_logic_1164.all;
    use IEEE.std_logic_unsigned;
    entity FPG_SYNC is
    port( clk:  in std_ulogic;
      output: out std_logic_vector(11 downto 0) := "000000000000"
    );
    end FPG_SYNC;
    -----------------------------------------------
    architecture behv of FPG_SYNC is
    signal counter: natural := 0;
    signal outputenable: boolean := true;
    signal state: std_logic_vector(3 downto 0) := "0000";
    signal nextstate: std_logic_vector(3 downto 0) := "0001";
    signal laststate: std_logic_vector(3 downto 0) := "0000";
    begin
     syncproc: process (clk) is
     begin
      if (clk'event and clk='1') then
     
       counter <= (counter + 1);
     
       case counter is
        when 0 =>
         outputenable <= true;
         state <= nextstate;
        when 2 =>
         outputenable <= false;
        when 15 =>
         counter <= 0;
        when others =>
         null;
       end case;
      end if;
     end process syncproc;
     
     NScombproc: process(state) is
     begin 
      case state is
       when "0000" =>            -- "0000" is the reset state
        nextstate <= "0001";
       when "0001" => 
        nextstate <= "0011";
       when "0011" => 
        nextstate <= "0010";
       when "0010" => 
        nextstate <= "0110";
       when "0110" => 
        nextstate <= "0111";
       when "0111" => 
        nextstate <= "0101";
       when "0101" => 
        nextstate <= "0100";
       when "0100" => 
        nextstate <= "1100";
       when "1100" => 
        nextstate <= "1101";
       when "1101" => 
        nextstate <= "1111";
       when "1111" => 
        nextstate <= "1110"; 
       when "1110" => 
        nextstate <= "1010";
       when others =>
        nextstate <= "0001";
      end case;
     end process NScombproc; 
     
     Outputcombproc: process(clk, state, outputenable) is
     begin 
      if (clk'event and clk='1') then
       if outputenable then
        case state is  
         when "0000" => 
          output <= "000000000000";
         when "0001" => 
          output <= "000000000001";     
         when "0011" => 
          output <= "000000000010";
         when "0010" => 
          output <= "000000000100";
         when "0110" => 
          output <= "000000001000";
         when "0111" => 
          output <= "000000010000";
         when "0101" => 
          output <= "000000100000";
         when "0100" => 
          output <= "000001000000";
         when "1100" => 
          output <= "000010000000";
         when "1101" => 
          output <= "000100000000";
         when "1111" => 
          output <= "001000000000";
         when "1110" => 
          output <= "010000000000";
         when "1010" => 
          output <= "100000000000";
         when others =>
          null;
        end case;
       else output <= "000000000000";
       end if;
      end if;
     end process Outputcombproc;
    end behv;
     
    

    Thanks again,

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

    --- Quote Start ---

    For instance, the "Fast model clock hold" minimum slack is only 0.397 ns. I am running a 20 MHz clock. Is this acceptable?

    --- Quote End ---

    You can use a setting to add clock uncertainty for things like clock jitter (for a PLL in non-MAX II devices and for your clock input in your design) that the Quartus timing analysis does not cover by default. Unless I'm forgetting something, clock uncertainty is all you need in order to count on even a zero slack (anything not negative) being good enough for internal timing for a global clock with no logic in the clock path.

    You might want to have some positive slack for I/O timing unless you are sure that your I/O timing constraints account for all uncertainties for what is happening outside the FPGA (like needing to wait a little longer for a noisy signal to settle out).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    First off, would you recommend a null statement for the "when others" cases?

    --- Quote End ---

    In case you haven't noticed my post that appeared at the same time as your question, see my mention of safe state machines above. Refer to the Quartus handbook for coding style recommendations.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think, the basic danger of inexpected behaviour with the design is outside the CPLD, clock input and signal output. The design itself is simple and rather slow clocked. It's not easy to cause an error here.

    The above safe state machine suggestion is important regarding the possibility, that the clock may be affected by interferences. A non safe state machine may get stuck to an illegal state and never recover due to a single glitch in the input clock.

    Safe transmission of output signals is mainly a question of appropriate wiring.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks to everyone for your help.

    I've now added clock jitter to my timing simulations, changed my code to ensure that the state machine was detected by Quartus II, and forced the state machine to be "safe."

    Hopefully that should cover all of my bases to the greatest degree possible.

    Thanks again,

    Jon