1
votes

I'm trying to code for a simple counter (0 to 9) displaying on a seven segment display. The way it increments is via a switch - going from a logic 0 to logic 1 which increments it by 1. There is also a rest capability which is meant to reset the counter to 0.

I have looked on here and got the majority of my code sorted. I have simulated this on ModelSim when compiling and it works as expected. However when I download the code to my DE0 board, it doens't work - I can't even describe what it does as it's so random and there's no discernible pattern (random LEDs will light up, random numbers will appear etc.).

The reset (which sets the counter to 0 and outputs a 0 to the 7-segment) works fine though!

Here's my code so far:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Lab_1 is port (
  switch : in  std_logic;
  rst    : in  std_logic;
  sseg   : out std_logic_vector(7 downto 0));
end Lab_1;

architecture top of Lab_1 is
  signal counter : unsigned (3 downto 0) := "0000";
begin

  display : process(switch, rst) is
  begin
    if rst = '1' and rst'last_value = '0' then
      counter <= "0000";
    elsif switch = '1' and switch'last_value = '0' then
      counter <= counter + 1;
    end if;
    case counter is
      when "0000" => sseg <= "11000000";
      when "0001" => sseg <= "11111001";
      when "0010" => sseg <= "10100100";
      when "0011" => sseg <= "10110000";
      when "0100" => sseg <= "10011001";
      when "0101" => sseg <= "10010010";
      when "0110" => sseg <= "10000010";
      when "0111" => sseg <= "11111000";
      when "1000" => sseg <= "10000000";
      when "1001" => sseg <= "10010000";
      when others => sseg <= "11111111";
    end case;
  end process;

end top;

Any help would be appreciated as to what is going wrong?

EDIT:

This from an assignment I am doing for my university course. The question actually wants a way to keep score for two "teams" by way of pushing a button/switch and then resetting it. I figured if I could have got a simple counter working then I could easily (I hope!) by way of keeping score for 2 teams.

The DE0 board does have buttons which are debounced - but when I altered the code so that it used the buttons, the 7-segment would display a random value/pattern WHILE the button was pressed and then change to another random value/pattern when the button was let go.

1
Welcome to Stack Overflow. It is generally good practice to mention when the question is based on homework, so those answering can determine how much of a solution they want to provide.Morten Zilmer
Are you using a physical switch on your DE1 board? If so, you are probably getting lots of glitches on the line which is destroying your counter logic. Look up "debouncing a switch on an FPGA" to see how to fix this problem.Russell
Also, I don't believe that 'last_value is synthesizable. You should think of another way to do positive edge detection. But first fix your debounce problem.Russell
@Russell: Altera QII accepts to synthesize 'last_value, but simply returns the inverted value of the signal, e.g. not switch, which sounds correct in synthesized design with only '0' and '1'.Morten Zilmer
sseg is organized decimal, g downto a. For simulation, counter isn't in the sensitivity list, your display wouldn't update until the next event on either switch or rst. The 'random' display symptoms sound like debounce issues in both switch and debounced button. From the Terasic Altera DE0 Board User Manual "only PCB 10-0100730-A0 version contains the debounced circuit", 4.2 Using the LEDs and Switches, para 4. Code switch as a clock, check warnings 'last_value likely ignored.user1155120

1 Answers

0
votes

Some suggestions for how to move on:

  1. There is no clock in the design, but a clock is needed for several reasons listed below, so add a clock the port list based on an available clock in on the DE0 reference board.

  2. Make a clocked process for update of the counter at the rising edge of the clock.

  3. A switch input will typically generate some amount of bouncing, see contact bouncing typically occur. So a debouncer must be to applied to the contact, see debounce. The deboundes switch is referred to as switch_db below. The clock is also used for this.

  4. The VHDL attribute 'last_value can't be used for edge detection as written in the code. Instead make a version of the switch signal that is delayed a single cycle through use of a flip-flop, and then check on current and previous value like (switch_db = '1') and (switch_db_delay_ = '0'). The VHDL attribute 'last_value is typically a test bench feature, thus for simulation only. The clock is also used for this.

  5. Convert of counter to the 7-segment values can be in a separate process, to avoid issues with sensitivity list handling, which may otherwise generate warnings in synthesis tool.