📄 timer_counter.vhd
字号:
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 + -