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

📄 timers.vhd

📁 宇航级微处理器LEON2 2.2 VHDL源代码,很难找的.
💻 VHD
字号:
------------------------------------------------------------------------------  This file is a part of the LEON VHDL model--  Copyright (C) 1999  European Space Agency (ESA)----  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 of the License, or (at your option) any later version.----  See the file COPYING.LGPL for the full details of the license.------------------------------------------------------------------------------- Entity: 	timers-- File:	timers.vhd-- Author:	Jiri Gaisler - ESA/ESTEC-- Description:	This unit implemets two general-pupose timers and one watchdog.--		All three timers are 24-bit wide down-counters clocked by a--		common 10-bit pre-scaler. The pre-scaler is clocked by the--		system clock. All three timers share the same decrementer--		which means that the minimum pre-scaler division is three.--		On reset, the scaler and watchdog are set to 'all-ones',--		the two GP-timers disabled, and the remaining registers are--		'unknown'.------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.std_logic_unsigned."-";use IEEE.std_logic_unsigned."+";use work.target.all;use work.config.all;use work.iface.all;use work.macro.all;use work.amba.all;entity timers is  port (    rst    : in  std_logic;    clk    : in  clk_type;    apbi   : in  apb_slv_in_type;    apbo   : out apb_slv_out_type;    timo   : out timers_out_type  );end;  architecture rtl of timers istype timer_control_type is record  enable	:  std_logic;	-- enable counter  load		:  std_logic;	-- load counter  restart	:  std_logic;	-- restart counter  irq   	:  std_logic;	-- interruptend record;type timregs is record  t0value 	:  std_logic_vector(23 downto 0);  t0load	:  std_logic_vector(23 downto 0);  t0ctrl   	:  timer_control_type;  t1value 	:  std_logic_vector(23 downto 0);  t1load	:  std_logic_vector(23 downto 0);  t1ctrl   	:  timer_control_type;  scalerval	:  std_logic_vector(9 downto 0);  scalerpre 	:  std_logic_vector(9 downto 0);  tick          :  std_logic;  tsel   	:  std_logic_vector(1 downto 0);end record;type wdogregs is record  wdog   	:  std_logic_vector(23 downto 0);  wdogtout      :  std_logic;end record;constant zero :  std_logic_vector(23 downto 0) := (others => '0');signal r, rin : timregs;signal wr, wrin : wdogregs;-- Main processbegin  timerop : process(rst, r, apbi)  variable sval : std_logic_vector(10 downto 0);  variable rdata : std_logic_vector(31 downto 0);  variable res, addin : std_logic_vector(23 downto 0);  variable tv : timregs;  variable wv : wdogregs;  variable z : std_logic;  begin    tv := r; tv.t0ctrl.irq := '0'; tv.t1ctrl.irq := '0';    tv.t0ctrl.load := '0'; tv.t1ctrl.load := '0';     wv := wr;-- scaler operation-- pragma translate_off    if not is_x(r.scalerval) then-- pragma translate_on      sval := ('0' & r.scalerval) - 1;		-- decrement scaler-- pragma translate_off    end if;-- pragma translate_on    if sval(10) = '1' then      tv.scalerval := r.scalerpre;			-- reload if carry-out    else      tv.scalerval := sval(9 downto 0);    end if;    tv.tick := sval(10);-- timer operation    if (r.tick = '1') or (r.tsel /= "00") then-- pragma translate_off      if not is_x(r.tsel) then-- pragma translate_on        tv.tsel := r.tsel + 1;-- pragma translate_off      end if;-- pragma translate_on    end if;    addin := (others => '-');    case r.tsel is		-- select which timer to operate on    when "01" => addin := r.t0value;    when "10" => addin := r.t1value;    when "11" => if WDOGEN then addin := wr.wdog; end if;    when others =>    end case;-- pragma translate_off    if not is_x(addin) then -- pragma translate_on      res := addin - 1;   -- decrement timer      if addin = zero then z := '1'; else z := '0'; end if; -- zero detect-- pragma translate_off    end if;-- pragma translate_on-- update corresponding register and generate irq/wdrst    case r.tsel is		-- select which timer to operate on    when "01" =>      if r.t0ctrl.enable = '1' then        tv.t0ctrl.irq := z;	if z = '1' then           tv.t0ctrl.enable := r.t0ctrl.restart;          if r.t0ctrl.restart = '1' then tv.t0value := r.t0load; end if;	else tv.t0value := res; end if;      end if;    when "10" =>      if r.t1ctrl.enable = '1' then        tv.t1ctrl.irq := z;	if z = '1' then           tv.t1ctrl.enable := r.t1ctrl.restart;          if r.t1ctrl.restart = '1' then tv.t1value := r.t1load; end if;	else tv.t1value := res; end if;      end if;    when "11" =>      if WDOGEN then        wv.wdogtout := z;        if z = '0' then wv.wdog := res; end if;      end if;    when others =>    end case;    if r.t0ctrl.load = '1' then tv.t0value := r.t0load; end if;    if r.t1ctrl.load = '1' then tv.t1value := r.t1load; end if;-- read/write registers    rdata := (others => '0');    case apbi.paddr(5 downto 2) is    when "0000" => rdata(23 downto 0) := r.t0value;    when "0001" => rdata(23 downto 0) := r.t0load;    when "0010" => rdata(1 downto 0) := r.t0ctrl.restart & r.t0ctrl.enable;    when "0011" => if WDOGEN then rdata(23 downto 0) := wr.wdog; end if;    when "0100" =>  rdata(23 downto 0) := r.t1value;    when "0101" => rdata(23 downto 0) := r.t1load;    when "0110" => rdata(1 downto 0) := r.t1ctrl.restart & r.t1ctrl.enable;    when "1000" => rdata(9 downto 0)  := r.scalerval;    when "1001" => rdata(9 downto 0)  := r.scalerpre;    when others => rdata(9 downto 0)  := (others => '-');    end case;    if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then      case apbi.paddr(5 downto 2) is      when "0000" => tv.t0value := apbi.pwdata(23 downto 0);      when "0001" => tv.t0load := apbi.pwdata(23 downto 0);      when "0010" => tv.t0ctrl.load := apbi.pwdata(2);		     tv.t0ctrl.restart := apbi.pwdata(1);	             tv.t0ctrl.enable := apbi.pwdata(0);      when "0011" => if WDOGEN then wv.wdog := apbi.pwdata(23 downto 0); end if;      when "0100" => tv.t1value := apbi.pwdata(23 downto 0);      when "0101" => tv.t1load := apbi.pwdata(23 downto 0);      when "0110" => tv.t1ctrl.load := apbi.pwdata(2);	             tv.t1ctrl.restart := apbi.pwdata(1);	             tv.t1ctrl.enable := apbi.pwdata(0);      when "1000" => tv.scalerval := apbi.pwdata(9 downto 0);      when "1001" => tv.scalerpre := apbi.pwdata(9 downto 0);      when others => null;      end case;    end if;-- reset operation    if rst = '0' then       tv.t0ctrl.enable := '0'; tv.t1ctrl.enable := '0';      if WDOGEN then wv.wdog := (others => '1'); wv.wdogtout := '0'; end if;      if BOOTOPT /= memory then        tv.scalerval := std_logic_vector(TPRESC(9 downto 0));	tv.scalerpre := std_logic_vector(TPRESC(9 downto 0));       else        tv.scalerval := (others => '0'); tv.scalerpre := (others => '0');       end if;      tv.tsel := "00";    end if;    rin <= tv; wrin <= wv;	-- update registers    apbo.prdata <= rdata; 	-- drive data bus  end process;-- Registers  regs : process(clk)  begin    if rising_edge(clk) then      r <= rin;    end if;  end process;  wd : if WDOGEN generate    regs : process(clk)    begin      if rising_edge(clk) then        wr <= wrin;      end if;    end process;  end generate;-- Drive outputs  timo.tick <= r.tick;  timo.irq <= r.t1ctrl.irq & r.t0ctrl.irq;  timo.wdog <= not wr.wdogtout when WDOGEN else '-';end;

⌨️ 快捷键说明

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