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.
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;
cntr_top.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity cntr_top is
port (clk_i : in std_logic; -- First Data Bit
reset_i : in std_logic; -- Second Data Bit
sw_i : in std_logic_vector (15 downto 0); -- 16 Switches Input
pb_i : in std_logic_vector(3 downto 0); -- 4 Buttons Input
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
end cntr_top;
io_ctrl.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity io_ctrl is
port (clk_i : in std_logic; -- System clock (100 MHZ)
reset_i : in std_logic; -- Asynchronous 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
sw_i : in std_logic_vector(15 downto 0); -- 16 switches (from FPGA board)
pb_i : in std_logic_vector(3 downto 0); -- 4 buttons (from FPGA board)
ss_o : out std_logic_vector(7 downto 0); -- to 7 segment displays of the FPGA board
ss_sel_o : out std_logic_vector(3 downto 0); -- Selection of a 7 segment digit
swclean_o: out std_logic_vector(15 downto 0); -- 16 switches (to internal logic)
pbclean_o : out std_logic_vector(3 downto 0)); -- 4 buttons
end io_ctrl;
cntr_rtl.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;
architecture rtl of cntr is
constant COUNTVALUE : std_logic_vector(26 downto 0):= "000000000000000001111101000";
--constant COUNTVALUE : std_logic_vector(26 downto 0):= "101111101011110000100000000";
signal s_enctr : std_logic_vector(26 downto 0) := "000000000000000000000000000";
signal s_1hzen : std_logic :='0';
signal s_cntr0 : std_logic_vector(3 downto 0) :="0000"; -- All digits set to zero.
signal s_cntr1 : std_logic_vector(3 downto 0) :="0000";
signal s_cntr2 : std_logic_vector(3 downto 0) :="0000";
signal s_cntr3 : std_logic_vector(3 downto 0) :="0000";
type s_state is (reset, hold, up, down);
signal s_present_state : s_state;
signal s_next_state : s_state;
begin
p_cntr: process(clk_i, reset_i)
variable v_digit0 : std_logic_vector(3 downto 0):= "0000";
variable v_digit1 : std_logic_vector(3 downto 0):= "0000";
variable v_digit2 : std_logic_vector(3 downto 0):= "0000";
variable v_digit3 : std_logic_vector(3 downto 0):= "0000";
begin
if reset_i = '1' then
v_digit0 := "0000";
v_digit1 := "0000";
v_digit2 := "0000";
v_digit3 := "0000";
s_enctr <= (others => '0');
elsif (clk_i'event and clk_i = '1') then
s_present_state <= s_next_state;
if s_enctr = COUNTVALUE then --When the number of terminals is reached, set the release flag and reset the counter
s_enctr <= (others => '0');
s_1hzen <= '1';
case s_present_state is
when up => --counting up.
if v_digit0 /= "1001" then
v_digit0 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit0 )) + 1, 4)); -- incrementing the bits.
elsif v_digit0 = "1001" and v_digit1 /= "1001" then
v_digit0 := "0000";
v_digit1 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit1 )) + 1, 4));
elsif v_digit0 = "1001" and v_digit1 = "1001" and v_digit2 /= "1001" then
v_digit0 := "0000";
v_digit1 := "0000";
v_digit2 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit2 )) + 1, 4));
elsif v_digit0 = "1001" and v_digit1 = "1001" and v_digit2 = "1001" and v_digit3 /= "1001"then
v_digit0 := "0000";
v_digit1 := "0000";
v_digit2 := "0000";
v_digit3 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit3 )) + 1, 4));
else
v_digit0 := "0000";
v_digit1 := "0000";
v_digit2 := "0000";
v_digit3 := "0000";
end if;
when down => --counting down.
if v_digit0 /= "0000" then
v_digit0 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit0 )) - 1, 4)); -- decrementing the bits.
elsif v_digit0 = "0000" and v_digit1 /= "0000" then
v_digit0 := "1001";
v_digit1 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit1 )) - 1, 4));
elsif v_digit0 = "0000" and v_digit1 = "0000" and v_digit2 /= "0000" then
v_digit0 := "1001";
v_digit1 := "1001";
v_digit2 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit2 )) - 1, 4));
elsif v_digit0 = "0000" and v_digit1 = "0000" and v_digit2 = "0000" and v_digit3 /= "0000"then
v_digit0 := "1001";
v_digit1 := "1001";
v_digit2 := "1001";
v_digit3 := std_logic_vector(to_unsigned(to_integer(unsigned( v_digit3 )) - 1, 4));
else
v_digit0 := "1001";
v_digit1 := "1001";
v_digit2 := "1001";
v_digit3 := "1001";
end if;
when hold => null; -- holding the counting.
when reset => -- reset all the values to zero.
v_digit0 := "0000";
v_digit1 := "0000";
v_digit2 := "0000";
v_digit3 := "0000";
end case;
else
s_enctr <=std_logic_vector(to_unsigned(to_integer(unsigned( s_enctr )) + 1, 27));
if s_1hzen = '1' then
s_1hzen <= '0';
end if;
end if;
s_cntr0 <= v_digit0;
s_cntr1 <= v_digit1;
s_cntr2 <= v_digit2;
s_cntr3 <= v_digit3;
end if;
end process p_cntr;
cntr0_o <= s_cntr0;
cntr1_o <= s_cntr1;
cntr2_o <= s_cntr2;
cntr3_o <= s_cntr3;
----------------------------------------------------------------------------------------------------------------
-- State machine
----------------------------------------------------------------------------------------------------------------
p_states: process(s_present_state, cntrup_i, cntrdown_i, cntrreset_i, cntrhold_i,reset_i)
begin
case s_present_state is
when reset => -- reset state conditions
if cntrreset_i = '1' then
s_next_state <= reset;
elsif cntrhold_i = '1' then
s_next_state <= hold;
elsif cntrup_i = '1' then
s_next_state <= up;
elsif cntrdown_i = '1' then
s_next_state <= down;
else s_next_state <= hold;
end if;
when hold => -- hold state conditions
if cntrreset_i = '1' then
s_next_state <= reset;
elsif cntrhold_i = '1' then
s_next_state <= hold;
elsif cntrup_i = '1' then
s_next_state <= up;
elsif cntrdown_i = '1' then
s_next_state <= down;
else s_next_state <= hold;
end if;
when up => -- up count state conditions
if cntrreset_i = '1' then
s_next_state <= reset;
elsif cntrhold_i = '1' then
s_next_state <= hold;
elsif cntrup_i = '1' then
s_next_state <= up;
elsif cntrdown_i = '1' then
s_next_state <= down;
else s_next_state <= hold;
end if;
when down => -- down count conditions
if cntrreset_i = '1' then
s_next_state <= reset;
elsif cntrhold_i = '1' then
s_next_state <= hold;
elsif cntrup_i = '1' then
s_next_state <= up;
elsif cntrdown_i = '1' then
s_next_state <= down;
else s_next_state <= hold;
end if;
when others => s_next_state <= reset;
end case;
end process p_states;
end rtl;
cntr.vhd
library IEEE;
use IEEE.std_logic_1164.all;
entity cntr is
port (clk_i : in std_logic; -- System clock (100 MHZ)
reset_i : in std_logic; -- Asysnchronous 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 cntr;
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;
------------------------------------------------------------