Can anyone help me with this VHDL code (currently malfunctioning)?
- by xx77aBs
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 !!!!