Forum Discussion

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

Altera MAX 3064 CPLD weird problem

Hi,

I'm using Altera MAX3000 series (EPM3064-10 to be exact) with CPLD_CLK = 77.5Mhz, and I have a very weird problem...

pseudocode is below:

signal_abc = asynchronous from external chip

below is flip-flops (just pseudocode):

if (reset) then reset the flops

elsif (clk'event and clk = 1)

signal_abc_q1 <= signal_abc;

signal_abc_q2 <= signal_abc_q1;

signal_abc_q3 <= signal_abc_q2;

signal_abc_posedge <= signal_abc_q2 and not signal_abc_q3;

if (reset OR signal_def_clear = '1') then -- async reset

signal_def <= '0';

elsif (clk'event and clk = 1)

if (signal_abc_posedge = '1') then

signal_def <= '1';

But, I see intermittent problems where there is NO edge transitions of signal_abc (and clean), yet there is edge transition for signal_def.

tracing back:

- signal_abc stays low

- but (exporting signal_abc_q2 & q3 out to pads), I saw: these 2 internal flip-flops actually toggles from low to HIGH,

- which of course causes signal_abc_posedge to go HIGH,

- which causes signal_def to go HIGH

I can't figure out why this is happening... right now, the only thing I can think of is there's something wrong with the CPLD...

any help is greatly appreciated...

Thanks

10 Replies

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

    I don't expect max devices to go wrong on a basic drive.

    Are you sure you start up with these flips on zero. I assume you do reset them to zero but there is an option of power-up don't care and it defaults to ON. quartus is then free to choose low or high logic for power up. You must change this default to No
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    But, this only happens intermittently even after I turned OFF the "power-up dont care"...

    after a few hundreds transitions of signal_abc, then I will see this error...

    small amount of transitions are alright...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In that case, you better post your main cpld code(not pseudocode) so that we can share it all. (not the project please)

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

    sure, in the entity:

    irq_src_reg <= wlan_irq & NOT sdio_irq_n & NOT fb_n & sw_irq & NOT overcurr_n & headlift & NOT pb_n; -- these are external signals

    PROCESS (rst_n, clk) IS

    BEGIN

    IF (rst_n = '0') THEN

    irq_src_reg_q (6 downto 0) <= (OTHERS => '0');

    irq_src_reg_q2 (6 downto 0) <= (OTHERS => '0');

    irq_src_reg_q3 (6 downto 0) <= (OTHERS => '0');

    irq_n <= '1';

    ELSIF (clk'event and clk = '1') THEN

    irq_src_reg_q (6 downto 0) <= irq_src_reg (6 downto 0);

    irq_src_reg_q2 (6 downto 0) <= irq_src_reg_q (6 downto 0);

    irq_src_reg_q3 (6 downto 0) <= irq_src_reg_q2(6 downto 0);

    irq_n <= NOT (irq_trig_reg(6) OR irq_trig_reg(5) OR irq_trig_reg(4) OR irq_trig_reg(3) OR irq_trig_reg(2) OR irq_trig_reg(1) OR irq_trig_reg(0));

    END IF;

    END PROCESS;

    -- Combinatorial logic for positive edge_to_pulse

    PROCESS (irq_src_reg_q2, irq_src_reg_q3) IS

    BEGIN

    FOR i IN 0 TO 6 LOOP

    irq_src_reg_posedge(i) <= irq_src_reg_q2(i) and not irq_src_reg_q3(i);

    END LOOP;

    END PROCESS;

    irq_clr_reg <= data(6 DOWNTO 0)

    WHEN (cs_n = '0' AND we_n = '0' AND addr = irq_clr_reg_addr)

    ELSE (OTHERS => '0')

    -- data is inout(7 downto 0) at top-level

    data <= 'Z' & irq_trig_reg

    WHEN ((cs_n = '0') AND (oe_n = '0') AND (addr = irq_trig_reg_addr))

    ELSE (OTHERS => 'Z')

    interrupt_trigger: PROCESS (rst_n, clk, irq_clr_reg) IS

    BEGIN

    FOR i IN 0 to 6 LOOP

    IF (rst_n = '0' OR irq_clr_reg(i) = '1') THEN

    irq_trig_reg(i) <= '0';

    ELSIF (clk'EVENT AND clk = '1') THEN

    IF (irq_src_reg_posedge(i) = '1') THEN

    irq_trig_reg(i) <= '1';

    END IF;

    END IF;

    END LOOP;

    END PROCESS interrupt_trigger
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    For now I feel there is a problem here, this is combinatorial(unlike pseudocode)

    
    -- Combinatorial logic for positive edge_to_pulse
    PROCESS (irq_src_reg_q2, irq_src_reg_q3) IS
    BEGIN
    FOR i IN 0 TO 6 LOOP
    irq_src_reg_posedge(i) <= irq_src_reg_q2(i) and not irq_src_reg_q3(i);
    END LOOP;
    END PROCESS;
    

    it will get you in trouble if there is any glitch
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    but this is to generate 1-clock-cycle wide of pulse when there's a rising-edge.

    I already made sure each bit went through double-flops before being used...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Sorry you are right you have indeed double registers(q2/q3). So I withdraw my first feel.

    Your code looks sound to me so far. The fact that the error is related to succession of asynch signal points to a possible glitch of irq_src_reg_posedge

    which is then registered as irq_trig_reg. It is now matter of speculations. But I will register the edge detection itself just in case.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    With regard to for loop in:

    
    interrupt_trigger: PROCESS (rst_n, clk, irq_clr_reg) IS 
    BEGIN
    FOR i IN 0 to 6 LOOP
        IF (rst_n = '0' OR irq_clr_reg(i) = '1') THEN
           irq_trig_reg(i) <= '0';
        ELSIF (clk'EVENT AND clk = '1') THEN
              IF (irq_src_reg_posedge(i) = '1') THEN
                   irq_trig_reg(i) <= '1';
              END IF;
        END IF;
    END LOOP;
    END PROCESS interrupt_trigger
    

    Ia it possible that this may go wrong:

    why not put the loop start after clk edge, just a thought
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    btw, I only noticed these glitches when we changed our system clock to 77.5Mhz. when previously running at 51Mhz, I never encountered this issue...

    the loop there is to repeat the entire flops for the whole 7-bit arrays (including the clear register)...

    hmm... I can try to re-flop the posedge register...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If your timing analysis is successful then the main culprit is that your asynch signals have glitches from outside.

    You can apply a patch: design a basic test to ignore these glitches for example register the asynch signal or decide the edge only if it is more than one clk period or so.

    -- this code tests asynch signal being high at two successive clock edges

    
    -- Combinatorial logic for positive edge_to_pulse
    PROCESS (irq_src_reg_q2,irq_src_reg_q3, irq_src_reg_q4) IS
    BEGIN
    FOR i IN 0 TO 6 LOOP
         irq_src_reg_posedge(i) <= irq_src_reg_q2(i) and irq_src_reg_q3(i) and not irq_src_reg_q4(i);
    END LOOP;
    END PROCESS;