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

📄 timer_counter.vhd

📁 avr core porocesssor vhdl source code
💻 VHD
📖 第 1 页 / 共 2 页
字号:
  Tosc1Latched <= '0';
     elsif (cp2='1' and cp2'event) then -- Clock
	Tosc1RE <= not Tosc1RE and (not Tosc1Latched and Tosc1); 
    Tosc1Latched <= Tosc1;
	 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 Counter 0	**************************************
-- 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);
	
	
Counter_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 
		(OCR0UB and not OCR0UB_Tmp and PCK0 and AS0))and not PWM0)or      -- Asynchronous non PWM mode
		(TCNT0(7) and TCNT0(6) and TCNT0(5) and TCNT0(4) and TCNT0(3) and TCNT0(2) and TCNT0(1) and TCNT0(0) and PWM0 and TCNT0_En)) -- Reload OCR0 with new value when TCNT0=0xFF (for PWM)
		 ='1' then     -- Clock enable ??!!
	  OCR0 <= OCR0_In;
	end if;
	   end if;
end process;				

-- OCR0 can be loaded from OCR0_Tmp (asynchronous non PWM mode, asynchronous PWM mode ) or from dbus_in	(synchronous non PWM mode only)
OCR0_In <= OCR0_Tmp when ((TCR0UB and not TCR0UB_Tmp and PCK0 and AS0 and not PWM0)or
(TCNT0(7) and TCNT0(6) and TCNT0(5) and TCNT0(4) and TCNT0(3) and TCNT0(2) and TCNT0(1) and TCNT0(0) and PWM0 and TCNT0_En))='1' else dbus_in;

--OC0_PWM0 output 
-- Attention! In the real ATmega103 chip this output of the TCNT0 combined with PB4

Output_TCNT0:process(cp2,ireset)
begin
if (ireset='0') then                                      -- Reset
 OC0_PWM0_Int <= '0'; 
  elsif (cp2='1' and cp2'event) then                      -- Clock
     
case OC0_PWM0_Int is
-- Set
when '0' =>
if (not PWM0 and COM00 and TCNT0_Cmp_Out)='1' or	 -- Compare mode - Toggle/Set ??!!
((PWM0 and COM01 and TCNT0_En)='1' and				 -- PWM modes : 
((TCNT0=x"FF" and COM00='1' and OCR0_Tmp=x"00")or	 -- Inverted PWM
(TCNT0=x"FF" and COM00='0' and OCR0_Tmp=x"FF")or	 -- Non-inverted PWM
(TCNT0=x"FF" and COM00='1' and OCR0_Tmp/=x"FF")or	 -- Inverted PWM
(TCNT0/=x"FF" and TCNT0_Cnt_Dir='1' and COM00='0' and OCR0_Tmp/=x"00" and OCR0=TCNT0)or	 -- Non-inverted PWM	
(TCNT0/=x"FF" and TCNT0_Cnt_Dir='0' and COM00='1' and OCR0_Tmp/=x"00" and OCR0=TCNT0)))	 -- Inverted PWM	
then 	
OC0_PWM0_Int <= '1';
end if;
-- Reset
when '1' =>	
if (not PWM0 and (COM01 or COM00) and TCNT0_Cmp_Out)='1' or	-- Compare mode - Toggle/Reset ??!!
((PWM0 and COM01 and TCNT0_En)='1' and				-- PWM modes : 
((TCNT0=x"FF" and COM00='1' and OCR0_Tmp=x"FF")or	-- Inverted PWM
(TCNT0=x"FF" and COM00='0' and OCR0_Tmp=x"00")or	-- Non-inverted PWM
(TCNT0=x"FF" and COM00='0' and OCR0_Tmp/=x"FF")or	-- Non-inverted PWM
(TCNT0/=x"FF" and TCNT0_Cnt_Dir='0' and COM00='0' and OCR0_Tmp/=x"00" and OCR0=TCNT0)or	 -- Non-inverted PWM	
(TCNT0/=x"FF" and TCNT0_Cnt_Dir='1' and COM00='1' and OCR0_Tmp/=x"00" and OCR0=TCNT0)))	 -- Inverted PWM		
then 	
OC0_PWM0_Int <= '0';
end if;

when others => null;
	
end case;	
	  
end if;																		  
end process;				

OC0_PWM0 <= OC0_PWM0_Int;
	
Common_Out_Mux: for i in dbus_out'range generate
dbus_out(i)	<= (TCCR0(i) and (TCCR0_Sel and not AS0))or  -- Synchronous mode of TCNT0
               (TCCR0_Tmp(i) and (TCCR0_Sel and AS0))or	 -- Asynchronous mode of TCNT0
			   (OCR0(i) and (OCR0_Sel and not AS0))or	 -- Synchronous mode of TCNT0
               (OCR0_Tmp(i) and (OCR0_Sel and AS0)) or	 -- Asynchronous mode of TCNT0
               (TCNT0(i) and TCNT0_Sel) or 				 -- Both modes of TCNT0
			   (TIFR(i) and TIFR_Sel) or
			   (TIMSK(i) and TIMSK_Sel);
end generate;	

TIFR_Bits:process(cp2,ireset)
begin
if ireset='0' then 
TIFR <= (others => '0');
elsif (cp2='1' and cp2'event) then
TOV0 <= (not TOV0 and (TCNT0_En and(
(not PWM0 and TCNT0(7) and TCNT0(6) and TCNT0(5) and TCNT0(4) and TCNT0(3) and TCNT0(2) and TCNT0(1) and TCNT0(0))or
(PWM0 and not(TCNT0(7) or TCNT0(6) or TCNT0(5) or TCNT0(4) or TCNT0(3) or TCNT0(2) or TCNT0(1)) and TCNT0(0) and TCNT0_Cnt_Dir ))))or	
(TOV0 and not(TC0OvfIRQ_Ack or(TIFR_Sel and iowe and dbus_in(0))));
OCF0 <= (not OCF0 and(not PWM0 and COM00 and TCNT0_Cmp_Out))or(OCF0 and not(TC0CmpIRQ_Ack or(TIFR_Sel and iowe and dbus_in(1))));
end if;	
end process;

TIMSK_Bits:process(cp2,ireset)
begin
if ireset='0' then 
TIMSK <= (others => '0');
elsif (cp2='1' and cp2'event) then
if (TIMSK_Sel and iowe)='1' then
TIMSK <= dbus_in;	
end if;	
end if;	
end process;

TC0OvfIRQ <= TOV0 and TOIE0;	  -- Interrupt on overflow of TCNT0
TC0CmpIRQ <= OCF0 and OCIE0;	  -- Interrupt on compare match	of TCNT0

out_en <= TCCR0_Sel or TCCR1A_Sel or TCCR1B_Sel or TCCR2_Sel or ASSR_Sel or TIMSK_Sel or 
          TIFR_Sel  or TCNT0_Sel  or TCNT2_Sel or OCR0_Sel or OCR2_Sel or TCNT1H_Sel or 
		  TCNT1L_Sel or OCR1AH_Sel or OCR1AL_Sel or OCR1BH_Sel or OCR1BL_Sel or ICR1AH_Sel or  
          ICR1AL_Sel;

end rtl;

⌨️ 快捷键说明

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