Addition with 7-Segment Display - case

I am trying to add the 2 outputs together and show their result in a third/fourth display on the 7 segment display. Each output is shown in their own segment respectively. The fourth display being a double digit number (Max being 14, Min being 0). I am getting an error stating that I need to write all instances of the case "add". Not sure where to go from here. Any help is appreciated.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Midterm2_Q2_4369 IS
PORT (
SW: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
SW0: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
ADD: IN STD_LOGIC_VECTOR(6 DOWNTO 0);
Y: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
Y0: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
Y1: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
Y2: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END Midterm2_Q2_4369;
ARCHITECTURE MUX8 OF Midterm2_Q2_4369 IS
BEGIN
PROCESS (SW,SW0,ADD)
BEGIN
CASE SW IS
WHEN "000" => Y <= "0000001";
WHEN "001" => Y <= "1001111";
WHEN "010" => Y <= "0010010";
WHEN "011" => Y <= "0000110";
WHEN "100" => Y <= "1001100";
WHEN "101" => Y <= "0100100";
WHEN "110" => Y <= "0100000";
WHEN "111" => Y <= "0001111";
END CASE;
CASE SW0 IS
WHEN "000" => Y0 <= "0000001";
WHEN "001" => Y0 <= "1001111";
WHEN "010" => Y0 <= "0010010";
WHEN "011" => Y0 <= "0000110";
WHEN "100" => Y0 <= "1001100";
WHEN "101" => Y0 <= "0100100";
WHEN "110" => Y0 <= "0100000";
WHEN "111" => Y0 <= "0001111";
END CASE;
CASE ADD IS
WHEN "0000000" => Y1 <= "0000001"; --0
WHEN "0000001" => Y1 <= "1001111"; --1
WHEN "0000010" => Y1 <= "0010010"; --2
WHEN "0000011" => Y1 <= "0000110"; --3
WHEN "0000100" => Y1 <= "1001100"; --4
WHEN "0000101" => Y1 <= "0100100"; --5
WHEN "0000110" => Y1 <= "0100000"; --6
WHEN "0000111" => Y1 <= "0001111"; --7
WHEN "0001111" => Y1 <= "0000000"; --8
WHEN "0010111" => Y1 <= "0000100"; --9
--8421421
WHEN "0011111" => Y2 <= "1001111"; --(1)0
WHEN "0100111" => Y2 <= "1001111"; --(1)1
WHEN "0101111" => Y2 <= "1001111"; --(1)2
WHEN "0110111" => Y2 <= "1001111"; --(1)3
WHEN "0111111" => Y2 <= "1001111"; --(1)4--
WHEN "1000111" => Y2 <= "1001111"; --(1)5
WHEN "1001111" => Y2 <= "1001111"; --(1)6
WHEN "1010111" => Y2 <= "1001111"; --(1)7--
WHEN "1011111" => Y2 <= "1001111"; --(1)8
WHEN "1100111" => Y2 <= "1001111"; --(1)9
END CASE;
END PROCESS;
END MUX8;

When using a case in VHDL, all cases MUST be covered.
Becasue SW, SW0 and ADD are all std_logic_vector, you must also cover all of the meta cases like "UUUUUUUU", etc. The easiest way to do this is with others.
For example. SW0 has all "real" cases covered, but you must also cover values that can only occur in simulation, so provide a handy message:
CASE SW0 IS
WHEN "000" => Y0 <= "0000001";
WHEN "001" => Y0 <= "1001111";
WHEN "010" => Y0 <= "0010010";
WHEN "011" => Y0 <= "0000110";
WHEN "100" => Y0 <= "1001100";
WHEN "101" => Y0 <= "0100100";
WHEN "110" => Y0 <= "0100000";
WHEN "111" => Y0 <= "0001111";
when others => report "Meta value detected" severity warning;-- simulation only case
END CASE;
You must also ensure all cases are covered for SW and ADD too

Related

Ada GNATprove insints that 1 is not >= 0

I am trying to prove, that my algorithm for finding second largest value in array works as it should. This is my code:
function FindMax2 (V : Vector) return Integer is
Max : Natural := 0;
SecondMax : Natural := 0;
begin
for I in V'Range loop
pragma Assert
(Max >= 0 and
SecondMax >= 0 and
V(I) > 0);
if V(I) > Max then
SecondMax := Max;
Max := V(I);
elsif V(I) /= Max and V(I) > SecondMax then
SecondMax := V(I);
end if;
pragma Loop_Invariant
(Max > SecondMax and
V(I) > 0 and
(for all J in V'First .. I => V(J) <= Max));
end loop;
return SecondMax;
end FindMax2;
and this are my pre- and postconditions:
package Max2 with SPARK_Mode is
type Vector is array (Integer range <>) of Positive;
function FindMax2 (V : Vector) return Integer
with
Pre => V'First < Integer'Last and V'Length > 0,
Post => FindMax2'Result >= 0 and
(FindMax2'Result = 0 or (for some I in V'Range => FindMax2'Result = V(I))) and
(if FindMax2'Result /= 0 then (for some I in V'Range => V(I) > FindMax2'Result)) and
(if FindMax2'Result = 0 then (for all I in V'Range => (for all J in V'Range => V(I) = V(J)))
else
(for all I in V'Range => (if V(I) > FindMax2'Result then (for all J in V'Range => V(J) <= V(I)))));
end Max2;
I'm stuck now on this message from GNATprove:
max2.ads:8:17: medium: postcondition might fail (e.g. when FindMax2'Result = 1 and V = (others => 1) and V'First = 0 and V'Last = 0)
If I am not mistaken it is reffering to the first condition about the result being greater or equal to 0, then why does it put 1 as a counter-example? Is there any way I can prove this?
I managed to solve my problem. I was wrong about the error message, gnatprove was reffering to the whole post condition statement. If someone is interested in the solution, Iadded a few conditions in the loop invariant
pragma Loop_Invariant
(Max > SecondMax and
V(I) > 0 and
(for all J in V'First .. I => V(J) <= Max) and
(Max = 0 or (for some J in V'First .. I => Max = V(J))) and
(SecondMax = 0 or (for some J in V'First .. I => SecondMax = V(J))) and
(if SecondMax = 0 then (for all J in V'First .. I => (for all K in V'First .. I => V(J) = V(K)))
else (for all J in V'First .. I => (if V(J) > SecondMax then (for all K in V'First .. I => V(K) <= V(J))))));
Note that the actual answer was provided by the OP self here. Credits should go there. This is just an addition to my comment on that nice result.
max2.ads
package Max2 with SPARK_Mode is
type Vector is array (Integer range <>) of Positive;
function All_Same (V : Vector) return Boolean is
(for all I in V'Range => (for all J in V'Range => V(I) = V(J)))
with Ghost;
function Elem_Of (V : Vector; X : Integer) return Boolean is
(for some I in V'Range => V (I) = X)
with Ghost;
function Is_Largest (V : Vector; X : Integer) return Boolean is
(Elem_Of (V, X) and (for all I in V'Range => V (I) <= X))
with Ghost;
function Is_Second_Largest (V : Vector; X : Integer) return Boolean is
(Elem_Of (V, X) and not Is_Largest (V, X) and
(for all I in V'Range => V(I) <= X or else Is_Largest (V, V (I))))
with Ghost;
pragma Annotate (GNATprove, Inline_For_Proof, All_Same);
pragma Annotate (GNATprove, Inline_For_Proof, Elem_Of);
pragma Annotate (GNATprove, Inline_For_Proof, Is_Largest);
pragma Annotate (GNATprove, Inline_For_Proof, Is_Second_Largest);
procedure FindMax2 (V : Vector; Found : out Boolean; Value : out Natural)
with Post => (if Found then Is_Second_Largest (V, Value) else All_Same (V));
end Max2;
max2.adb
package body Max2 with SPARK_Mode is
--------------
-- FindMax2 --
--------------
procedure FindMax2
(V : in Vector;
Found : out Boolean;
Value : out Natural)
is
L1 : Natural := 0;
L2 : Natural := 0;
begin
if V'Length > 1 then
for I in V'Range loop
if L1 < V(I) then
L2 := L1;
L1 := V(I);
elsif L2 < V(I) and V(I) < L1 then
L2 := V(I);
end if;
pragma Loop_Invariant
(L2 < L1);
pragma Loop_Invariant
(L1 = 0 or Elem_Of (V (V'First .. I), L1));
pragma Loop_Invariant
(L2 = 0 or Elem_Of (V (V'First .. I), L2));
pragma Loop_Invariant
(Is_Largest (V (V'First .. I), L1));
pragma Loop_Invariant
(if L2 = 0
then All_Same (V (V'First .. I))
else Is_Second_Largest (V (V'First .. I), L2));
end loop;
end if;
Found := (L2 > 0);
Value := L2;
end FindMax2;
end Max2;

Why do I get undefined output vectors and an undefined clock when simulating?

I am pretty new to VHDL and am encountering an error with my testbench (at least I believe its only in the testbench).
My programme simulates a stadium with 12 sections. The programme consists of 12 individual counters along with LEDs when 90% of max capacity is reached and a digital 4 digit display that displays the total of all 12 counters.
Whenever I try to compile the code, there is no change in any of the outputs and all of the inputs are undefined.
Any advice would be appreciated.
Architecture:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.Numeric_STD.all;
entity counter is
Port (Clk: in STD_LOGIC;
Enable : in STD_LOGIC_Vector(11 downto 0);
Reset : in STD_LOGIC_Vector(11 downto 0);
Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10,Q11,Q12 : out STD_LOGIC_Vector(8 downto 0); -- 9 bits as 300 <2^9
Qt : out STD_LOGIC_Vector(11 downto 0); -- 12 bits as 300 (section) * 12 > 2^12
a,b,c,d,e,f,g : out STD_LOGIC_Vector(3 downto 0); --Individual segments of the display (4 because the number will max out at 3600)
Led0,Led1,Led2,Led3,Led4,Led5,Led6,Led7,Led8,Led9,Led10,Led11 : out STD_LOGIC);
end counter;
Architecture behavioral of counter is
type REG_variable is array(0 to 11) of unsigned(8 downto 0);
type Q_variable is array (0 to 11) of STD_LOGIC_Vector(8 downto 0);
type DIGITS_variable is array (0 to 3) of unsigned (3 downto 0);
signal output_array : Q_variable;
signal LED_Output : STD_LOGIC_Vector(11 downto 0);
component count_comp is
Port(Clk, Reset, Enable : in STD_Logic;
Q : out STD_LOGIC_Vector(8 downto 0);
LED : out STD_LOGIC);
end component;
begin
process (CLK,Reset)
variable LED_lights : STD_LOGIC_Vector(11 downto 0) := (others => '0');
variable REG : REG_variable := (others =>(others => '0'));
variable Total_REG: unsigned(11 downto 0) := (others => '0');
variable Digits : DIGITS_variable := (others => (others => '0'));
begin
Single_Counter : for i in 11 downto 0 loop
if Reset(i) = '1' then
Total_REG := Total_REG - REG(i);
REG(i) := (others => '0');
LED_lights(i) := '0';
elsif rising_edge(CLK) then
if Enable(i) = '1' and (REG(i) <= 300) then
if (REG(i) >= 270) then
LED_lights(i) := '1';
Total_REG := Total_REG + 1;
REG(i) := REG(i)+ 1;
end if;
Digits(0) := to_unsigned(to_integer(Total_REG - Total_REG mod 100),4);
Digits(1) := to_unsigned(to_integer((Total_REG - Total_REG mod 100)/10),4);
Digits(2) := to_unsigned(to_integer((Total_REG - Total_REG mod 100)/100),4);
Digits(3) := to_unsigned(to_integer((Total_REG - Total_REG mod 100)/1000),4);
end if;
end if;
Qt <= STD_LOGIC_Vector(Total_REG);
output_array(i) <= STD_LOGIC_Vector(REG(i));
LED_output(i) <= LED_lights(i);
for x in 3 downto 0 loop
case to_integer(Digits(x)) is
when 0
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '1'; d(x) <= '1'; e(x) <= '1'; f(x) <= '1'; g(x) <= '0';
when 1
=> a(x) <= '0'; b(x) <= '1'; c(x) <= '1'; d(x) <= '0'; e(x) <= '0'; f(x) <= '0'; g(x) <= '0';
when 2
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '0'; d(x) <= '1'; e(x) <= '1'; f(x) <= '0'; g(x) <= '1';
when 3
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '1'; d(x) <= '1'; e(x) <= '0'; f(x) <= '0'; g(x) <= '1';
when 4
=> a(x) <= '0'; b(x) <= '1'; c(x) <= '1'; d(x) <= '0'; e(x) <= '0'; f(x) <= '1'; g(x) <= '1';
when 5
=> a(x) <= '1'; b(x) <= '0'; c(x) <= '1'; d(x) <= '1'; e(x) <= '0'; f(x) <= '1'; g(x) <= '1';
when 6
=> a(x) <= '1'; b(x) <= '0'; c(x) <= '1'; d(x) <= '1'; e(x) <= '1'; f(x) <= '1'; g(x) <= '1';
when 7
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '1'; d(x) <= '0'; e(x) <= '0'; f(x) <= '0'; g(x) <= '0';
when 8
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '1'; d(x) <= '1'; e(x) <= '1'; f(x) <= '1'; g(x) <= '1';
when 9
=> a(x) <= '1'; b(x) <= '1'; c(x) <= '1'; d(x) <= '1'; e(x) <= '0'; f(x) <= '1'; g(x) <= '1';
when others
=> a(x) <= '0'; b(x) <= '0'; c(x) <= '0'; d(x) <= '0'; e(x) <= '0'; f(x) <= '0'; g(x) <= '0';
end case;
end loop;
end loop;
end process;
Counters : for i in 11 downto 0 generate
counter_gen : count_comp
port map (CLK => CLK, Reset => Reset (i), Enable => Enable(i), Q => output_array(i), LED => LED_output(i));
end generate;
Q1 <= output_array(0);
Q2 <= output_array(1);
Q3 <= output_array(2);
Q4 <= output_array(3);
Q5 <= output_array(4);
Q6 <= output_array(5);
Q7 <= output_array(6);
Q8 <= output_array(7);
Q9 <= output_array(8);
Q10 <= output_array(9);
Q11 <= output_array(10);
Q12 <= output_array(11);
Led0 <= LED_output(0);
Led1 <= LED_output(1);
Led2 <= LED_output(2);
Led3 <= LED_output(3);
Led4 <= LED_output(4);
Led5 <= LED_output(5);
Led6 <= LED_output(6);
Led7 <= LED_output(7);
Led8 <= LED_output(8);
Led9 <= LED_output(9);
Led10 <= LED_output(10);
Led11 <= LED_output(11);
end behavioral;
Testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Project_Testbench is
end;
architecture TB1 of Project_Testbench is
component count_comp is
Port(Clk: in STD_LOGIC;
Enable : in STD_LOGIC_Vector(11 downto 0);
Reset : in STD_LOGIC_Vector(11 downto 0);
Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10,Q11,Q12 : out STD_LOGIC_Vector(8 downto 0);
Qt : out STD_LOGIC_Vector(11 downto 0);
a,b,c,d,e,f,g : out STD_LOGIC_Vector(3 downto 0);
Led0,Led1,Led2,Led3,Led4,Led5,Led6,Led7,Led8,Led9,Led10,Led11 : out STD_LOGIC);
end component count_comp;
signal Clk_TB : std_logic := '0';
signal Enable : std_logic_Vector(11 downto 0) := (others => '0');
signal Reset : std_logic_Vector(11 downto 0) := (others => '0');
begin
Clk_TB <= not Clk_TB after 5ns;
stimuli: process
begin
Enable <= "000000000000"; Reset <= "11111111111";
wait for 100 ns;
Enable <= "11111111111"; Reset <= "00000000000";
wait for 200 ns;
Enable <= "11110011111"; Reset <= "00000000000";
wait for 50 ns;
Enable <= "00011111111"; Reset <= "00000000000";
wait for 20 ns;
Enable <= "11111111111"; Reset <= "11000000000";
wait for 20 ns;
Enable <= "11111111111"; Reset <= "00000000000";
wait for 1000 ns;
wait;
end process;
uut: count_comp port map
(
Clk => Clk_TB,
Enable => Enable,
Reset => Reset);
end;
Here is a screenshot of the output signals.
Output Signals

Initializing values in a vector

I have a std_logic_vector variable RT defined:
variable RT: std_logic_vector (127 downto 0);
I want to set the values (127 downto 4) to be all 0.
How can i do this?
There are many ways to do that. The most straightforward probably being
rt(127 downto 4) <= (others => '0');
If you want to assign a initial value to your variable you can do:
variable RT : std_logic_vector(127 downto 0) := (others => '0');
to assign all zero to RT.
If the first few positions of RT should have values different than '0' you can go for:
variable RT : std_logic_vector(127 downto 0) := (
0 => '1',
1 => '1',
2 => '1',
3 => '1',
others => '0'
);
This will assign '1' to the first 4 positions and '0' to the rest.

Incrementing Seven Segment by Using Push Buttons

My fpga is spartan 3E-100 Cp132. I have four push buttons as my inputs and I want to increment the four digits on 7-segment of the board by using them. The VHDL code is below:
entity main is
port(b1,b2,b3,b4 : in STD_LOGIC;
clk : in STD_LOGIC;
sseg : out STD_LOGIC_VECTOR(0 to 6);
anodes : out STD_LOGIC_VECTOR(3 downto 0);
reset : in STD_LOGIC
);
end main;
architecture Behavioral of main is
signal bcd1, bcd2, bcd3, bcd4 : STD_LOGIC_VECTOR (3 downto 0);
signal clk2 : STD_LOGIC;
signal pushbuttons : STD_LOGIC_VECTOR(3 downto 0);
signal db_pushbuttons : STD_LOGIC_VECTOR(3 downto 0);
signal counter : STD_LOGIC_VECTOR(1 downto 0);
signal clk_divider : STD_LOGIC_VECTOR(20 downto 0);
component Debounce is
port( cclk : in STD_LOGIC;
inp : in STD_LOGIC_VECTOR(3 downto 0);
cclr : in STD_LOGIC;
db : out STD_LOGIC_VECTOR(3 downto 0)
);
end component;
begin
pushbuttons <= b4 & b3 & b2 & b1;
Db : Debounce port map
( cclk => clk2,
inp => pushbuttons,
cclr => reset,
db => db_pushbuttons);
process (clk)
begin
if rising_edge(clk) then
if clk_divider <= "1100001101010000" then
clk_divider <= clk_divider + 1;
clk2 <= '0';
else
clk_divider <= (others => '0');
clk2 <= '1';
end if;
end if;
end process;
process (clk2, reset)
begin
if reset = '1' then
-- do something here
bcd1 <= "0000";
bcd2 <= "0000";
bcd3 <= "0000";
bcd4 <= "0000";
elsif rising_edge(clk2) then
counter <= counter + 1;
if db_pushbuttons(0) = '1' then -- db_b1
if bcd1 <= "1000" then
bcd1 <= bcd1 + 1;
else
bcd1 <= "0000";
end if;
elsif db_pushbuttons(1) = '1' then -- db_b2
if bcd2 <= "1000" then
bcd2 <= bcd2 + 1;
else
bcd2 <= "0000";
end if;
elsif db_pushbuttons(2) = '1' then -- db_b3
if bcd3 <= "1000" then
bcd3 <= bcd3 + 1;
else
bcd3 <= "0000";
end if;
elsif db_pushbuttons(3) = '1' then --db_b4
if bcd4 <= "1000" then
bcd4 <= bcd4 + 1;
else
bcd4 <= "0000";
end if;
end if;
end if;
end process;
process (counter, bcd1, bcd2, bcd3, bcd4)
variable display : STD_LOGIC_VECTOR(3 downto 0);
begin
case counter is
when "00" => anodes <= "1110"; display := bcd1;
when "01" => anodes <= "1101"; display := bcd2;
when "10" => anodes <= "1011"; display := bcd3;
when "11" => anodes <= "0111"; display := bcd4;
when others => null;
end case;
case display is
when "0000" => sseg <= "0000001"; --0
when "0001" => sseg <= "1001111"; --1
when "0010" => sseg <= "0010010"; --2
when "0011" => sseg <= "0000110"; --3
when "0100" => sseg <= "1001100"; --4
when "0101" => sseg <= "0100100"; --5
when "0110" => sseg <= "0100000"; --6
when "0111" => sseg <= "0001111"; --7
when "1000" => sseg <= "0000000"; --8
when "1001" => sseg <= "0000100"; --9
when others => sseg <= "0010000"; --e, represents error
end case;
end process;
end Behavioral;
Every pushbutton should increment the corresponding 7-segment digit (b1 --> rightmost digit and b4--> leftmost digit) by one. The problem is when I push the button, it does the job but not increment it by one but some arbitrary number. The reason is that it increments by one at every rising edge of the clock 2 and it happens too quickly due to the frequency of this clock. How can I manage to get rid of this problem? I tried several debouncing code for the push buttons but they weren't helpful so much. I am totally stuck here. I mean there should be a way to do it, but how? By the way, the debouncing code that I have been using with the code above is
entity Debounce is
port(cclk : in STD_LOGIC;
inp : in STD_LOGIC_VECTOR(3 downto 0);
cclr : in STD_LOGIC;
db : out STD_LOGIC_VECTOR(3 downto 0)
);
end Debounce;
architecture Behavioral of Debounce is
signal delay1, delay2, delay3 : STD_LOGIC_VECTOR(3 downto 0);
begin
process (cclk, cclr)
begin
if cclr = '1' then
delay1 <= "0000";
delay2 <= "0000";
delay3 <= "0000";
elsif rising_edge(cclk) then
delay1 <= inp;
delay2 <= delay1;
delay3 <= delay2;
end if;
end process;
db <= delay1 and delay2 and delay3;
end Behavioral;
So any help will be appreciated, thanks in advance!
If the intended function of the button is that you will only increment once, no matter how long you hold it down, you need to implement an "edge detect" on the debounced switch output. That is, only allow the bcd count to increment/update on the rising edge of the debounced switch signal. For example:
...
elsif rising_edge(clk2) then
counter <= counter + 1;
db_pushbuttons_previous <= db_pushbuttons;
if db_pushbuttons(0) = '1' and db_pushbuttons_previous(0) = '0' then --rising edge detect
if bcd1 <= "1000" then
bcd1 <= bcd1 + 1;
else
bcd1 <= "0000";
end if;
...
This way, no matter how long db_pushbuttons(0) is asserted, the bcd value will only be incremented once.
Testing with GHDL I have the following code.
file: sevensegns.vhdl
-----------------------------------------
---- SevenSegNS.vhdl
---- Seven segment driver with 4 input
---- buttons
---- Author: Derby Russell
---- Date: 12-13-2013
-----------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.ALL;
entity main_7_seg is
port(b1,b2,b3,b4 : in std_logic;
clk : in std_logic;
sseg : out std_logic_vector(0 to 6);
anodes : out std_logic_vector (3 downto 0);
reset : in std_logic
);
end main_7_seg;
architecture behavioral of main_7_seg is
signal bcd1, bcd2, bcd3, bcd4 : unsigned (3 downto 0) := "0000";
signal clk2 : std_logic := '0';
signal pushbuttons : std_logic_vector(3 downto 0) := "0000";
signal db_pushbuttons : std_logic_vector(3 downto 0) := "0000";
signal counter : unsigned (1 downto 0) := "00";
component Debounce is
port( cclk : in std_logic;
inp : in std_logic_vector(3 downto 0);
cclr : in std_logic;
db : out std_logic_vector(3 downto 0)
);
end component;
begin
pushbuttons <= b4 & b3 & b2 & b1;
Db : Debounce port map
( cclk => clk2,
inp => pushbuttons,
cclr => reset,
db => db_pushbuttons);
process (clk)
begin
if rising_edge(clk) then
clk2 <= '1';
else
clk2 <= '0';
-- FOR RUNNING ON ACTUAL HARDWARE:
-- RESTORE NEXT 6 LINES AND COMMENT OUT ABOVE 4 LINES.
-- if clk_divider <= "1100001101010000" then
-- clk_divider <= clk_divider + 1;
-- clk2 <= '0';
-- else
-- clk_divider <= (others => '0');
-- clk2 <= '1';
end if;
end process;
P2: process (clk2, reset)
begin
if reset = '1' then
-- do something here
bcd1 <= "0000";
bcd2 <= "0000";
bcd3 <= "0000";
bcd4 <= "0000";
elsif rising_edge(clk2) then
counter <= counter + 1;
if db_pushbuttons(0) = '1' then -- db_b1
if bcd1 <= "0010" then
if bcd1 = "0000" then
bcd1 <= bcd1 + 1;
end if;
else
bcd1 <= "0000";
end if;
elsif db_pushbuttons(1) = '1' then -- db_b2
if bcd2 <= "0010" then
if bcd2 = "0000" then
bcd2 <= bcd2 + 1;
end if;
else
bcd2 <= "0000";
end if;
elsif db_pushbuttons(2) = '1' then -- db_b3
if bcd3 <= "0010" then
if bcd3 = "0000" then
bcd3 <= bcd3 + 1;
end if;
else
bcd3 <= "0000";
end if;
elsif db_pushbuttons(3) = '1' then --db_b4
if bcd4 <= "0010" then
if bcd4 = "0000" then
bcd4 <= bcd4 + 1;
end if;
else
bcd4 <= "0000";
end if;
end if;
end if;
end process P2;
P3: process (counter, bcd1, bcd2, bcd3, bcd4)
-- variable display : std_logic_vector(3 downto 0);
variable display : unsigned (3 downto 0);
begin
case counter is
when "00" => anodes <= "1110"; display := bcd1;
when "01" => anodes <= "1101"; display := bcd2;
when "10" => anodes <= "1011"; display := bcd3;
when "11" => anodes <= "0111"; display := bcd4;
when others => null;
end case;
case display is
when "0000" => sseg <= "0000001"; --0
when "0001" => sseg <= "1001111"; --1
when "0010" => sseg <= "0010010"; --2
when "0011" => sseg <= "0000110"; --3
when "0100" => sseg <= "1001100"; --4
when "0101" => sseg <= "0100100"; --5
when "0110" => sseg <= "0100000"; --6
when "0111" => sseg <= "0001111"; --7
when "1000" => sseg <= "0000000"; --8
when "1001" => sseg <= "0000100"; --9
when others => sseg <= "0010000"; --e, represents error
end case;
end process P3;
end behavioral;
file: debounce.vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.ALL;
entity Debounce is
port(cclk : in std_logic;
inp : in std_logic_vector(3 downto 0);
cclr : in std_logic;
db : out std_logic_vector(3 downto 0)
);
end Debounce;
architecture behavioral_2 of Debounce is
signal delay1, delay2, delay3 : std_logic_vector(3 downto 0);
begin
process (cclk, cclr)
begin
if cclr = '1' then
delay1 <= "0000";
delay2 <= "0000";
delay3 <= "0000";
elsif rising_edge(cclk) then
delay1 <= inp;
delay2 <= delay1;
delay3 <= delay2;
end if;
end process;
db <= delay1 and delay2 and delay3;
end behavioral_2;
I processed these two files with a data file sevensegns_tb.vhdl
Then I ran the files and observed the data with gtkwave
here is the output:
(source: googlecode.com)
And I have posted all the code and results to:
Google Code sevenseg
Click on the Source tab to see all the files created.

VHDL Case/When: multiple cases, single clause

Inside a process I have something like this:
CASE res IS
WHEN "00" => Y <= A;
WHEN "01" => Y <= A;
WHEN "10" => Y <= B;
WHEN "11" => Y <= C;
WHEN OTHERS => Y <= 'X';
END CASE;
Note that case "00" and "01" get the same value. Is there a correct syntax for something like
WHEN "00", "01" => ?
Extra note: There's far more to this than Y being changed, I just used that for simplicity. So the case/when is necessary.
You can separate multiple choices with the "pipe" or bar symbol. The proper syntax for your example is:
CASE res IS
WHEN "00" | "01" => Y <= A;
WHEN "10" => Y <= B;
WHEN "11" => Y <= C;
WHEN OTHERS => Y <= 'X';
END CASE;
You can also give a range of choices for a case:
USE IEEE.STD_LOGIC_ARITH.ALL;
CASE CONV_INTEGER(res) IS
WHEN 0 to 1 => Y <= A;
WHEN 2 => Y <= B;
WHEN 3 => Y <= C;
WHEN OTHERS => Y <= 'X';
END CASE;

Resources