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

📄 timer_counter.vhd

📁 another avr core porocesssor vhdl source code
💻 VHD
📖 第 1 页 / 共 3 页
字号:
end if;	 
end process;	
	
-- -------------------------------------------------------------------------------------------
-- Prescalers
-- -------------------------------------------------------------------------------------------	
	
-- Prescaler 1 for TCNT1 and TCNT2
Prescaler_1:process(cp2,ireset)
begin
if  ireset='0'  then                 -- Reset
 Pre1Cnt <= (others => '0'); 
 CK8 <= '0';
 CK64 <= '0';
 CK256 <= '0';
 CK1024 <= '0';
 EXT1RE <= '0';
 EXT1FE <= '0';
 EXT2RE <= '0';
 EXT2FE <= '0';
 EXT1Latched <= '0';
 EXT2Latched <= '0';
  elsif  cp2='1' and cp2'event  then -- Clock
    Pre1Cnt <= Pre1Cnt+1;
	 CK8 <= not CK8 and(Pre1Cnt(0) and Pre1Cnt(1)and Pre1Cnt(2));
     CK64 <= not CK64 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5));
     CK256 <= not CK256 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5) and Pre1Cnt(6) and Pre1Cnt(7));
     CK1024 <= not CK1024 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5) and Pre1Cnt(6) and Pre1Cnt(7) and Pre1Cnt(8) and Pre1Cnt(9));
     EXT1RE <= not EXT1RE and (EXT1SB and not EXT1Latched);
     EXT1FE <= not EXT1FE and (not EXT1SB and EXT1Latched);
     EXT2RE <= not EXT2RE and (EXT2SB and not EXT2Latched);
     EXT2FE <= not EXT2FE and (not EXT2SB and EXT2Latched);
     EXT1Latched <= EXT1SB;
     EXT2Latched <= EXT2SB;  
  end if;
end process;		

TCNT1_En <= (not CS12 and not CS11 and CS10) or            -- CK             "001"
            (CK8 and not CS12 and CS11 and not CS10) or    -- CK/8			 "010"
			(CK64 and not CS12 and CS11 and CS10)    or    -- CK/64			 "011"
			(CK256 and CS12 and not CS11 and not CS10) or  -- CK/256		 "100"
            (CK64 and CS12 and not CS11 and CS10)    or    -- CK/1024		 "101"
			(EXT1FE and CS12 and CS11 and not CS10) or     -- Falling edge	 "110"
            (EXT1RE and CS12 and CS11 and CS10);           -- Rising edge	 "111"
			
TCNT2_En <= (not CS22 and not CS21 and CS20) or            -- CK             "001"
            (CK8 and not CS22 and CS21 and not CS20) or    -- CK/8			 "010"
			(CK64 and not CS22 and CS21 and CS20)    or    -- CK/64			 "011"
			(CK256 and CS22 and not CS21 and not CS20) or  -- CK/256		 "100"
            (CK64 and CS22 and not CS21 and CS20)    or    -- CK/1024		 "101"
			(EXT2FE and CS22 and CS21 and not CS20) or     -- Falling edge	 "110"
            (EXT2RE and CS22 and CS21 and CS20);           -- Rising edge	 "111"


-- Prescaler 0 for TCNT0
Tosc1_Rising_Edge_Detector:process(cp2,ireset)
begin
 if ireset='0' then  --Reset
  Tosc1RE <= '0';
  Tosc1Latched <= '0';
     elsif  cp2='1' and cp2'event  then -- Clock
	Tosc1RE <= not Tosc1RE and (not Tosc1Latched and Tosc1SB); 
    Tosc1Latched <= Tosc1SB;
	 end if;	
end process;	

PCK0 <= Tosc1RE when AS0='1' else '1';
	
Prescaler_0_Cnt:process(cp2,ireset)
begin
if  ireset='0'  then                   -- Reset
 Pre0Cnt <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then -- Clock
    if PCK0='1' then                   -- Clock enable
	 Pre0Cnt <= Pre0Cnt+1;
	end if;
	   end if;
end process;					

Prescaler_0:process(cp2,ireset)
begin
if  ireset='0'  then                   -- Reset
 PCK08 <= '0';
 PCK032 <= '0';
 PCK064 <= '0';
 PCK0128 <= '0';
 PCK0256 <= '0';
 PCK01024 <= '0';
 PCK0_Del <= '0';
  elsif  cp2='1' and cp2'event  then -- Clock
	 PCK08 <= (not PCK08 and(Pre0Cnt(0) and Pre0Cnt(1)and Pre0Cnt(2)) and PCK0_Del);
     PCK032 <= (not PCK032 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4)) and PCK0_Del); 
	 PCK064 <= (not PCK064 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5)) and PCK0_Del);
     PCK0128 <= (not PCK0128 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and PCK0_Del));
	 PCK0256 <= (not PCK0256 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and Pre0Cnt(7)) and PCK0_Del);
     PCK01024 <= (not PCK01024 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and Pre0Cnt(7) and Pre0Cnt(8) and Pre0Cnt(9)) and PCK0_Del); 
	 PCK0_Del <= PCK0;
  end if;
end process;					


TCNT0_En <= (PCK0 and not CS02 and not CS01 and CS00) or     -- PCK            "001" !!??
            (PCK08 and not CS02 and CS01 and not CS00) or    -- PCK/8		   "010"
			(PCK032 and not CS02 and CS01 and CS00)or	     -- PCK/32		   "011"
			(PCK064 and CS02 and not CS01 and not CS00)or    -- PCK/64		   "100"
			(PCK0128 and CS02 and not CS01 and CS00)or       -- PCK/64		   "101"
			(PCK0256 and CS02 and CS01 and not CS00)or       -- PCK/256		   "110"
            (PCK01024 and CS02 and CS01 and CS00);           -- PCK/1024	   "111"

-- -------------------------------------------------------------------------------------------
-- End of prescalers
-- -------------------------------------------------------------------------------------------
			
-- I/O address decoder
TCCR0_Sel  <= '1' when adr=TCCR0_Address else '0';
TCCR1A_Sel <= '1' when adr=TCCR1A_Address else '0';
TCCR1B_Sel <= '1' when adr=TCCR1B_Address else '0';
TCCR2_Sel  <= '1' when adr=TCCR2_Address else '0';
ASSR_Sel   <= '1' when adr=ASSR_Address else '0';
TIMSK_Sel  <= '1' when adr=TIMSK_Address else '0';
TIFR_Sel   <= '1' when adr=TIFR_Address else '0';
TCNT0_Sel  <= '1' when adr=TCNT0_Address else '0';
TCNT2_Sel  <= '1' when adr=TCNT2_Address else '0';
OCR0_Sel   <= '1' when adr=OCR0_Address else '0';
OCR2_Sel   <= '1' when adr=OCR2_Address else '0';
TCNT1H_Sel <= '1' when adr=TCNT1H_Address else '0';
TCNT1L_Sel <= '1' when adr=TCNT1L_Address else '0';
OCR1AH_Sel <= '1' when adr=OCR1AH_Address else '0';
OCR1AL_Sel <= '1' when adr=OCR1AL_Address else '0';
OCR1BH_Sel <= '1' when adr=OCR1BH_Address else '0';
OCR1BL_Sel <= '1' when adr=OCR1BL_Address else '0';
ICR1AH_Sel <= '1' when adr=ICR1AH_Address else '0';
ICR1AL_Sel <= '1' when adr=ICR1AL_Address else '0';
		

-- -------------------------------------------------------------------------------------------
-- Timer/Counter0
-- -------------------------------------------------------------------------------------------

-- Attention !!! This model only emulates the asynchronous mode of TCNT0. 
-- Real TCNT0 of ATmega103/603 operates with two separate clock sources.

Counter_0:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 TCNT0 <= (others => '0'); 
   elsif  cp2='1' and cp2'event  then                      -- Clock
    if (TCNT0_En or TCNT0_Clr or TCNT0_Ld_Imm)='1' then   -- Clock enable
	 TCNT0 <= TCNT0_In;
	end if;
	   end if;
end process;				

Counter_0_Inc:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
  	TCNT0_Inc <= '0'; 
   elsif  cp2='1' and cp2'event  then                      -- Clock
	 TCNT0_Inc <= (not TCNT0_Inc and(TCNT0_En and not TCNT0_Ld_Imm))or(TCNT0_Inc and not(TCNT0_Ld_Imm));
	   end if;
end process;				


TCNT0_In <= TCNT0_Imm_In    when TCNT0_Ld_Imm = '1' else -- Immediate value (from dbus_in or TCNT0_Tmp)
            (others => '0') when TCNT0_Clr ='1'	else     -- Synchronous clear (for OCR)
			TCNT0-1 when TCNT0_Cnt_Dir='1' else			 -- Decrement (for PWM)
			TCNT0+1;									 -- Icrement (for counter and PWM)
				

TCNT0_Imm_In <= TCNT0_Tmp when (TCN0UB and not TCN0UB_Tmp and PCK0 and AS0)='1' else dbus_in;
TCNT0_Clr <= TCNT0_Cmp_Out and CTC0 and not PWM0;
TCNT0_Cmp_Out <= '1' when (TCNT0=OCR0 and OCR0/=x"00" and TCNT0_Inc='1') else '0';
TCNT0_Ld_Imm <= (TCNT0_Sel and iowe and not AS0) or (TCN0UB and not TCN0UB_Tmp and PCK0 and AS0);
	
	
TCCR0_Control:process(cp2,ireset)
begin
if ireset='0' then                  -- Reset
 TCNT0_Cnt_Dir <= '0';
 
 TCR0UB_Tmp <= '0';
 OCR0UB_Tmp <= '0';
 TCN0UB_Tmp <= '0';
 
 ASSR <= (others => '0');
  
elsif cp2='1' and cp2'event then  -- Clock
   TCNT0_Cnt_Dir <= (not TCNT0_Cnt_Dir and(TCNT0(7) and TCNT0(6) and TCNT0(5) and TCNT0(4) and TCNT0(3) and TCNT0(2) and TCNT0(1) and not TCNT0(0) and TCNT0_En and PWM0)) or           -- 0xFE
   (TCNT0_Cnt_Dir and not ((not TCNT0(7) and not TCNT0(6) and not TCNT0(5) and not TCNT0(4) and not TCNT0(3) and not TCNT0(2) and not TCNT0(1) and TCNT0(0)and TCNT0_En) or not PWM0));	-- 0x01
   
   TCR0UB_Tmp <= (not TCR0UB_Tmp and (TCCR0_Sel and iowe and AS0))or
   				 (TCR0UB_Tmp and not PCK0);
   OCR0UB_Tmp <= (not OCR0UB_Tmp and (OCR0_Sel and iowe and AS0))or
                 (OCR0UB_Tmp and not PCK0);
   TCN0UB_Tmp <= (not TCN0UB_Tmp and (TCNT0_Sel and iowe and AS0))or
   				 (TCN0UB_Tmp and not PCK0);
   
  TCR0UB <= (not TCR0UB and (TCCR0_Sel and iowe and AS0))or
   		    (TCR0UB and not (not TCR0UB_Tmp and PCK0));
  OCR0UB <= (not OCR0UB and (OCR0_Sel and iowe and AS0))or
            (OCR0UB and not (not OCR0UB_Tmp and PCK0));
  TCN0UB <= (not TCN0UB and (TCNT0_Sel and iowe and AS0))or
   			(TCN0UB and not (not TCN0UB_Tmp and PCK0));
  
  AS0    <= (not AS0 and(ASSR_Sel and iowe and dbus_in(3)))or 
            (AS0 and not(ASSR_Sel and iowe and not dbus_in(3)));		   

  end if;
end process;				
	
	
-- Temp registers of TCNT0

-- This register is used only when TCNT0 operates in the asynchronous mode
TCNT0_Temp_Control:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 TCCR0_Tmp <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then                      -- Clock
    if (TCCR0_Sel and iowe and AS0)='1' then              -- Clock enable
	 TCCR0_Tmp <= dbus_in;
	end if;
	   end if;
end process;				

-- This register is used only when TCNT0 operates in the asynchronous mode
TCNT0_Temp_CNT:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 TCNT0_Tmp <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then                      -- Clock
    if (TCNT0_Sel and iowe and AS0)='1' then              -- Clock enable
	 TCNT0_Tmp <= dbus_in;
	end if;
	   end if;
end process;				

TCNT0_Temp_Compare:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 OCR0_Tmp <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then                      -- Clock
    if (OCR0_Sel and iowe )='1' then     -- Clock enable ??!! was "and (AS0 or PWM0)"
	 OCR0_Tmp <= dbus_in;
	end if;
	   end if;
end process;				

-- Main registers of TCNT0
TCNT0_Control:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 TCCR0 <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then                      -- Clock
    if ((TCCR0_Sel and iowe and not AS0)or
		(TCR0UB and not TCR0UB_Tmp and PCK0 and AS0))='1' then              -- Clock enable
	 TCCR0(6 downto 0) <= TCCR0_In(6 downto 0);
	end if;
	   end if;
end process;				

TCCR0_In <= TCCR0_Tmp when (TCR0UB and not TCR0UB_Tmp and PCK0 and AS0)='1' else dbus_in;

TCNT0_Compare:process(cp2,ireset)
begin
if  ireset='0'  then                                      -- Reset
 OCR0 <= (others => '0'); 
  elsif  cp2='1' and cp2'event  then                      -- Clock
    if  ((((OCR0_Sel and iowe and not AS0)or                              -- Synchronous non PWM mode 

⌨️ 快捷键说明

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