?? timer_top_struct.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 + -