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

📄 timer_counter.vhd

📁 AVR IP core writen in VHDL. It is beta version, working even with AVR studio
💻 VHD
📖 第 1 页 / 共 3 页
字号:
      when '1' => 
	   if(TCNT2=x"00") then
	    Cnt2Dir <= '0';
	   end if; 
	  when others => null;
     end case;
    end if;
   end if;
  end if;
 end if;
end process;				


TCnt2OutputControl:process(cp2,ireset)
begin
 if (ireset='0')  then                    -- Reset
  OC2_PWM2_Int <= '0';
 elsif  (cp2='1' and cp2'event)  then     -- Clock
  if(tmr_cp2en='1') then                  -- Clock enable
   if(TCNT2_En='1') then
	   
    case PWM2 is
     when '0' =>	     --  Non PWM Mode
	  if(TCNT2=OCR2 and TCNT2CmpBl='0') then
	   if(COM21='0' and COM20='1') then -- Toggle	 
	    OC2_PWM2_Int <= not OC2_PWM2_Int;	 
	   end if; 
	  end if; 
     when '1' =>	     --  PWM Mode	   
	  case TCCR2(5 downto 4) is -- -> COM21&COM20
	   when "10" =>      -- Non-inverted PWM  
	    if(TCNT2=x"FF") then  -- Update OCR2
		 if (OCR2_Tmp=x"00") then 
		  OC2_PWM2_Int <= '0'; -- Clear
		 elsif (OCR2_Tmp=x"FF") then
		  OC2_PWM2_Int <= '1'; -- Set
		 end if; 
	    elsif(TCNT2=OCR2 and OCR2/=x"00") then
         if(Cnt2Dir='0') then  -- Up-counting 
		  OC2_PWM2_Int <= '0'; -- Clear			 
		 else 				   -- Down-counting
          OC2_PWM2_Int <= '1'; -- Set		 			
		 end if;
		end if;
	   when "11" =>      -- Inverted PWM  
	    if(TCNT2=x"FF") then  -- Update OCR2
		 if (OCR2_Tmp=x"00") then 
		  OC2_PWM2_Int <= '1'; -- Set
		 elsif (OCR2_Tmp=x"FF") then
		  OC2_PWM2_Int <= '0'; -- Clear
		 end if; 
	    elsif(TCNT2=OCR2 and OCR2/=x"00") then
         if(Cnt2Dir='0') then  -- Up-counting 
		  OC2_PWM2_Int <= '1'; -- Set 			 
		 else 				   -- Down-counting
          OC2_PWM2_Int <= '0'; -- Clear 		 			
		 end if;
	    end if;
	   when others => null;
	  end case; 
	   
     when others =>	null;     	   	  
    end case;
   
   end if;	  	
  end if;	  
 end if;
end process;				


OC2_PWM2 <= OC2_PWM2_Int;

TCnt2_TIFR_Bits:process(cp2,ireset)
begin
 if (ireset='0') then -- Reset
  TOV2 <= '0';
  OCF2 <= '0';
 elsif  (cp2='1' and cp2'event)  then -- Clock	
	 
  -- TOV2
  if(stopped_mode='1' and tmr_running='0' and cp2en='1') then -- !!!Special mode!!!
   if(adr=TIFR_Address and iowe='1') then	 
	TOV2 <= dbus_in(6); -- !!!
   end if;
  else 
   case TOV2 is
    when '0' => 
     if (tmr_cp2en='1' and TCNT2_En='1') then
	  if (PWM2='0') then   -- Non PWM Mode
	   if (TCNT2=x"FF") then
	    TOV2 <= '1';  	 
	   end if;
	  else                 -- PWM Mode 
	   if(TCNT2=x"00") then  	 
	    TOV2 <= '1';  	 
	   end if;
	  end if; 
     end if;
    when '1' => 
     if((TC2OvfIRQ_Ack='1' or (adr=TIFR_Address and iowe='1' and dbus_in(6)='1')) and cp2en='1') then -- Clear TOV2 flag
      TOV2 <= '0';
     end if; 
    when others => null;
   end case; 
  end if;
  
  -- OCF2
  if(stopped_mode='1' and tmr_running='0' and cp2en='1') then -- !!!Special mode!!!
   if(adr=TIFR_Address and iowe='1') then	 
	OCF2 <= dbus_in(7); -- !!!
   end if;
  else 
   case OCF2 is
    when '0' => 
	 if (tmr_cp2en='1' and TCNT2_En='1') then 
	  if (TCNT2=OCR2 and TCNT2CmpBl='0') then
	   OCF2 <= '1';  
	  end if;
	 end if; 
    when '1' => 
     if((TC2CmpIRQ_Ack='1' or (adr=TIFR_Address and iowe='1' and dbus_in(7)='1')) and cp2en='1') then -- Clear OCF2 flag
      OCF2 <= '0';
     end if; 
    when others => null;
   end case; 
  end if;
  
 end if;	
end process;


TCCR2(7) <= '0';

TCCR2_Reg:process(cp2,ireset)
begin
 if (ireset='0')  then                          -- Reset
  TCCR2(6 downto 0) <= (others => '0'); 
 elsif (cp2='1' and cp2'event)  then            -- Clock
  if (cp2en='1') then                           -- Clock Enable	
   if (adr=TCCR2_Address and iowe='1') then              
	TCCR2(6 downto 0) <= dbus_in(6 downto 0);
   end if;
  end if;
 end if;
end process;	

OCR2_Write:process(cp2,ireset)
begin
 if (ireset='0')  then                      -- Reset
  OCR2 <= (others => '0');
 elsif (cp2='1' and cp2'event)  then        -- Clock
  case PWM2 is 
   when '0' =>                              -- Non-PWM mode
    if (adr=OCR2_Address and iowe='1' and cp2en='1') then  -- Load data from the data bus
	 OCR2 <= dbus_in;
    end if;
   when '1' => 								-- PWM mode
    if(TCNT2=x"FF" and tmr_cp2en='1' and TCNT2_En='1') then  -- Load data from the temporary register
	 OCR2 <= OCR2_Tmp;  
    end if;
   when others => null;
  end case;
 end if;
end process;			


OCR2_Tmp_Write:process(cp2,ireset)
begin
 if (ireset='0')  then                      -- Reset
  OCR2_Tmp <= (others => '0');
 elsif (cp2='1' and cp2'event)  then        -- Clock
  if (cp2en='1') then 	 
   if (adr=OCR2_Address and iowe='1') then  -- Load data from the data bus
    OCR2_Tmp <= dbus_in;
   end if;
  end if;
 end if;
end process;			

-- 

TCNT2WriteControl:process(cp2,ireset)
begin
 if (ireset='0')  then                      -- Reset
  TCNT2WrFl <= '0';
 elsif (cp2='1' and cp2'event)  then        -- Clock
  if (cp2en='1') then 
    case TCNT2WrFl is
 	 when '0' =>
	  if (adr=TCNT2_Address and iowe='1' and TCNT2_En='0') then  -- Load data from the data bus 
	   TCNT2WrFl <= '1';
	  end if;
	 when '1' =>
	  if(TCNT2_En='0') then 
	   TCNT2WrFl <= '0';
	  end if; 	  
	 when others => null;
	end case; 	
  end if;
 end if;
end process;			

-- Operations on compare match(OCF2 and Toggling) disabled for TCNT2
TCNT2CmpBl <= '1' when (TCNT2WrFl='1' or (adr=TCNT2_Address and iowe='1')) else 
	          '0'; 

	
-- -------------------------------------------------------------------------------------------
-- Common (Control/Interrupt) bits
-- ------------------------------------------------------------------------------------------- 

TIMSK_Bits:process(cp2,ireset)
begin
 if (ireset='0') then 
  TIMSK <= (others => '0');
 elsif  (cp2='1' and cp2'event)  then
  if (cp2en='1') then       -- Clock Enable	
   if (adr=TIMSK_Address and iowe='1') then
    TIMSK <= dbus_in;	
   end if;
  end if;	 
 end if;	
end process;


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

-- Interrupt flags of Timer/Counter0
TC2OvfIRQ <= TOV2 and TOIE2;	  -- Interrupt on overflow of TCNT2
TC2CmpIRQ <= OCF2 and OCIE2;	  -- Interrupt on compare match	of TCNT2

-- Unused interrupt requests(for T/C1)
TC1OvfIRQ  <= TOV1 and TOIE1;
TC1CmpAIRQ <= OCF1A and OCIE1A;
TC1CmpBIRQ <= OCF1B and OCIE1B;
TC1ICIRQ   <= ICF1 and TICIE1;

-- Unused TIFR flags(for T/C1)
TOV1  <= '0';
OCF1A <= '0';	
OCF1B <= '0';
ICF1  <= '0';

-- -------------------------------------------------------------------------------------------
-- End of common (Control/Interrupt) bits
-- -------------------------------------------------------------------------------------------

-- -------------------------------------------------------------------------------------------
-- Bus interface
-- -------------------------------------------------------------------------------------------

out_en <= '1' when ((adr=TCCR0_Address or 
                     adr=TCCR1A_Address or 
                     adr=TCCR1B_Address or
                     adr=TCCR2_Address or
                     adr=ASSR_Address or
                     adr=TIMSK_Address or						 
                     adr=TIFR_Address or
                     adr=TCNT0_Address or
                     adr=TCNT2_Address or
                     adr=OCR0_Address or
                     adr=OCR2_Address or
                     adr=TCNT1H_Address	or
                     adr=TCNT1L_Address	or
                     adr=OCR1AH_Address	or
                     adr=OCR1AL_Address	or
                     adr=OCR1BH_Address	or
                     adr=OCR1BL_Address	or 
                     adr=ICR1AH_Address	or
                     adr=ICR1AL_Address) and iore='1') else '0';  

-- Output multilexer
						 
--Output_Mux:process(adr,TCCR0,OCR0,OCR0_Tmp,TCNT0,TCCR2,OCR2,OCR2_Tmp,TCNT2,TIFR,TIMSK) -- Combinatorial
--begin		  
-- case adr is 
--  when TCCR0_Address => dbus_out <= TCCR0;
--  when OCR0_Address => 
--   if (PWM0='0') then
--	dbus_out <= OCR0;
--   else
--	dbus_out <= OCR0_Tmp;
--   end if;	
--  when TCNT0_Address => dbus_out <= TCNT0;
--  when TCCR2_Address => dbus_out <= TCCR2;
--  when OCR2_Address =>    
--   if (PWM2='0') then
--	dbus_out <= OCR2;
--   else
--	dbus_out <= OCR2_Tmp;
--   end if;	
--  when TCNT2_Address => dbus_out <= TCNT2;
--  when TIFR_Address => dbus_out <= TIFR;
--  when TIMSK_Address => dbus_out <= TIMSK;
--  when others => dbus_out <= (others => '0'); 
-- end case; 
--end process;		  


-- Synopsys version
dbus_out <= TCCR0 when (adr=TCCR0_Address) else 
			OCR0 when (adr=OCR0_Address and PWM0='0') else -- Non PWM mode of T/C0
            OCR0_Tmp when (adr=OCR0_Address and PWM0='1') else -- PWM mode of T/C0
			TCNT0 when (adr=TCNT0_Address) else 
            TCCR2 when (adr=TCCR2_Address) else 
			OCR2 when (adr=OCR2_Address and PWM2='0') else -- Non PWM mode of T/C2
            OCR2_Tmp when (adr=OCR2_Address and PWM2='1') else -- PWM mode of T/C2
			TCNT2 when (adr=TCNT2_Address) else 
			TIFR when (adr=TIFR_Address) else 	
			TIMSK when (adr=TIMSK_Address) else	
			(others => '0');	
			
-- -------------------------------------------------------------------------------------------
-- End of bus interface
-- -------------------------------------------------------------------------------------------

end RTL;

⌨️ 快捷键说明

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