EmbDev.net

Forum: FPGA, VHDL & Verilog Debounce Code Correction for a Decimal Counter Project in 1Hz counting Speed


von Ali A. (ali_a184)


Attached files:

Rate this post
0 useful
not useful
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:

reset

hold

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.

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;
------------------------------------------------------------

: Edited by Moderator
von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
Ali A. schrieb:
> And in the project it has to diplay on the 7 segment controlled by the
> switches : count up/count down  hold  reset
Nice job for basic hardware design.

> here down below example for debounce
That is only an empty template with absolutely nothing in it.

> but couldnt find to way to implement.
How would you implement such a debouncing in real hardware with 
flipflops and counters and logic? When you have an idea, then simply 
describe it with the hardware description language VHDL.

You can have a look how others do it: see the data sheet of the MAX6818. 
Understand, what the device is doing! When you understand, what the 
device is doing, its kind of simple to implement that function in VHDL:
http://www.lothar-miller.de/s9y/archives/4-Tasterentprellung-wie-MAX6816.html

> We got 3 different layers as a design.
> cntr  cntr_rtl  cntr_top  cntr_top_struc  io_ctrl  io_ctrl_rtl
Crude and chatty academic style.
Not a nice job to be forced to solve easy problems that cumbersome way.


> here down below example
Pls use the [vhdl] tags as described above each text box...

: Edited by Moderator
von Ali (Guest)


Rate this post
0 useful
not useful
Here is the my code for debounce.
My tutor told me that i need to do it with the clock which it is already 
been for the system.

But my code uses some sort of extra generated signal so i need to change 
the implementation of the lines down below according to the empty 
skript.

-----------------------------------------------------------------------------
--
-- 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;



You can also check the hole files that i upload for the vhdl folder.

: Edited by Moderator
von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
Ali wrote:
> p_debounce: process (s_1hzen, reset_i)
Congratulation: you formed a combinatorial loop.
 variable dbouncecntr : integer:=0;
 begin
 if reset_i = '1' then                      
     :                  
 else
     :
        dbouncecntr := dbouncecntr + 1; ---- here it is: a counter with no clock!

I would write your REALLY BIG enable process somehow that way by using 
integer as counters:
p_slowen: process (clk_i, reset_i) -- can't see no need for the reset...
begin
if clk_i'event and clk_i = '1' then

  s_2khzen <= '0';                   -- the default value is '0' but it
  s_1hzen  <= '0';                   -- maybe overwritten furtherdown

  if s_enctr < COUNTVALUE then       --  COUNTVALUE = (f_clk_i/2kHz)-1
    s_enctr <= s_enctr + 1;
  else 
    s_enctr <= 0;
    s_2khzen <= '1';                 -- 2kHz clock enable
    if s_2khzcount<1999 then
       s_2khzcount <= s_2khzcount+1;
    else    
       s_1hzen <= '1';               -- 1Hz clock enable
    end if; 
  end if;

end if;
end process p_slowen;
While editing I was heavily wondering, what the s_2khzen is for.
But I would use it for debouncing:
p_debounce: process (clk_i, reset_i) -- USE OLNY ONE AND THE SAME CLOCK IN THE WHOLE DESIGN
                                     -- again absolutely no need for the reset....
variable cntpb, cntsw : integer range 0 to 15 := 0;

begin 
if clk_i'event and clk_i = '1' then
    if s_2khzen = '1' then
       -- debounce sw
       if swsync1 /= swdebounced then 
          cntsw<=0;
       else
          cntsw <= cntsw+1;
       end if;
       if cntsw = 15 then 
         swdebounced <= swsync1; 
      end if;
      
      --- same for pd
      
   end if;
end process;
swclean_o <= swdebounced;
pbclean_o <= pbdebounced;


> You can also check the hole files that i upload for the vhdl folder.
I can't open rar files here. Why not simply attaching the VHDL flies 
plus getting a bonus like sytax higlighting?


BTW: check the use of the vhdl tags...
Rules — please read before posting
  ...
    Post long source code as attachment, not in the text

Formatting options
  ...
    [vhdl]VHDL code[/vhdl]

: Edited by Moderator
von Ali (Guest)


Rate this post
0 useful
not useful
Thanks a lot i think i solved the issue. Thanks for your contribution.
Wish you a nice day.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.