Übung
(EN google-translate)
(PL google-translate)
Bitte verbinden Sie die Taster in der Schaltung genau so wie in der hier unten zu sehenden aktuellen Version, um Schäden an der Hardware zu vermeiden!
Entwickeln Sie mit Hilfe des FPGA-Boards eine Uhr mit 24-Stunden-Anzeige und Minutenanzeige oder eine Stoppuhr mit Sekunden (0..99) und Hundertstelsekunden.
Als Anzeigeelement wird ein LTC-2723WC Element benutzt.
Verwenden Sie als Vorwiderstand an den Anoden 2200 Ohm. An den Katoden wird kein Widerstand vorgeschaltet.
Die Uhr / Stoppuhr soll mit entsprechenden Buttons ausgerüstet sein: Stunden+/- Minuten+/- bzw. Start Stop Reset
Teilaufgaben
  | 
Bild 0-1: Pinzuordnungen / Überblick.
uhr003.zip - Musterlösung.
Hinweise zur Musterlösung
  | 
Quelltexte zur Musterlösung
1. uhr.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity uhr is
    Port ( MEINECLOCK : in  STD_LOGIC;
           LEDROT : out  STD_LOGIC;
           LEDGRUEN : out  STD_LOGIC;
           DIGIT12P34 : out  STD_LOGIC_VECTOR (4 downto 0);
           ABCDEFG : out  STD_LOGIC_VECTOR (6 downto 0);
           GROUND123 : out  STD_LOGIC_VECTOR (2 downto 0);
           TASTE123 : in  STD_LOGIC_VECTOR (2 downto 0));
end uhr;
architecture Behavioral of uhr is
--                                     ABCDEFG
constant ZIFFER0: STD_LOGIC_VECTOR := "1111110";
constant ZIFFER1: STD_LOGIC_VECTOR := "0110000";
constant ZIFFER2: STD_LOGIC_VECTOR := "1101101";
constant ZIFFER3: STD_LOGIC_VECTOR := "1111001";
constant ZIFFER4: STD_LOGIC_VECTOR := "0110011";
constant ZIFFER5: STD_LOGIC_VECTOR := "1011011";
constant ZIFFER6: STD_LOGIC_VECTOR := "1011111";
constant ZIFFER7: STD_LOGIC_VECTOR := "1110000";
constant ZIFFER8: STD_LOGIC_VECTOR := "1111111";
constant ZIFFER9: STD_LOGIC_VECTOR := "1111011";
    signal zaehler    : integer range 0 to 2999999 := 0;
    signal D1     : integer range 0 to 9 := 0; -- Stunden obere Stelle
    signal D2     : integer range 0 to 9 := 0; -- Stunden untere Stelle
    signal D3     : integer range 0 to 9 := 0; -- Minuten obere Stelle
    signal D4     : integer range 0 to 9 := 0; -- Minuten untere Stelle
    signal D1_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D2_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D3_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D4_anzeige : std_logic_vector (6 downto 0) := "0000000";
	 	 
    signal logikpegel : std_logic := '0';
    signal auswahl    : std_logic_vector (4 downto 0) := "01111";
    signal tasten    : std_logic_vector (2 downto 0) := "111";
	 
	 signal blockiert : std_logic := '0';
	 
    begin
       process begin
            wait until rising_edge(MEINECLOCK);
				
				
            if (zaehler<2999999) then
                zaehler <= zaehler+1;
            else -- schalten im Halb-Sekundentakt
                blockiert <= '0';				
                zaehler <= 0;
                logikpegel <= not logikpegel;
                if(D4<9) then 
                    D4 <= D4+1;  -- Minuten untere Stelle
                else
                    D4 <= 0;
                    if(D3<5) then
                        D3 <= D3+1; -- Minuten obere Stelle
                    else
                        D3 <= 0; 
                        if( ((D2<9) and (D1<2)) or ((D2<3) and (D1=2)) ) then -- Stunden untere Stelle
                            D2 <= D2+1;
                        else
                            D2 <= 0;
                            if(D1<2) then -- Stunden obere Stelle
                                D1 <= D1+1;
                            else
                                D1 <= 0;
                            end if;										 
                        end if;									 
                    end if;						  
                 end if;
            end if;
				
            if ( (TASTE123(0) = '0') and (blockiert='0')) then 
                 blockiert <= '1';
                 if( ((D2<9) and (D1<2)) or ((D2<3) and (D1=2)) ) then -- Stunden untere Stelle
                     D2 <= D2+1;
                 else
                     D2 <= 0;
                     if(D1<2) then -- Stunden obere Stelle
                         D1 <= D1+1;
                     else
                         D1 <= 0;
                     end if;										 
                  end if;									 
             elsif ( (TASTE123(1) = '0') and (blockiert='0') ) then 
                  blockiert <= '1';
                  if(D4<9) then 
                      D4 <= D4+1;  -- Minuten untere Stelle
                  else
                      D4 <= 0;
                      if(D3<5) then
                          D3 <= D3+1; -- Minuten obere Stelle
                      else
                          D3 <= 0; 
                      end if;
                  end if;	  
             elsif ( (TASTE123(2) = '0') and (blockiert='0') ) then 
                  blockiert <= '1';				
                  if(D4>1) then 
                      D4 <= D4-2;  -- Minuten untere Stelle
                  else
                      D4 <= 9;
                      if(D3>0) then
                          D3 <= D3-1; -- Minuten obere Stelle
                      else
                          D3 <= 5; 
                      end if;
                  end if;	  
             end if;								
-- Umwandlung Ziffer in Digit:				
				case D1 is
				    when 0 => 
					     D1_anzeige <= ZIFFER0;  
				    when 1 => 
					     D1_anzeige <= ZIFFER1;  
				    when 2 => 
					     D1_anzeige <= ZIFFER2;  
				    when 3 => 
					     D1_anzeige <= ZIFFER3;  
				    when 4 => 
					     D1_anzeige <= ZIFFER4;  
				    when 5 => 
					     D1_anzeige <= ZIFFER5;  
				    when 6 => 
					     D1_anzeige <= ZIFFER6;  
				    when 7 => 
					     D1_anzeige <= ZIFFER7;  
				    when 8 => 
					     D1_anzeige <= ZIFFER8;  
				    when 9 => 
					     D1_anzeige <= ZIFFER9;  
				end case;
				
				case D2 is
				    when 0 => 
					     D2_anzeige <= ZIFFER0;  
				    when 1 => 
					     D2_anzeige <= ZIFFER1;  
				    when 2 => 
					     D2_anzeige <= ZIFFER2;  
				    when 3 => 
					     D2_anzeige <= ZIFFER3;  
				    when 4 => 
					     D2_anzeige <= ZIFFER4;  
				    when 5 => 
					     D2_anzeige <= ZIFFER5;  
				    when 6 => 
					     D2_anzeige <= ZIFFER6;  
				    when 7 => 
					     D2_anzeige <= ZIFFER7;  
				    when 8 => 
					     D2_anzeige <= ZIFFER8;  
				    when 9 => 
					     D2_anzeige <= ZIFFER9;  
				end case;
				case D3 is
				    when 0 => 
					     D3_anzeige <= ZIFFER0;  
				    when 1 => 
					     D3_anzeige <= ZIFFER1;  
				    when 2 => 
					     D3_anzeige <= ZIFFER2;  
				    when 3 => 
					     D3_anzeige <= ZIFFER3;  
				    when 4 => 
					     D3_anzeige <= ZIFFER4;  
				    when 5 => 
					     D3_anzeige <= ZIFFER5;  
				    when 6 => 
					     D3_anzeige <= ZIFFER6;  
				    when 7 => 
					     D3_anzeige <= ZIFFER7;  
				    when 8 => 
					     D3_anzeige <= ZIFFER8;  
				    when 9 => 
					     D3_anzeige <= ZIFFER9;  
				end case;
				case D4 is
				    when 0 => 
					     D4_anzeige <= ZIFFER0;  
				    when 1 => 
					     D4_anzeige <= ZIFFER1;  
				    when 2 => 
					     D4_anzeige <= ZIFFER2;  
				    when 3 => 
					     D4_anzeige <= ZIFFER3;  
				    when 4 => 
					     D4_anzeige <= ZIFFER4;  
				    when 5 => 
					     D4_anzeige <= ZIFFER5;  
				    when 6 => 
					     D4_anzeige <= ZIFFER6;  
				    when 7 => 
					     D4_anzeige <= ZIFFER7;  
				    when 8 => 
					     D4_anzeige <= ZIFFER8;  
				    when 9 => 
					     D4_anzeige <= ZIFFER9;  
				end case;
            -- Digit waehlen und richtig setzen, das aufgefrischt werden soll:
            case (zaehler mod 4) is
				    when 0 =>
                    DIGIT12P34 <= "01111";
                    ABCDEFG    <= D1_anzeige;						  
				    when 1 =>
                    DIGIT12P34 <= "10111";
                    ABCDEFG    <= D2_anzeige;						  
				    when 2 =>
                    DIGIT12P34 <= "11101";
                    ABCDEFG    <= D3_anzeige;						  
				    when others =>
                    DIGIT12P34 <= "11110";
                    ABCDEFG    <= D4_anzeige;						  
				end case;
        end process;      
    --- LEDROT und GRUEN blinken lassen
    LEDROT <= logikpegel;
    LEDGRUEN <= not logikpegel;
    --- GROUND123 auf Masse setzen:
    GROUND123 <= "000";
end Behavioral;
Code 0-1: uhr.vhd
2. uhr.ucf
## GCLK6 ist auf FPGA-Chip Pin 56 NET "MEINECLOCK" LOC = "P56" | IOSTANDARD = LVCMOS25; ## LEDROT NET "LEDROT" LOC = "P126" | IOSTANDARD = LVCMOS33; ## LEDGRUEN NET "LEDGRUEN" LOC = "P125" | IOSTANDARD = LVCMOS33; ## DIGIT12P34 NET "DIGIT12P34<4>" LOC = "P105" | IOSTANDARD = LVCMOS33; ## 1 NET "DIGIT12P34<3>" LOC = "P106" | IOSTANDARD = LVCMOS33; ## 2 NET "DIGIT12P34<2>" LOC = "P112" | IOSTANDARD = LVCMOS33; ## P NET "DIGIT12P34<1>" LOC = "P113" | IOSTANDARD = LVCMOS33; ## 3 NET "DIGIT12P34<0>" LOC = "P116" | IOSTANDARD = LVCMOS33; ## 4 ## ABCDEFG NET "ABCDEFG<6>" LOC = "P130" | IOSTANDARD = LVCMOS33; ## A NET "ABCDEFG<5>" LOC = "P131" | IOSTANDARD = LVCMOS33; ## B NET "ABCDEFG<4>" LOC = "P132" | IOSTANDARD = LVCMOS33; ## C NET "ABCDEFG<3>" LOC = "P134" | IOSTANDARD = LVCMOS33; ## D NET "ABCDEFG<2>" LOC = "P135" | IOSTANDARD = LVCMOS33; ## E NET "ABCDEFG<1>" LOC = "P139" | IOSTANDARD = LVCMOS33; ## F NET "ABCDEFG<0>" LOC = "P140" | IOSTANDARD = LVCMOS33; ## G ## TASTEN123 IO0,2,5 NET "TASTE123<2>" LOC = "P58" | PULLUP | IOSTANDARD = LVCMOS33; NET "TASTE123<1>" LOC = "P93" | PULLUP | IOSTANDARD = LVCMOS33; NET "TASTE123<0>" LOC = "P97" | PULLUP | IOSTANDARD = LVCMOS33; ## GROUND123 IO1,4,7 NET "GROUND123<2>" LOC = "P59" | IOSTANDARD = LVCMOS33; NET "GROUND123<1>" LOC = "P96" | IOSTANDARD = LVCMOS33; NET "GROUND123<0>" LOC = "P104" | IOSTANDARD = LVCMOS33;
Code 0-2: uhr.ucf