OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [timer.vhd] - Diff between revs 19 and 22

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 19 Rev 22
Line 5... Line 5...
--  www.OpenCores.Org - September 2003
--  www.OpenCores.Org - September 2003
--  This core adheres to the GNU public license  
--  This core adheres to the GNU public license  
--
--
-- File name      : timer.vhd
-- File name      : timer.vhd
--
--
-- Purpose        : 9 bit timer module for System 09
-- Purpose        : 8 bit timer module for System 09
--
--
-- Dependencies   : ieee.Std_Logic_1164
-- Dependencies   : ieee.Std_Logic_1164
--                  ieee.std_logic_unsigned
--                  ieee.std_logic_unsigned
--
--
-- Uses           : None
-- Uses           : None
Line 28... Line 28...
--
--
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Version 1.0 - 6 Sept 2003 - John Kent
-- Realeased to open Cores
-- Realeased to open Cores
-- changed Clock Edge
-- changed Clock Edge
--
--
 
-- Version 2.0 - 5th February 2008 - John Kent
 
-- removed Timer inputs and outputs
 
-- made into a simple 8 bit interrupt down counter
 
--
--===========================================================================
--===========================================================================
--
--
-- Register Addressing:
-- Register Addressing:
-- addr=0 rw=1 down count
-- addr=0 rw=1 down count
-- addr=0 rw=0 preset count
-- addr=0 rw=0 preset count
-- addr=1 rw=1 status
-- addr=1 rw=1 status
-- addr=1 rw=0 control
-- addr=1 rw=0 control
--
--
-- Control register
-- Control register
-- b0 = counter enable
-- b0 = counter enable
-- b1 = mode (0 = counter, 1 = timer)
 
-- b7 = interrupt enable
-- b7 = interrupt enable
--
--
-- Status register
-- Status register
-- b6 = timer output
 
-- b7 = interrupt flag
-- b7 = interrupt flag
--
--
 
-- Operation:
 
-- Write count to counter register
 
-- Enable counter by setting bit 0 of the control register
 
-- enable interrupts by setting bit 7 of the control register
 
-- Counter will count down to zero
 
-- when it reaches zero the terminal flag is set
 
-- if the interrupt is enabled an interrupt is generated
 
-- The interrupt may be disabled by writing a 0 to bit 7 of the control register
 
-- or by loading a new down count into the counter register.
 
-- 
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
 
 
entity timer is
entity timer is
Line 58... Line 70...
    cs         : in  std_logic;
    cs         : in  std_logic;
    rw         : in  std_logic;
    rw         : in  std_logic;
    addr       : in  std_logic;
    addr       : in  std_logic;
    data_in    : in  std_logic_vector(7 downto 0);
    data_in    : in  std_logic_vector(7 downto 0);
         data_out   : out std_logic_vector(7 downto 0);
         data_out   : out std_logic_vector(7 downto 0);
         irq        : out std_logic;
         irq        : out std_logic
         timer_in   : in  std_logic;
 
         timer_out  : out std_logic
 
  );
  );
end;
end;
 
 
architecture rtl of timer is
architecture rtl of timer is
signal timer_ctrl  : std_logic_vector(7 downto 0);
signal timer_ctrl  : std_logic_vector(7 downto 0);
signal timer_stat  : std_logic_vector(7 downto 0);
signal timer_stat  : std_logic_vector(7 downto 0);
signal timer_reg   : std_logic_vector(7 downto 0);
 
signal timer_count : std_logic_vector(7 downto 0);
signal timer_count : std_logic_vector(7 downto 0);
signal timer_int   : std_logic; -- Timer interrupt
 
signal timer_term  : std_logic; -- Timer terminal count
signal timer_term  : std_logic; -- Timer terminal count
signal timer_tog   : std_logic; -- Timer output
 
--
--
-- control/status register bits
-- control/status register bits
--
--
constant T_enab   : integer := 0; -- 0=disable, 1=enabled
constant T_enab   : integer := 0; -- 0=disable, 1=enabled
constant T_mode   : integer := 1; -- 0=counter, 1=timer
 
constant T_out    : integer := 6; -- 0=disabled, 1=enabled
 
constant T_irq    : integer := 7; -- 0=disabled, 1-enabled
constant T_irq    : integer := 7; -- 0=disabled, 1-enabled
 
 
begin
begin
 
 
--------------------------------
--------------------------------
Line 89... Line 94...
-- write control registers
-- write control registers
-- doesn't do anything yet
-- doesn't do anything yet
--
--
--------------------------------
--------------------------------
timer_write : process( clk, rst, cs, rw, addr, data_in,
timer_write : process( clk, rst, cs, rw, addr, data_in,
                       timer_reg, timer_ctrl, timer_term, timer_count )
                       timer_ctrl, timer_term, timer_count )
begin
begin
  if clk'event and clk = '0' then
 
    if rst = '1' then
    if rst = '1' then
           timer_reg <= "00000000";
           timer_count <= "00000000";
                timer_ctrl <= "00000000";
                timer_ctrl <= "00000000";
    elsif cs = '1' and rw = '0' then
                timer_term  <= '0';
 
  elsif clk'event and clk = '0' then
 
    if cs = '1' and rw = '0' then
           if addr='0' then
           if addr='0' then
                  timer_reg <= data_in;
                  timer_count <= data_in;
                  timer_ctrl <= timer_ctrl;
 
                  timer_term <= '0';
                  timer_term <= '0';
           else
           else
                  timer_reg <= timer_reg;
 
                  timer_ctrl <= data_in;
                  timer_ctrl <= data_in;
                  timer_term <= timer_term;
 
                end if;
                end if;
         else
         else
           timer_ctrl <= timer_ctrl;
 
                timer_reg <= timer_reg;
 
           if (timer_ctrl(T_enab) = '1') then
           if (timer_ctrl(T_enab) = '1') then
                  if (timer_count = "00000000" ) then
                  if (timer_count = "00000000" ) then
                    timer_term <= '1';
                    timer_term <= '1';
                  elsif timer_ctrl(T_mode) = '0' then
 
                    timer_term <= '0'; -- counter mode, reset on non zero
 
                  else
                  else
                    timer_term <= timer_term; -- timer mode, keep as is
          timer_count <= timer_count - 1;
                  end if;
                  end if;
                else
 
                  timer_term <= timer_term;
 
                end if;
                end if;
    end if;
    end if;
  end if;
  end if;
end process;
end process;
 
 
Line 135... Line 132...
  else
  else
    data_out <= timer_stat;
    data_out <= timer_stat;
  end if;
  end if;
end process;
end process;
 
 
--------------------------------
 
--
 
-- counters
 
--
 
--------------------------------
 
 
 
my_counter: process( clk, rst, timer_ctrl, timer_count, timer_reg, timer_in )
 
variable timer_tmp : std_logic;
 
begin
 
  if clk'event and clk = '0' then
 
    if rst = '1' then
 
           timer_count <= "00000000";
 
                timer_tmp := '0';
 
    else
 
      if timer_ctrl( T_enab ) = '1' then
 
                  if timer_in = '0' and timer_tmp = '1' then
 
                    timer_tmp := '0';
 
          if timer_count = "00000000" then
 
                      timer_count <= timer_reg;
 
                    else
 
                 timer_count <= timer_count - 1;
 
                    end if;
 
                  elsif timer_in = '1' and timer_tmp = '0' then
 
                    timer_tmp := '1';
 
               timer_count <= timer_count;
 
                  else
 
                    timer_tmp := timer_tmp;
 
               timer_count <= timer_count;
 
                  end if;
 
                else
 
                  timer_tmp := timer_tmp;
 
             timer_count <= timer_count;
 
           end if; -- timer_ctrl
 
    end if; -- rst
 
  end if; -- clk
 
end process;
 
 
 
--
--
-- read timer strobe to reset interrupts
-- read timer strobe to reset interrupts
--
--
  timer_interrupt : process( Clk, rst, cs, rw, addr,
timer_interrupt : process( timer_term, timer_ctrl )
                             timer_term, timer_int, timer_ctrl )
 
  begin
  begin
    if clk'event and clk = '0' then
         irq <= timer_term and timer_ctrl( T_irq );
           if rst = '1' then
 
                  timer_int <= '0';
 
      elsif cs = '1' and rw = '1' then
 
             if addr = '0' then
 
                    timer_int <= '0'; -- reset interrupt on read count
 
                  else
 
                    timer_int <= timer_int;
 
                  end if;
 
           else
 
             if timer_term = '1' then
 
                    timer_int <= '1';
 
                  else
 
                    timer_int <= timer_int;
 
                  end if;
 
      end if;
 
    end if;
 
 
 
    if timer_ctrl( T_irq ) = '1' then
 
           irq <= timer_int;
 
         else
 
           irq <= '0';
 
         end if;
 
  end process;
  end process;
 
 
  --
  --
  -- timer status register
  -- timer status register
  --
  --
  timer_status : process( timer_ctrl, timer_int, timer_tog )
  timer_status : process( timer_ctrl, timer_term )
  begin
  begin
    timer_stat(5 downto 0) <= timer_ctrl(5 downto 0);
    timer_stat(6 downto 0) <= timer_ctrl(6 downto 0);
         timer_stat(T_out) <= timer_tog;
    timer_stat(T_irq) <= timer_term;
    timer_stat(T_irq) <= timer_int;
 
  end process;
 
 
 
  --
 
  -- timer output
 
  --
 
  timer_output : process( Clk, rst, timer_term, timer_ctrl, timer_tog )
 
  variable timer_tmp : std_logic; -- tracks change in terminal count
 
  begin
 
    if clk'event and clk = '0' then
 
      if rst = '1' then
 
             timer_tog <= '0';
 
                  timer_tmp := '0';
 
           elsif timer_ctrl(T_mode) = '0' then -- free running ?
 
                  if (timer_term = '1') and (timer_tmp = '0') then
 
                    timer_tmp := '1';
 
                         timer_tog <= not timer_tog;
 
                  elsif (timer_term = '0') and (timer_tmp = '1') then
 
                    timer_tmp := '0';
 
                         timer_tog <= timer_tog;
 
                  else
 
                    timer_tmp := timer_tmp;
 
                         timer_tog <= timer_tog;
 
                  end if;
 
                else                            -- one shot timer mode, follow terminal count
 
                  if (timer_term = '1') and (timer_tmp = '0') then
 
                    timer_tmp := '1';
 
                         timer_tog <= '1';
 
                  elsif (timer_term = '0') and (timer_tmp = '1') then
 
                    timer_tmp := '0';
 
                         timer_tog <= '0';
 
                  else
 
                    timer_tmp := timer_tmp;
 
                         timer_tog <= timer_tog;
 
                  end if;
 
                end if;
 
         end if;
 
    timer_out <= timer_tog and timer_ctrl(T_out);
 
  end process;
  end process;
 
 
end rtl;
end rtl;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.