Can anyone help me with this VHDL code (currently malfunctioning)?

Posted by xx77aBs on Stack Overflow See other posts from Stack Overflow or by xx77aBs
Published on 2012-02-20T18:12:14Z Indexed on 2012/09/11 21:38 UTC
Read the original article Hit count: 185

Filed under:

This code should be (and is) very simple, and I don't know what I am doing wrong. Here is description of what it should do:

It should display a number on one 7-segment display. That number should be increased by one every time someone presses the push button. There is also reset button which sets the number to 0. That's it. Here is VHDL code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity PWM is
    Port ( cp_in : in  STD_LOGIC;
           inc : in  STD_LOGIC;
              rst: in std_logic;
           AN : out  STD_LOGIC_VECTOR (3 downto 0);
           segments : out  STD_LOGIC_VECTOR (6 downto 0));
end PWM;

architecture Behavioral of PWM is
    signal cp: std_logic;

    signal CurrentPWMState: integer range 0 to 10;
    signal inco: std_logic;
    signal temp: std_logic_vector (3 downto 0);
begin
    --cp = 100 Hz
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
    debounce: entity debounce port map (inc, cp, inco);
    temp <= conv_std_logic_vector(CurrentPWMState, 4);
    ss: entity decoder7seg port map (temp, segments);

    process (inco, rst)
    begin
        if inco = '1' then
            CurrentPWMState <= CurrentPWMState + 1;
        elsif rst='1' then
            CurrentPWMState <= 0;
        end if;
    end process;

    AN <= "1110";
end Behavioral;

Entity djelitelj (the counter used to divide 50MHz clock):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity PWM is
    Port ( cp_in : in  STD_LOGIC;
           inc : in  STD_LOGIC;
              rst: in std_logic;
           AN : out  STD_LOGIC_VECTOR (3 downto 0);
           segments : out  STD_LOGIC_VECTOR (6 downto 0));
end PWM;

architecture Behavioral of PWM is
    signal cp: std_logic;

    signal CurrentPWMState: integer range 0 to 10;
    signal inco: std_logic;
    signal temp: std_logic_vector (3 downto 0);
begin
    --cp = 100 Hz
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
    debounce: entity debounce port map (inc, cp, inco);
    temp <= conv_std_logic_vector(CurrentPWMState, 4);
    ss: entity decoder7seg port map (temp, segments);

    process (inco, rst)
    begin
        if inco = '1' then
            CurrentPWMState <= CurrentPWMState + 1;
        elsif rst='1' then
            CurrentPWMState <= 0;
        end if;
    end process;

    AN <= "1110";
end Behavioral;

Debouncing entity:

library IEEE;
use  IEEE.STD_LOGIC_1164.all;
use  IEEE.STD_LOGIC_ARITH.all;
use  IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY debounce IS
    PORT(pb, clock_100Hz : IN    STD_LOGIC;
         pb_debounced     : OUT    STD_LOGIC);
END debounce;

ARCHITECTURE a OF debounce IS
    SIGNAL SHIFT_PB : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN

-- Debounce Button: Filters out mechanical switch bounce for around 40Ms.
-- Debounce clock should be approximately 10ms
process 
begin
  wait until (clock_100Hz'EVENT) AND (clock_100Hz = '1');
      SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1);
      SHIFT_PB(3) <= NOT PB;
      If SHIFT_PB(3 Downto 0)="0000" THEN
        PB_DEBOUNCED <= '1';
      ELSE 
        PB_DEBOUNCED <= '0';
      End if;
end process;
end a;

And here is BCD to 7-segment decoder:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity decoder7seg is
    port (
        bcd: in std_logic_vector (3 downto 0);
        segm: out std_logic_vector (6 downto 0));
end decoder7seg;

architecture Behavioral of decoder7seg is
begin
    with bcd select
        segm<= "0000001" when "0000", -- 0
        "1001111" when "0001",        -- 1
        "0010010" when "0010",        -- 2
        "0000110" when "0011",        -- 3
        "1001100" when "0100",        -- 4
        "0100100" when "0101",        -- 5
        "0100000" when "0110",        -- 6
        "0001111" when "0111",        -- 7
        "0000000" when "1000",        -- 8
        "0000100" when "1001",        -- 9
        "1111110" when others;        -- just - character

end Behavioral;

Does anyone see where I made my mistake(s) ? I've tried that design on Spartan-3 Started board and it isn't working ... Every time I press the push button, I get crazy (random) values. The reset button is working properly. Thanks !!!!

© Stack Overflow or respective owner

Related posts about vhdl