Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > switching problem

Reply
Thread Tools

switching problem

 
 
Simone Winkler
Guest
Posts: n/a
 
      09-05-2003
Hello!

I'm trying to build the following thing: a 7-segment-led that increases its
value every time a switch is pressed.

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

entity sevsegment is
Port (
clk_i: in std_logic;
sevseg : out std_logic_vector(6 downto 0);
reset : in std_logic;
switch: in std_logic);
end sevsegment;

architecture Behavioral of sevsegment is
signal sevseg_s: std_logic_vector(6 downto 0);
begin

process(reset,switch,clk_i)
variable counter: integer range 0 to 9;
begin
if clk_i'event and clk_i='1' then
if reset='0' then
counter:=0;
sevseg_s <= "1111110";
elsif switch'event and switch='0' then
if counter<9 then
counter:=counter+1;
else
counter:=0;
end if;
case counter is
when 0 => sevseg_s <= "1111110";
when 1 => sevseg_s <= "0110000";
when 2 => sevseg_s <= "1101101";
when 3 => sevseg_s <= "1111001";
when 4 => sevseg_s <= "0110011";
when 5 => sevseg_s <= "1011011";
when 6 => sevseg_s <= "1011111";
when 7 => sevseg_s <= "1110000";
when 8 => sevseg_s <= "1111111";
when 9 => sevseg_s <= "1111011";
end case;
end if;
end process;

sevseg <= sevseg_s;

end Behavioral;


Why doesn't it work? I know that "multiple clocks" are not allowed, but i
can't find any solution to solve my problem.... ((((((((
In the end, everything should be implemented to a spartanII-FPGA...

Thank you very much,
Simone


 
Reply With Quote
 
 
 
 
Ralf Hildebrandt
Guest
Posts: n/a
 
      09-06-2003
Hi Simone!

> I'm trying to build the following thing: a 7-segment-led that increases its
> value every time a switch is pressed.


Ok - but what is the reason for the use of "clk"?


> process(reset,switch,clk_i)
> variable counter: integer range 0 to 9;
> begin
> if clk_i'event and clk_i='1' then
> if reset='0' then
> counter:=0;
> sevseg_s <= "1111110";
> elsif switch'event and switch='0' then
> if counter<9 then
> counter:=counter+1;
> else
> counter:=0;
> end if;
> case counter is
> when 0 => sevseg_s <= "1111110";
> when 1 => sevseg_s <= "0110000";
> when 2 => sevseg_s <= "1101101";
> when 3 => sevseg_s <= "1111001";
> when 4 => sevseg_s <= "0110011";
> when 5 => sevseg_s <= "1011011";
> when 6 => sevseg_s <= "1011111";
> when 7 => sevseg_s <= "1110000";
> when 8 => sevseg_s <= "1111111";
> when 9 => sevseg_s <= "1111011";
> end case;
> end if;
> end process;



> Why doesn't it work? I know that "multiple clocks" are not allowed,


Thats the point. What you have described it a "dual-edge-flipflop", that
ist not synthesizeable. (Not synthesizeable today - but maybe in some
years...)

Ok, what about the following solution? (I cant see a reason for clk, so
I have left it.)

process(reset_async,switch)
variable counter: integer range 0 to 9;
begin
if reset_async='0' then -- asynchronous reset
counter:=0;
sevseg_s <= "1111110";
elsif switch'event and switch='0' then
if (reset_sync='1') then -- synchronous reset
counter:=0;
sevseg_s <= "1111110";
else if counter<9 then
counter:=counter+1;
else
counter:=0;
end if;
case counter is
when 0 => sevseg_s <= "1111110";
when 1 => sevseg_s <= "0110000";
when 2 => sevseg_s <= "1101101";
when 3 => sevseg_s <= "1111001";
when 4 => sevseg_s <= "0110011";
when 5 => sevseg_s <= "1011011";
when 6 => sevseg_s <= "1011111";
when 7 => sevseg_s <= "1110000";
when 8 => sevseg_s <= "1111111";
when 9 => sevseg_s <= "1111011";
end case;
end if;
end if;
end process;


I've placed two resets. Choose one or take both...


Ralf

 
Reply With Quote
 
 
 
 
Pieter Hulshoff
Guest
Posts: n/a
 
      09-06-2003
> I'm trying to build the following thing: a 7-segment-led that increases
> its value every time a switch is pressed.


OK, sounds doable.

> elsif switch'event and switch='0' then


You've just defined your second 'clock' here.

> Why doesn't it work? I know that "multiple clocks" are not allowed, but i
> can't find any solution to solve my problem.... ((((((((
> In the end, everything should be implemented to a spartanII-FPGA...


Well, what you need is to find a switch change on the clock. Sooo....

SIGNAL switch_d : std_logic;

PROCESS
VARIABLE counter: integer range 0 to 9;
BEGIN

WAIT UNTIL clk_i = '1'; -- Sorry, but I prefer this notation

switch_d <= switch; -- Save previous value of switch

IF switch = '0' AND switch_d = '1' THEN -- Switch has just become 0
IF counter < 9 THEN
counter := counter+1;
ELSE
counter := 0;
END IF;
END IF;

CASE counter IS
WHEN 0 => sevseg_s <= "1111110";
WHEN 1 => sevseg_s <= "0110000";
WHEN 2 => sevseg_s <= "1101101";
WHEN 3 => sevseg_s <= "1111001";
WHEN 4 => sevseg_s <= "0110011";
WHEN 5 => sevseg_s <= "1011011";
WHEN 6 => sevseg_s <= "1011111";
WHEN 7 => sevseg_s <= "1110000";
WHEN 8 => sevseg_s <= "1111111";
WHEN 9 => sevseg_s <= "1111011";
END CASE;

-- I usually use synchronous resets like this, at the end of a process.
--
IF reset='0' THEN
counter :=0;
sevseg_s <= "1111110";
switch_d <= '0';
END IF;

END PROCESS;


Hope this helps.

Regards,

Pieter Hulshoff

 
Reply With Quote
 
Egbert Molenkamp
Guest
Posts: n/a
 
      09-06-2003

"Ralf Hildebrandt" <Ralf-> schreef in bericht
news:bjcepr$hiv6v$...
> process(reset_async,switch)
> variable counter: integer range 0 to 9;
> begin
> if reset_async='0' then -- asynchronous reset
> counter:=0;
> sevseg_s <= "1111110";
> elsif switch'event and switch='0' then


But if switch is a real switch, I mean include bouncing, it probably can
count 'too fast'.

One way to solve it is using a SR latch for debouncing (see many text books
on digital logic).
Another approach is to add a counter. The original description had a clk.
You
can add a process that increments a counter at the active edge (eg rising
edge)
of the clock if switch is STILL '1' (pressed). If the counter reaches 100
(depends
of course on the clock freq.) you may assume that the switch is pressed.
This internal counter is zero if switch is '0'. So if the counter has
reached 100
you may assume that the switch is stable and pressed.
Now this process can generate a pulse "switch_pressed" for the logic
that counts the occurences.

process(reset,clk)
variable counter: integer range 0 to 9;
begin
if reset='0' then
counter:=0;
sevseg_s <= "1111110";
if rising_edge(clk) then
if switch_pressed = '1' then -- or use a boolean in stead of std_logic!
if counter<9 then
counter:=counter+1;
else
counter:=0;
end if;
case counter is
....

It depends how the first part is realized but maybe an additional FF at the
input switch is needed for synchronization. Otherwise it may be possible
that
if switch is changed within setup/hold time the FF's may not see the same
value for the switch.

Egbert Molenkamp


 
Reply With Quote
 
Pieter Hulshoff
Guest
Posts: n/a
 
      09-07-2003
Actually, mr Molenkamp had a very good remark in his post below: if the
switch is unrelated to the clock, you'll need to add some FFs for
metastability, like this:

SIGNAL switch_1d : std_logic;
SIGNAL switch_2d : std_logic;
SIGNAL switch_3d : std_logic;

PROCESS
VARIABLE counter: integer range 0 to 9;
BEGIN

WAIT UNTIL clk_i = '1'; -- Sorry, but I prefer this notation

switch_1d <= switch; -- 1st FF for metastability
switch_2d <= switch_1d; -- 2nd FF for metastability
switch_3d <= switch_2d; -- 3rd FF to compare against 2nd FF

IF switch_2d = '0' AND switch_3d = '1' THEN -- Switch has just become 0
IF counter < 9 THEN
counter := counter+1;
ELSE
counter := 0;
END IF;
END IF;

CASE counter IS
WHEN 0 => sevseg_s <= "1111110";
WHEN 1 => sevseg_s <= "0110000";
WHEN 2 => sevseg_s <= "1101101";
WHEN 3 => sevseg_s <= "1111001";
WHEN 4 => sevseg_s <= "0110011";
WHEN 5 => sevseg_s <= "1011011";
WHEN 6 => sevseg_s <= "1011111";
WHEN 7 => sevseg_s <= "1110000";
WHEN 8 => sevseg_s <= "1111111";
WHEN 9 => sevseg_s <= "1111011";
END CASE;

-- I usually use synchronous resets like this, at the end of a process.
--
IF reset='0' THEN
counter :=0;
sevseg_s <= "1111110";
switch_d <= '0';
END IF;

END PROCESS;


Hope this helps.

Regards,

Pieter Hulshoff

 
Reply With Quote
 
William Wallace
Guest
Posts: n/a
 
      09-10-2003
In lieu of an s-r debounce latch on your switch, you could try
something like this (not even syntax checked):

entity sevsegment is
port (
clk_i : in std_logic;
sevseg : out std_logic_vector(6 downto 0);
reset_n : in std_logic;--active low reset
switch : in std_logic
);
end sevsegment;

architecture rtl of sevsegment is
signal switch_filter : std_logic_vector(15 downto 0); -- actual
length depends on clk speed and bounce characteristics
signal switch_changed : std_logic;
signal bcd_counter : std_logic_vector(4 downto 0);
begin

process(reset_n,clk_i)
variable bcd_counter: integer range 0 to 9;
begin
if(reset_n ='0') then
bcd_counter <= X"0";-- enable 1993 syntax
switch_filter <= (others => '0');
switch_changed <= '0';
elsif clk_i'event and clk_i='1' then
if(switch_changed='1') then
if bcd_counter< X"9" then
bcd_counter <= bcd_counter + 1;
else
bcd_counter <= X"0";
end if;
end if;
switch_filter <= switch_filter(switch_filter'length - 2 downto 0)
& switch;--shift register
switch_changed <= (not switch_filter(switch_filter'length -1)) and
switch_filter(switch_filter'length -2) and
switch_filter(switch_filter'length -3) and
switch_filter(switch_filter'length -4);
end if;
end process;

decode_bcd_counter_combinatorial: process(bcd_counter)
begin
case bcd_counter is
when 0 =>
sevseg <= "1111110";

when 1 =>
sevseg <= "0110000";

when 2 =>
sevseg <= "1101101";

when 3 =>
sevseg <= "1111001";

when 4 =>
sevseg <= "0110011";

when 5 =>
sevseg<= "1011011";

when 6 =>
sevseg <= "1011111";

when 7 =>
sevseg <= "1110000";

when 8 =>
sevseg <= "1111111";

when 9 =>
sevseg <= "1111011";

when others =>
sevseg <= "1111110";

end case;

end process decode_bcd_counter_combinatorial;

end rtl;


"Simone Winkler" <> wrote in message news:<>...
> Hello!
>
> I'm trying to build the following thing: a 7-segment-led that increases its
> value every time a switch is pressed.
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.ALL;
> use IEEE.STD_LOGIC_ARITH.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
>
> entity sevsegment is
> Port (
> clk_i: in std_logic;
> sevseg : out std_logic_vector(6 downto 0);
> reset : in std_logic;
> switch: in std_logic);
> end sevsegment;
>
> architecture Behavioral of sevsegment is
> signal sevseg_s: std_logic_vector(6 downto 0);
> begin
>
> process(reset,switch,clk_i)
> variable counter: integer range 0 to 9;
> begin
> if clk_i'event and clk_i='1' then
> if reset='0' then
> counter:=0;
> sevseg_s <= "1111110";
> elsif switch'event and switch='0' then
> if counter<9 then
> counter:=counter+1;
> else
> counter:=0;
> end if;
> case counter is
> when 0 => sevseg_s <= "1111110";
> when 1 => sevseg_s <= "0110000";
> when 2 => sevseg_s <= "1101101";
> when 3 => sevseg_s <= "1111001";
> when 4 => sevseg_s <= "0110011";
> when 5 => sevseg_s <= "1011011";
> when 6 => sevseg_s <= "1011111";
> when 7 => sevseg_s <= "1110000";
> when 8 => sevseg_s <= "1111111";
> when 9 => sevseg_s <= "1111011";
> end case;
> end if;
> end process;
>
> sevseg <= sevseg_s;
>
> end Behavioral;
>
>
> Why doesn't it work?


1. The switch is not debounced (possibly).
2. The synthesizer doesn't recognized one process with two clocks.

> I know that "multiple clocks" are not allowed, but i
> can't find any solution to solve my problem.... ((((((((

There are many solutions. I think the one I gave above may work.

> In the end, everything should be implemented to a spartanII-FPGA...
>
> Thank you very much,
> Simone


Good luck.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with ASP.Net version switching: select 1.1.4322 ben@arrayx.co.uk ASP .Net 3 10-19-2008 11:34 AM
Process Switching vs. Fast/CEF Switching? asdf Cisco 7 05-29-2007 05:26 PM
Switching problem ? dizzy_devil_be@yahoo.fr Cisco 0 09-11-2005 07:16 PM
Bizarre switching problem Matthew Melbourne Cisco 0 10-22-2004 07:25 PM
Struts URL problem with switching modules oscar Java 0 12-09-2003 04:55 AM



Advertisments