⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer_top_struct.vhd

📁 Run Pac-man Game Based on 8086/8088 FPGA IP Core
💻 VHD
字号:
-------------------------------------------------------------------------------
--                                                                           --
--  CPU86 - VHDL CPU8088 IP core                                             --
--  Copyright (C) 2005 HT-LAB                                                --
--                                                                           --
--  Contact : mailto:cpu86@ht-lab.com                                        --
--  Web: http://www.ht-lab.com                                               --
--                                                                           --
-------------------------------------------------------------------------------
--                                                                           --
--  This library is free software; you can redistribute it and/or            --
--  modify it under the terms of the GNU Lesser General Public               --
--  License as published by the Free Software Foundation; either             --
--  version 2.1 of the License, or (at your option) any later version.       --
--                                                                           --
--  This library is distributed in the hope that it will be useful,          --
--  but WITHOUT ANY WARRANTY; without even the implied warranty of           --
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        --
--  Lesser General Public License for more details.                          --
--                                                                           --
--  Full details of the license can be found in the file "copying.txt".      --
--                                                                           --
--  You should have received a copy of the GNU Lesser General Public         --
--  License along with this library; if not, write to the Free Software      --
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  --
--                                                                           --
-------------------------------------------------------------------------------
--
-- VHDL Architecture Timer.timer_top.symbol
--
-- Created: by - Hans 22/08/2005
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;

ENTITY timer_top IS
   GENERIC( 
      DIVIDER_91HZ : integer := 359256
   );
   PORT( 
      abus     : IN     std_logic;
      clk      : IN     std_logic;
      csn      : IN     std_logic;
      dbus_in  : IN     std_logic_vector (7 DOWNTO 0);
      resetn   : IN     std_logic;
      wrn      : IN     std_logic;
      dbus_out : OUT    std_logic_vector (7 DOWNTO 0);
      pulse182 : OUT    std_logic
   );

-- Declarations

END timer_top ;

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ARCHITECTURE struct OF timer_top IS

   -- Architecture declarations

   -- Internal signal declarations
   SIGNAL date         : std_logic_vector(5 DOWNTO 0);
   SIGNAL hours        : std_logic_vector(4 DOWNTO 0);
   SIGNAL leap_years_s : std_logic;
   SIGNAL minutes      : std_logic_vector(5 DOWNTO 0);
   SIGNAL months       : std_logic_vector(3 DOWNTO 0);
   SIGNAL pulse1sec_s  : std_logic;
   SIGNAL regsel_s     : std_logic_vector(3 DOWNTO 0);
   SIGNAL seconds      : std_logic_vector(5 DOWNTO 0);
   SIGNAL uip_flag_s   : std_logic;
   SIGNAL wr_s         : std_logic;
   SIGNAL years        : std_logic_vector(4 DOWNTO 0);


signal divcnt_s : std_logic_vector(19 downto 0);
signal divcnt18_s:std_logic_vector(2 downto 0); -- 18.2Hz divider
signal divcntsec_s:std_logic_vector(6 downto 0); -- 1 sec divider
signal pulse91_s : std_logic;

   -- Component Declarations
   COMPONENT Timer_fsm
   PORT (
      clk          : IN     std_logic ;
      dbus_in      : IN     std_logic_vector (7 DOWNTO 0);
      leap_years_s : IN     std_logic ;
      pulse1sec_s  : IN     std_logic ;
      regsel_s     : IN     std_logic_vector (3 DOWNTO 0);
      resetn       : IN     std_logic ;
      wr_s         : IN     std_logic ;
      date         : OUT    std_logic_vector (5 DOWNTO 0);
      hours        : OUT    std_logic_vector (4 DOWNTO 0);
      minutes      : OUT    std_logic_vector (5 DOWNTO 0);
      months       : OUT    std_logic_vector (3 DOWNTO 0);
      seconds      : OUT    std_logic_vector (5 DOWNTO 0);
      years        : OUT    std_logic_vector (4 DOWNTO 0)
   );
   END COMPONENT;


BEGIN
   -- Architecture concurrent statements
   -- HDL Embedded Text Block 1 eb1
   -- eb1 1            
   -- Some bits and pieces compatible with IBM XT Motorola MC146818 Real Time Clock
   
   -- 0x71 read/write result register csn=70/71  
   wr_s <= '1' when (abus='1' AND wrn='0' AND csn='0') else '0';
   
   -- 0x70 Write to register select register 
   process (clk,resetn)  
       begin
         if (resetn='0') then                     
            regsel_s <= (others=> '0');
         elsif (rising_edge(clk)) then    
            if (abus='0' AND wrn='0' AND csn='0') then
               regsel_s <= dbus_in(3 downto 0);
            end if;
         end if;   
   end process;    
   
   -- User need to set the DIVIDER_91HZ generic such that the clk/DIVIDER_91HZ=... yes 91Hz :-)
   -- 91Hz is further divided by 5 to generate the 18.2Hz timer tick and 91 to update the RTC.
   
   -- Divide system clock to create 91Hz pulse (clk wide), use 20 bits divider   (clk Fmax=95MHz)
   -- assume default clock of 32.692308MHz   DIVIDER_91HZ=359256 (0x57B58) 
   process (clk,resetn)  
       begin
         if (resetn='0') then                     
            divcnt_s <= (others=> '0');   
            pulse91_s <= '0';                                    
         elsif (rising_edge(clk)) then    
            if divcnt_s=CONV_STD_LOGIC_VECTOR(DIVIDER_91HZ,20) then
               divcnt_s  <= (others => '0');    
               pulse91_s <= '1';            
            else 
               divcnt_s  <= divcnt_s + '1';  
               pulse91_s <= '0';  
            end if;
         end if;   
   end process;    
   
   
   -- Divide pulse91_s/5 to create 18.2Hz pulse
   process (clk,resetn)  
       begin
         if (resetn='0') then                     
            divcnt18_s <= (others => '0');   
            pulse182 <= '0';                                    
         elsif (rising_edge(clk)) then   
              if pulse91_s='1' then  
               if divcnt18_s="100" then    -- 5-1
                  divcnt18_s <= (others => '0');    
                  pulse182 <= '1';            
               else 
                  divcnt18_s    <= divcnt18_s + '1';  
                  pulse182 <= '0';  
               end if;
           else
            pulse182 <= '0';
           end if;
         end if;   
   end process;    
   
   -- Divide pulse91_s/91 to create 1Hz pulse
   -- Create a Update_In_Progress flag which is asserted n cycles before the 1sec pulse
   -- software need to check this flag until negated.
   process (clk,resetn)  
       begin
         if (resetn='0') then                     
            divcntsec_s <= (others => '0');   
            pulse1sec_s <= '0';                                    
         elsif (rising_edge(clk)) then 
            if pulse91_s='1' then  
               if divcntsec_s="1011010" then -- 91-1
                  divcntsec_s <= (others => '0');    
                  pulse1sec_s <= '1';            
               else 
                  divcntsec_s <= divcntsec_s + '1';  
                  pulse1sec_s <= '0';  
               end if;
          else
            pulse1sec_s <= '0';
            end if;
         end if;   
   end process;
   
   -- 10.9msec before the update the uip_flag_s is set, this is far too much time but
   -- easy to implement in hardware and setting the clock doesn't have to be fast, right?
   uip_flag_s <= '1' when (divcntsec_s>="1011010") else '0';    --or pulse1sec_s='1'
       
   

   -- HDL Embedded Text Block 2 eb2
   -- eb2 2    
   --Addr    Function
   --====    =========================================
   -- 00     current second for real-time clock
   -- 01     *not yet implemented * alarm second
   -- 02     current minute
   -- 03     *not yet implemented * alarm minute
   -- 04     current hour
   -- 05     *not yet implemented * alarm hour
   -- 06     *not yet implemented * current day of week (1=Sunday)
   -- 07     current date of month
   -- 08     current month
   -- 09     current year  (final two digits; eg, 93)
   --
   -- 0A     Status Register A - Read/Write except UIP
   -- ==     =========================================
   
   process (regsel_s,seconds,minutes,hours,date,months,years,uip_flag_s) is
      begin
         case regsel_s is
            when "0000"  => dbus_out <= "00"& seconds; 
            when "0010"  => dbus_out <= "00"& minutes; 
            when "0100"  => dbus_out <= "000" & hours; 
            when "0111"  => dbus_out <= "00"& date; 
            when "1000"  => dbus_out <= "0000" & months;
            when "1001"  => dbus_out <= "000" & years; 
            when others  => dbus_out <= uip_flag_s&"0000000"; -- bit 7 update_in_progress flag
         end case;                                    
   end process;

   -- HDL Embedded Text Block 3 leap_lut
   -- leap_lut 3                                        
   -- 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, and 2048
   process(years)
      begin
         case years is
            when "00000" => leap_years_s<='1';    --2000
             when "00100" => leap_years_s<='1';    --2004
             when "01000" => leap_years_s<='1';    --2008
             when "01100" => leap_years_s<='1';    --2012
            when "10000" => leap_years_s<='1';    --2016 
            when "10100" => leap_years_s<='1';    --2020 
            when "11100" => leap_years_s<='1';    --2028 I will be amazed if this module is still used by then :-)
             when  others => leap_years_s<='0';
         end case;
   end process;

   -- Instance port mappings.
   I0 : Timer_fsm
      PORT MAP (
         clk          => clk,
         dbus_in      => dbus_in,
         leap_years_s => leap_years_s,
         pulse1sec_s  => pulse1sec_s,
         regsel_s     => regsel_s,
         resetn       => resetn,
         wr_s         => wr_s,
         date         => date,
         hours        => hours,
         minutes      => minutes,
         months       => months,
         seconds      => seconds,
         years        => years
      );

END struct;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -