Jump to content
  • 0

Debounce Code Correction for a Decimal Counter Project in 1Hz counting Speed


excellency

Question

I am completly new for the FPGA and basys3  development board. 

I have a project for Counter on the 7 segment displays on the board. 

We got 3 different layers as a design. 

cntr

cntr_rtl

cntr_top

cntr_top_struc

io_ctrl

io_ctrl_rtl 

And in the project it has to diplay on the 7 segment controlled by the switches : count up / count down / hold / reset options: 

 

The priorities for these switches are:
1. reset
2. hold
3. count direction

 

top level VHDL file cntr_top.vhd
Port Name Direction Description
clk_i In System clock (100 MHz)
reset_i In Asynchronous high active reset
sw_i(15:0) In 16 switches
pb_i(3:0) In 4 buttons
ss_o(7:0) Out Contain the value for all 7-segment digits
ss_sel_o(3:0) Out Select a 7-segment digit
 

io_ctrl

 

clk_i In System clock (100 MHz)
reset_i In Asynchronous high active reset
cntr0_i(n:0) In Digit 0 (from internal logic)
cntr1_i(n:0) In Digit 1 (from internal logic)
cntr2_i(n:0) In Digit 2 (from internal logic)
cntr3_i(n:0) In Digit 3 (from internal logic)
sw_i(15:0) In 16 switches (from FPGA board)
pb_i(3:0) In 4 buttons (from FPGA board)
ss_o(7:0) Out to 7-segment displays of the FPGA board
ss_sel_o(3:0) Out Selection of a 7-segment digit
swclean_o(15:0) Out 16 switches (to internal logic)
pbclean_o(3:0) Out 4 buttons (to internal logic)
 

cntr.vhd

 

clk_i In System clock (100 MHz)
reset_i In Asynchronous high active reset
cntrup_i In Counts up if signal is ‘1’
cntrdown_i In Counts down if signal is ‘1’
cntrreset_i In Sets counter to 0x0 if signal is ‘1’
cntrhold_i In Holds count value if signal is ‘1’
cntr0_o(n:0) Out Digit 0 (from internal logic)
cntr1_o(n:0) Out Digit 1 (from internal logic)
cntr2_o(n:0) Out Digit 2 (from internal logic)
cntr3_o(n:0) Out Digit 3 (from internal logic)
 

 

I will attach also the file to the attachment. Now my code is working and do all the funcitionality correct but there is only one issue which is the DEBOUNCE code part. 

I didnt use the clk signal for the code and i have to change it. The certain given clock signal has to be used. 

So can any be give me suggestions how i can correct  the debounce concept in the code. 

io_ctrl_rtl.vhd -code down below:

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


architecture rtl of io_ctrl is

constant COUNTVALUE : std_logic_vector(16 downto 0):= "01100001101010000"; 

signal s_enctr : std_logic_vector(16 downto 0):="00000000000000000";
signal s_2khzen : std_logic :='0';
signal s_1hzen : std_logic :='0';
signal s_2khzcount : std_logic_vector(3 downto 0) := "0000";
signal swsync0 : std_logic_vector(15 downto 0):="0000000000000000";
signal pbsync0 : std_logic_vector(3 downto 0):="0000";
signal swsync1 : std_logic_vector(15 downto 0):="0000000000000000";
signal pbsync1 : std_logic_vector(3 downto 0):="0000";
signal swtmp : std_logic_vector(15 downto 0):="0000000000000000";
signal pbtmp : std_logic_vector(3 downto 0):="0000";
signal swdebounced : std_logic_vector(15 downto 0):="0000000000000000";
signal pbdebounced : std_logic_vector(3 downto 0):="0000";
signal s_ss_sel : std_logic_vector(3 downto 0) := "0000";
signal s_ss : std_logic_vector(7 downto 0) := "00000000";
begin -- rtl
-----------------------------------------------------------------------------
--
-- Synchronize the inputs
--
-----------------------------------------------------------------------------
p_sync: process (clk_i, reset_i)
begin 
if reset_i = '1' then 
swsync0 <= (others => '0');
pbsync0 <= (others => '0');
swsync1 <= (others => '0');
pbsync1 <= (others => '0');
elsif clk_i'event and clk_i = '1' then

    swsync0 <=    sw_i;
    pbsync0 <=    pb_i;
    swsync1 <=     swsync0;
    pbsync1    <=    pbsync0;
    else null;
end if;
end process;

-----------------------------------------------------------------------------
--
-- Generate 1 KHz enable signal.
--
-----------------------------------------------------------------------------
p_slowen: process (clk_i, reset_i)
begin
if reset_i = '1' then        
    s_enctr <= (others => '0');
    s_2khzen <= '0';
    
elsif clk_i'event and clk_i = '1' then 
    if s_enctr = COUNTVALUE then    -- When the terminal counter is reached, set the release flag and reset the counter
        s_enctr <= (others => '0');
        s_2khzen <= '1';
        s_2khzcount <= std_logic_vector(to_unsigned(to_integer(unsigned( s_2khzcount )) + 1, 4));
    else 
        s_enctr <= std_logic_vector(to_unsigned(to_integer(unsigned( s_enctr )) + 1, 17)); -- As long as the terminal count is not reached: increment the counter.
        if    s_2khzen = '1' then 
        s_2khzen <= '0';
        end if; 
        end if;
    if s_2khzcount = "1010" then
        s_1hzen <= not s_1hzen;
        s_2khzcount <= "0000";
    end if;
end if;
end process p_slowen;
-----------------------------------------------------------------------------
--
-- Debounce buttons and switches
--
-----------------------------------------------------------------------------
p_debounce: process (s_1hzen, reset_i)
variable dbouncecntr : integer:=0;
begin 
if reset_i = '1' then 
        swdebounced <= "0000000000000000";
        pbdebounced <= "0000";
        dbouncecntr :=0;                                 -- Change clocking the process with signal from sens list.
else
    if (dbouncecntr = 0) then
                swtmp <= swsync1;
                pbtmp <= pbsync1;
                dbouncecntr := dbouncecntr + 1;
    elsif (dbouncecntr = 1) then
                if (swtmp = swsync1) then
                    swdebounced <= swsync1;
                end if;
                if (pbtmp = pbsync1) then
                    pbdebounced <= pbsync1;
                end if;
                dbouncecntr := 0;
        
        end if;
     end if;
end process p_debounce;
swclean_o <= swdebounced;
pbclean_o <= pbdebounced;
-----------------------------------------------------------------------------
--
-- Display controller for the 7-segment display
--
-----------------------------------------------------------------------------
p_displaycontrol: process (clk_i, reset_i)

variable v_scancnt : std_logic_vector(1 downto 0):= "00";
variable v_output : std_logic_vector(3 downto 0):="0000"; 
begin 
if reset_i = '1' then
v_scancnt := "00";
s_ss <= "00000000";
elsif clk_i'event and clk_i = '1' then 
     if    s_2khzen = '1' then 

        case v_scancnt is
            when "00" =>    
            v_output    := cntr0_i;
            s_ss_sel    <=    "0001";
            when "01" =>
            v_output     := cntr1_i;
            s_ss_sel    <=    "0010";
            when "10" =>
            v_output     := cntr2_i;
            s_ss_sel    <=    "0100";
            when "11" =>
            v_output     := cntr3_i;
            s_ss_sel    <=    "1000";
            when others =>
            v_output    := "1111";
            s_ss_sel    <=    "0001";
        end case;
    
        case v_output is             --ABCDEFG,    
            when "0000" => s_ss <= "11111100";  --0
            when "0001" => s_ss <= "01100000";  --1
            when "0010" => s_ss <= "11011010";  --2
            when "0011" => s_ss <= "11110010";  --3
            when "0100" => s_ss <= "01100110";  --4
            when "0101" => s_ss <= "10110110";  --5
            when "0110" => s_ss <= "10111110";  --6
            when "0111" => s_ss <= "11100000";  --7
            when "1000" => s_ss <= "11111110";  --8
            when "1001" => s_ss <= "11110110";  --9
            when others => s_ss <= v_scancnt & "000000";
        end case;
    
    if v_scancnt = "11" then
    v_scancnt := "00";
    else
        v_scancnt := std_logic_vector(to_unsigned(to_integer(unsigned( v_scancnt )) + 1, 2));
    end if;
        
    else null;
    end if;
    else null;
    
end if;

end process p_displaycontrol;

ss_o <= not s_ss;
ss_sel_o <= not s_ss_sel;
end rtl;

 

The code for : cntr_top_struc.vhd

 

library IEEE;
use IEEE.std_logic_1164.all;

architecture rtl of cntr_top is

  component cntr                                                    -- component of cntr
  
    port (clk_i:        in  std_logic;                              -- 100 MHz system clock
          reset_i:        in  std_logic;                                -- async high active reset
          cntrup_i :    in  std_logic;                                --counts up if signal is '1'
          cntrdown_i :  in  std_logic;                                --counts down if signal is '1'
          cntrreset_i : in  std_logic;                                --sets counter to 0x0 if signal is '1'
          cntrhold_i :  in  std_logic;                                --holds count value if signal is '1'
          
          cntr0_o:        out std_logic_vector(3 downto 0);            --    Digit 0 (from internal logic)
          cntr1_o:        out std_logic_vector(3 downto 0);            --    Digit 1 (from internal logic)
          cntr2_o:        out std_logic_vector(3 downto 0);            --    Digit 2 (from internal logic)
          cntr3_o:        out std_logic_vector(3 downto 0));            --    Digit 3 (from internal logic)
          
  end component;
  
  component io_ctrl   ---- component io_crtl
    port (clk_i:        in  std_logic;                                -- 100 MHz system clock
          reset_i:        in  std_logic;                                -- async high active reset
          
          cntr0_i:        in std_logic_vector(3 downto 0);            --    Digit 0 (from internal logic)
          cntr1_i:        in std_logic_vector(3 downto 0);            --    Digit 1 (from internal logic)
          cntr2_i:        in std_logic_vector(3 downto 0);            --    Digit 2 (from internal logic)
          cntr3_i:        in std_logic_vector(3 downto 0);            --    Digit 3 (from internal logic)
          
          swclean_o:    out std_logic_vector(15 downto 0);
          pbclean_o:    out std_logic_vector(3 downto 0);
          
          ss_o:            out std_logic_vector(7 downto 0);            -- Contain the Value for All 7-Segment Digits     
          ss_sel_o:        out std_logic_vector(3 downto 0);            -- Select a 7-segment digits

          pb_i:            in std_logic_vector(3 downto 0);            --4 Buttons
          sw_i:            in std_logic_vector(15 downto 0) );              --16 Switches
                    
  end component;

  -- Declare the signals that are used to connect the submodules.
  signal s_cntr0 : std_logic_vector(3 downto 0);
  signal s_cntr1 : std_logic_vector(3 downto 0);
  signal s_cntr2 : std_logic_vector(3 downto 0);
  signal s_cntr3 : std_logic_vector(3 downto 0);  
  signal s_cntrup         : std_logic;  
  signal s_cntrdown        : std_logic;  
  signal s_cntrreset     : std_logic; 
  signal s_cntrhold        : std_logic; 
  signal s_overflow : std_logic_vector(11 downto 0);
begin

--Instantiate the counter that is connected to the IO-Control
  i_cntr_top1 : cntr
  port map              
    (clk_i   => clk_i,
     reset_i   => reset_i,
     -- cntrdir_i  => s_cntrdir,                   --swsync_o(13);
     cntrup_i       => s_cntrup,                 --swsync_o(13);
     cntrdown_i     => s_cntrdown,                 --swsync_o(12);
     cntrreset_i    => s_cntrreset,             --swsync_o(15),
     cntrhold_i     => s_cntrhold,                 --swsync_o(14),
     
     cntr0_o   => s_cntr0,
      cntr1_o   => s_cntr1,
      cntr2_o   => s_cntr2,
     cntr3_o   => s_cntr3);

--Instantiate the IO control to which it is connected
  i_io_ctrl : io_ctrl
  port map
    (clk_i           => clk_i,
     reset_i           => reset_i,   
     swclean_o(12)    => s_cntrdown,
     swclean_o(13)    => s_cntrup,
     swclean_o(15)    => s_cntrreset,
     swclean_o(14)    => s_cntrhold,
     swclean_o(11 downto 0)    => s_overflow(11 downto 0),
     cntr0_i           => s_cntr0,
      cntr1_i           => s_cntr1,
      cntr2_i           => s_cntr2,
     cntr3_i           => s_cntr3,    
    
     ss_o            =>    ss_o,
     ss_sel_o        =>    ss_sel_o,
     sw_i            =>    sw_i,
     pb_i            =>    pb_i);
     
end rtl;

 

Please waiting for your suggestions. 

Any help would be great appricated thanks for all. 

 

here down below example for debounce but couldnt find to way to implement.

 

-----------------------------------------------------------------------------
--
-- Debounce buttons and switches
--
-----------------------------------------------------------------------------
p_debounce: process (clk_i, reset_i)
begin -- process debounce
if reset_i = '1' then -- asynchronous reset (active high)
elsif clk_i'event and clk_i = '1' then -- rising clock edge
end if;
end process p_debounce;
swsync_o <= swsync;
pbsync_o <= pbsync;
------------------------------------------------------------
 

 

 

 

Final Project-Decimal Count -1Hz.rar

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

Hi,

>> So can any be give me suggestions how i can correct  the debounce concept in the code. 

  • regular solution: count consecutive, identical input states and reset the counter on change of input state. Signal change of output state when counter reaches predetermined value.
  • sneaky / suboptimal solution: sample the switch on a 100 Hz grid.

I have to keep reminding myself that there is nothing inherently wrong with VHDL ... in Verilog, the whole task could be solved cleanly in one screen length of code, give or take some.

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...