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

📄 timer_counter.vhd

📁 AVR IP core writen in VHDL. It is beta version, working even with AVR studio
💻 VHD
📖 第 1 页 / 共 3 页
字号:

TimerCounter0Cnt:process(cp2,ireset)
begin
 if (ireset='0') then                    -- Reset
  TCNT0 <= (others => '0'); 
 elsif  (cp2='1' and cp2'event)  then    -- Clock
  if(adr=TCNT0_Address and iowe='1' and cp2en='1') then  -- Write to TCNT0
   TCNT0 <= dbus_in;	  
  elsif(tmr_cp2en='1') then
   case PWM0 is 
	when '0' =>           -- Non-PWM mode  
	 if(CTC0='1' and TCNT0=OCR0) then  -- Clear T/C on compare match
	  TCNT0 <= (others => '0');
	 elsif(TCNT0_En='1') then
	  TCNT0 <= TCNT0 + 1; -- Increment TCNT0	  
	 end if;
	when '1' =>           -- PWM mode  
	 if(TCNT0_En='1') then
	   case Cnt0Dir is
		when '0' =>        -- Counts up
		 if(TCNT0=x"FF") then
		  TCNT0<=x"FE";
		 else 
	      TCNT0 <= TCNT0 + 1; -- Increment TCNT0 (0 to FF)
		 end if;
		when '1' =>        -- Counts down
		 if(TCNT0=x"00") then
		  TCNT0 <= x"01";
		 else 
	      TCNT0 <= TCNT0 - 1; -- Decrement TCNT0 (FF to 0)	  
		 end if;
        when others => null;
       end case;	
     end if;
	when others => null;
   end case;
   
  end if;	  
 end if;
end process;				


Cnt0DirectionControl:process(cp2,ireset)
begin
 if (ireset='0')  then                   -- Reset
  Cnt0Dir <= '0';
 elsif (cp2='1' and cp2'event)  then     -- Clock
  if(tmr_cp2en='1') then  				 -- Clock enable
   if(TCNT0_En='1') then
    if (PWM0='1') then   
     case Cnt0Dir is
	  when '0' => 
	   if(TCNT0=x"FF") then
	    Cnt0Dir <= '1';
	   end if; 
      when '1' => 
	   if(TCNT0=x"00") then
	    Cnt0Dir <= '0';
	   end if; 
	  when others => null;
     end case;
    end if;
   end if;
  end if;
 end if;
end process;				


TCnt0OutputControl:process(cp2,ireset)
begin
 if (ireset='0')  then                    -- Reset
  OC0_PWM0_Int <= '0';
 elsif  (cp2='1' and cp2'event)  then     -- Clock
  if(tmr_cp2en='1') then                  -- Clock enable
   if(TCNT0_En='1') then
	   
    case PWM0 is
     when '0' =>	     --  Non PWM Mode
	  if(TCNT0=OCR0 and TCNT0CmpBl='0') then
	   if(COM01='0' and COM00='1') then -- Toggle	 
	    OC0_PWM0_Int <= not OC0_PWM0_Int;	 
	   end if; 
	  end if; 
     when '1' =>	     --  PWM Mode	   
	  case TCCR0(5 downto 4) is -- -> COM01&COM00
	   when "10" =>      -- Non-inverted PWM  
	    if(TCNT0=x"FF") then  -- Update OCR0
		 if (OCR0_Tmp=x"00") then 
		  OC0_PWM0_Int <= '0'; -- Clear
		 elsif (OCR0_Tmp=x"FF") then
		  OC0_PWM0_Int <= '1'; -- Set
		 end if; 
	    elsif(TCNT0=OCR0 and OCR0/=x"00") then
         if(Cnt0Dir='0') then  -- Up-counting 
		  OC0_PWM0_Int <= '0'; -- Clear			 
		 else 				   -- Down-counting
          OC0_PWM0_Int <= '1'; -- Set		 			
		 end if;
		end if;
	   when "11" =>      -- Inverted PWM  
	    if(TCNT0=x"FF") then  -- Update OCR0
		 if (OCR0_Tmp=x"00") then 
		  OC0_PWM0_Int <= '1'; -- Set
		 elsif (OCR0_Tmp=x"FF") then
		  OC0_PWM0_Int <= '0'; -- Clear
		 end if; 
	    elsif(TCNT0=OCR0 and OCR0/=x"00") then
         if(Cnt0Dir='0') then  -- Up-counting 
		  OC0_PWM0_Int <= '1'; -- Set 			 
		 else 				   -- Down-counting
          OC0_PWM0_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;				


OC0_PWM0 <= OC0_PWM0_Int;

TCnt0_TIFR_Bits:process(cp2,ireset)
begin
 if (ireset='0') then -- Reset
  TOV0 <= '0';
  OCF0 <= '0';
 elsif  (cp2='1' and cp2'event)  then -- Clock	
	 
  -- TOV0
  if(stopped_mode='1' and tmr_running='0' and cp2en='1') then -- !!!Special mode!!!
   if(adr=TIFR_Address and iowe='1') then	 
	TOV0 <= dbus_in(0); -- !!!
   end if;
  else 
   case TOV0 is
    when '0' => 
     if (tmr_cp2en='1' and TCNT0_En='1') then
	  if (PWM0='0') then   -- Non PWM Mode
	   if (TCNT0=x"FF") then
	    TOV0 <= '1';  	 
	   end if;
	  else                 -- PWM Mode 
	   if(TCNT0=x"00") then  	 
	    TOV0 <= '1';  	 
	   end if;
	  end if; 
     end if;
    when '1' => 
     if((TC0OvfIRQ_Ack='1' or (adr=TIFR_Address and iowe='1' and dbus_in(0)='1')) and cp2en='1') then -- Clear TOV0 flag
      TOV0 <= '0';
     end if; 
    when others => null;
   end case; 
  end if;
  
  -- OCF0
  if(stopped_mode='1' and tmr_running='0' and cp2en='1') then -- !!!Special mode!!!
   if(adr=TIFR_Address and iowe='1') then	 
	OCF0 <= dbus_in(1); -- !!!
   end if;
  else 
   case OCF0 is
    when '0' => 
	 if (tmr_cp2en='1' and TCNT0_En='1') then 
	  if (TCNT0=OCR0 and TCNT0CmpBl='0') then
	   OCF0 <= '1';  
	  end if;
	 end if; 
    when '1' => 
     if((TC0CmpIRQ_Ack='1' or (adr=TIFR_Address and iowe='1' and dbus_in(1)='1')) and cp2en='1') then -- Clear OCF2 flag
      OCF0 <= '0';
     end if; 
    when others => null;
   end case; 
  end if;
  
 end if;	
end process;


TCCR0(7) <= '0';

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

OCR0_Write:process(cp2,ireset)
begin
 if (ireset='0')  then                      -- Reset
  OCR0 <= (others => '0');
 elsif (cp2='1' and cp2'event)  then        -- Clock
  case PWM0 is 
   when '0' =>                              -- Non-PWM mode
    if (adr=OCR0_Address and iowe='1' and cp2en='1') then  -- Load data from the data bus
	 OCR0 <= dbus_in;
    end if;
   when '1' => 								-- PWM mode
    if(TCNT0=x"FF" and tmr_cp2en='1' and TCNT0_En='1') then  -- Load data from the temporary register
	 OCR0 <= OCR0_Tmp;  
    end if;
   when others => null;
  end case;
 end if;
end process;			


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

-- 

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

-- Operations on compare match(OCF0 and Toggling) disabled for TCNT0
TCNT0CmpBl <= '1' when (TCNT0WrFl='1' or (adr=TCNT0_Address and iowe='1')) else 
	          '0'; 


-- -------------------------------------------------------------------------------------------
-- Timer/Counter 2
-- -------------------------------------------------------------------------------------------

TimerCounter2Cnt:process(cp2,ireset)
begin
 if (ireset='0') then                    -- Reset
  TCNT2 <= (others => '0'); 
 elsif  (cp2='1' and cp2'event)  then    -- Clock
  if(adr=TCNT2_Address and iowe='1' and cp2en='1') then  -- Write to TCNT2
   TCNT2 <= dbus_in;	  
  elsif(tmr_cp2en='1') then
   case PWM2 is 
	when '0' =>           -- Non-PWM mode  
	 if(CTC2='1' and TCNT2=OCR2) then  -- Clear T/C on compare match
	  TCNT2 <= (others => '0');
	 elsif(TCNT2_En='1') then
	  TCNT2 <= TCNT2 + 1; -- Increment TCNT2
	 end if;
	when '1' =>           -- PWM mode  
	 if(TCNT2_En='1') then
	   case Cnt2Dir is
		when '0' =>        -- Counts up
		 if(TCNT2=x"FF") then
		  TCNT2 <= x"FE";
		 else 
	      TCNT2 <= TCNT2 + 1; -- Increment TCNT2 (0 to FF)
		 end if;
		when '1' =>        -- Counts down
		 if(TCNT2=x"00") then
		  TCNT2 <= x"01";
		 else 
	      TCNT2 <= TCNT2 - 1; -- Decrement TCNT0 (FF to 0)	  
		 end if;
        when others => null;
       end case;	
     end if;
	when others => null;
   end case;
   
  end if;	  
 end if;
end process;				


Cnt2DirectionControl:process(cp2,ireset)
begin
 if (ireset='0')  then                   -- Reset
  Cnt2Dir <= '0';
 elsif (cp2='1' and cp2'event)  then     -- Clock
  if(tmr_cp2en='1') then  				 -- Clock enable
   if(TCNT2_En='1') then
    if (PWM2='1') then   
     case Cnt2Dir is
	  when '0' => 
	   if(TCNT2=x"FF") then
	    Cnt2Dir <= '1';
	   end if; 

⌨️ 快捷键说明

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