Forum Discussion

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

A very basic newbie question

Hi All

I have a very basic question. I've recently started learning about CPLD and VHDL. My VHDL code usually compiles and simulates fine, but when I put it in an actual CPLD it behaves really strange. I'm sure you have all been there. Could you please solve this mystery for me?

Basically what I am doing is dividing the global clock by 500, and incerementing a counter to show the value on a seven segment. This is the very simple code, I am using MAX EPM7128SLC84-15:


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
 
-- this is the entity
Entity V2 Is
 Port ( 
  GClk : In std_logic; --Global clock, pin 83
  SS : Out std_logic_vector(6 Downto 0); -- Connected to the Seven Segement
   );
End V2;
 
Architecture RTL of V2 is  
 Signal MyClk : std_logic;      -- The divided clock
 Signal SevSegVal : std_logic_vector(6 downto 0);
Begin 
 Process (GClk)
  Variable Count : Integer Range 0 To 1023 := 0;
 Begin
  If (rising_edge(GClk)) Then
   Count := Count + 1;
   If (Count = 500) Then
    Count := 0;
    MyClk <= Not MyClk;
   End If;
  End IF;
 End Process;  
 
 
 PROCESS (MyClk)
  Variable Counter : Integer Range 0 To 9 := 0;
  Type SSValues Is array(integer range 0 to 9) Of std_logic_vector(6 downto 0); 
  Variable  Values : SSValues := (('1', '0', '0', '0', '0', '0', '0')
        , ('1', '1', '1', '1', '0', '0', '1')
        , ('0', '1', '0', '0', '1', '0', '0')
        , ('0', '1', '1', '0', '0', '0', '0')
        , ('0', '0', '1', '1', '0', '0', '1')
        , ('0', '0', '1', '0', '0', '1', '0')
        , ('0', '0', '0', '0', '0', '1', '0')
        , ('1', '1', '1', '1', '0', '0', '0')
        , ('0', '0', '0', '0', '0', '0', '0')
        , ('0', '0', '1', '0', '0', '0', '0'));  -- To hold the bit pattern for the seven segment numbers
 
 Begin  
  If (rising_edge(MyClk)) Then
   SevSegVal <= Values (Counter);
   If (Counter = 9) Then
    Counter := 0;
   Else
    Counter := Counter + 1;
   End IF;
  End If;
 End Process;
 
 SS <= SevSegVal;
 
End RTL;

This code simulates fine in Quartus II using a vector waveform file. But doesn't work properly when I upload it to my development board.

The problem is the the seven segment flickers. I can see it count, but the lamps that are supposed to be off for each number flicker dimly.

From what I can see, Quartus II (v 8.0) synthesizes this code to a latch which is clocked by MyClk, which goes to high impedance during the wait and causes the lines to float and flicker. Am I right?

To me, it seems I am violating some 'well-known' rules for writing synthesizable code that actually works in real hardware. What am I doing wrong? What is the correct way of dividing a clock and incrementing a seven segment counter? I really really appreciate your help.

13 Replies

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

    Good to hear you solved your problem Haplo.

    Your chip obviously has more pins than you are actually using in your FPGA design. Previously the pins that you weren't using in the FPGA were driving low because of that setting. Either one of those pins is driving some output on some other chip or has a short to something nasty and causing weird behaviour.

    Personally I usually make sure that I set unused pins to tri-state. If you had a load of tracks that are connected to unused stuff which might cause signal integrity problems if left floating, then you could fix these to a safe level in your design. If all is working then you probably don't need to worry about this - leave unused pins as tri-state.

    Well done.

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

    Always follow the instructions in the .pin file regardless of the setting for unused pins.

    You still need to follow the instructions in the .pin file with the unused pins set to "As input tri-stated". The .pin file probably tells you to ground unused pins. If they are left unconnected, the input buffers will float. That can cause oscillations on input buffers, which can result in a high I/O current, noise, and degraded reliability.

    For device families that have the option "As input tri-stated with bus-hold circuitry" for unused pins, I recommend that. For device families without that option, I recommend "As input tri-stated with weak pull-up resistor". With either of these settings, it is OK to leave unused pins unconnected and also OK to have them driven either high or low by something else on the board.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In theory setting the unused pins to output should have worked, but as batfink suggested, I think a few of the I/O pins that were connected to the microcontroller started misbehaving. A lesson learned.

    This what you get with a poorly designed board and absolutely no documentation.

    Thanks guys for all your help!