📄 timer_counter.vhd
字号:
(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, synchronous 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;
-- -------------------------------------------------------------------------------------------
-- Timer/Counter0
-- -------------------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Timer/Counter 2
-- -------------------------------------------------------------------------------------------
Counter_2:process(cp2,ireset)
begin
if ireset='0' then -- Reset
TCNT2 <= (others => '0');
elsif cp2='1' and cp2'event then -- Clock
if (TCNT2_En or TCNT2_Clr or TCNT2_Ld_Imm)='1' then -- Clock enable
TCNT2 <= TCNT2_In;
end if;
end if;
end process;
Counter_2_Inc:process(cp2,ireset)
begin
if ireset='0' then -- Reset
TCNT2_Inc <= '0';
elsif cp2='1' and cp2'event then -- Clock
TCNT2_Inc <= (not TCNT2_Inc and(TCNT2_En and not (TCNT2_Sel and iowe)))or
(TCNT2_Inc and not (TCNT2_Sel and iowe));
end if;
end process;
-- Input muultiplexer of TCCR2 register
TCNT2_In <= dbus_in when (TCNT2_Sel and iowe) = '1' else -- Immediate value (from dbus_in)
(others => '0') when TCNT2_Clr ='1' else -- Synchronous clear (for OCR)
TCNT2-1 when TCNT2_Cnt_Dir='1' else -- Decrement (for PWM)
TCNT2+1; -- Icrement (for counter and PWM)
TCNT2_Clr <= TCNT2_Cmp_Out and CTC2 and not PWM2;
TCNT2_Cmp_Out <= '1' when TCNT2=OCR2 and OCR2/=x"00" and TCNT2_Inc='1' else '0';
TCCR2_Control:process(cp2,ireset)
begin
if ireset='0' then -- Reset
TCNT2_Cnt_Dir <= '0';
elsif cp2='1' and cp2'event then -- Clock
TCNT2_Cnt_Dir <= (not TCNT2_Cnt_Dir and(TCNT2(7) and TCNT2(6) and TCNT2(5) and TCNT2(4) and TCNT2(3) and TCNT2(2) and TCNT2(1) and not TCNT2(0) and TCNT2_En and PWM0)) or -- 0xFE
(TCNT2_Cnt_Dir and not ((not TCNT2(7) and not TCNT2(6) and not TCNT2(5) and not TCNT2(4) and not TCNT2(3) and not TCNT2(2) and not TCNT2(1) and TCNT2(0)and TCNT2_En) or not PWM0)); -- 0x01
end if;
end process;
TCNT2_Temp_Compare:process(cp2,ireset)
begin
if ireset='0' then -- Reset
OCR2_Tmp <= (others => '0');
elsif cp2='1' and cp2'event then -- Clock
if (OCR2_Sel and iowe )='1' then -- Clock enable
OCR2_Tmp <= dbus_in;
end if;
end if;
end process;
-- Main registers of TCNT2
TCNT2_Control:process(cp2,ireset)
begin
if ireset='0' then -- Reset
TCCR2 <= (others => '0');
elsif cp2='1' and cp2'event then -- Clock
if (TCCR2_Sel and iowe)='1' then -- Clock enable
TCCR2(6 downto 0) <= dbus_in(6 downto 0);
end if;
end if;
end process;
TCNT2_Compare:process(cp2,ireset)
begin
if ireset='0' then -- Reset
OCR2 <= (others => '0');
elsif cp2='1' and cp2'event then -- Clock
if ((OCR2_Sel and iowe)or -- Non PWM mode
(TCNT2(7) and TCNT2(6) and TCNT2(5) and TCNT2(4) and TCNT2(3) and TCNT2(2) and TCNT2(1) and TCNT2(0) and PWM2 and TCNT2_En)) -- Reload OCR2 with new value when TCNT2=0xFF (for PWM)
='1' then -- Clock enable ??!!
OCR2 <= OCR2_In;
end if;
end if;
end process;
-- OCR2 can be loaded from OCR2_Tmp (PWM mode ) or from dbus_in (non PWM mode only)
OCR2_In <= OCR2_Tmp when ((TCNT2(7) and TCNT2(6) and TCNT2(5) and TCNT2(4) and TCNT2(3) and TCNT2(2) and TCNT2(1) and TCNT2(0) and PWM2 and TCNT2_En))='1' else dbus_in;
--OC2_PWM2 output
-- Attention!!! In the real ATmega103 chip this output of the TCNT2 combined with PB7
Output_TCNT2:process(cp2,ireset)
begin
if ireset='0' then -- Reset
OC2_PWM2_Int <= '0';
elsif cp2='1' and cp2'event then -- Clock
case OC2_PWM2_Int is
-- Set
when '0' =>
if (not PWM2 and COM20 and TCNT2_Cmp_Out)='1' or -- Compare mode - Toggle/Set ??!!
((PWM2 and COM21 and TCNT2_En)='1' and -- PWM modes :
((TCNT2=x"FF" and COM20='1' and OCR2_Tmp=x"00")or -- Inverted PWM
(TCNT2=x"FF" and COM20='0' and OCR2_Tmp=x"FF")or -- Non-inverted PWM
(TCNT2=x"FF" and COM20='1' and OCR2_Tmp/=x"FF")or -- Inverted PWM
(TCNT2/=x"FF" and TCNT2_Cnt_Dir='1' and COM20='0' and OCR2_Tmp/=x"00" and OCR2=TCNT2)or -- Non-inverted PWM
(TCNT2/=x"FF" and TCNT2_Cnt_Dir='0' and COM20='1' and OCR2_Tmp/=x"00" and OCR2=TCNT2))) -- Inverted PWM
then
OC2_PWM2_Int <= '1';
end if;
-- Reset
when '1' =>
if (not PWM2 and (COM21 or COM20) and TCNT2_Cmp_Out)='1' or -- Compare mode - Toggle/Reset ??!!
((PWM2 and COM21 and TCNT2_En)='1' and -- PWM modes :
((TCNT2=x"FF" and COM20='1' and OCR2_Tmp=x"FF")or -- Inverted PWM
(TCNT2=x"FF" and COM20='0' and OCR2_Tmp=x"00")or -- Non-inverted PWM
(TCNT2=x"FF" and COM20='0' and OCR2_Tmp/=x"FF")or -- Non-inverted PWM
(TCNT2/=x"FF" and TCNT2_Cnt_Dir='0' and COM20='0' and OCR2_Tmp/=x"00" and OCR2=TCNT0)or -- Non-inverted PWM
(TCNT2/=x"FF" and TCNT2_Cnt_Dir='1' and COM20='1' and OCR2_Tmp/=x"00" and OCR2=TCNT0))) -- Inverted PWM
then
OC2_PWM2_Int <= '0';
end if;
when others => null;
end case;
end if;
end process;
OC2_PWM2 <= OC2_PWM2_Int;
-- -------------------------------------------------------------------------------------------
-- End of Timer/Counter2
-- -------------------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Common (Control/Interrupt) bits
-- -------------------------------------------------------------------------------------------
TIFR_Bits:process(cp2,ireset)
begin
if ireset='0' then
TIFR <= (others => '0');
elsif cp2='1' and cp2'event then
-- Timer/Counter0
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))));
-- Timer/Counter2
TOV2 <= (not TOV2 and (TCNT2_En and(
(not PWM2 and TCNT2(7) and TCNT2(6) and TCNT2(5) and TCNT2(4) and TCNT2(3) and TCNT2(2) and TCNT2(1) and TCNT2(0))or
(PWM2 and not(TCNT2(7) or TCNT2(6) or TCNT2(5) or TCNT2(4) or TCNT2(3) or TCNT2(2) or TCNT2(1)) and TCNT2(0) and TCNT2_Cnt_Dir ))))or
(TOV2 and not(TC2OvfIRQ_Ack or(TIFR_Sel and iowe and dbus_in(6))));
OCF2 <= (not OCF2 and(not PWM2 and COM20 and TCNT2_Cmp_Out))or(OCF2 and not(TC2CmpIRQ_Ack or(TIFR_Sel and iowe and dbus_in(7))));
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;
-- 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
-- -------------------------------------------------------------------------------------------
-- End of common (Control/Interrupt) bits
-- -------------------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Bus interface
-- -------------------------------------------------------------------------------------------
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;
Common_Out_Mux: for i in dbus_out'range generate
dbus_out(i) <= (TCCR0(i) and (TCCR0_Sel and not AS0))or -- TCCR0 (Synchronous mode of TCNT0)
(TCCR0_Tmp(i) and (TCCR0_Sel and AS0))or -- TCCR0 (Asynchronous mode of TCNT0)
(OCR0(i) and (OCR0_Sel and not AS0))or -- OCR0 (Synchronous mode of TCNT0)
(OCR0_Tmp(i) and (OCR0_Sel and AS0)) or -- OCR0 (Asynchronous mode of TCNT0)
(TCNT0(i) and TCNT0_Sel) or -- TCNT0 (Both modes of TCNT0)
(TCCR2(i) and TCCR2_Sel )or -- TCCR2
(OCR2(i) and OCR2_Sel)or -- OCR2
(TCNT2(i) and TCNT2_Sel) or -- TCNT2
(TIFR(i) and TIFR_Sel) or -- TIFR
(TIMSK(i) and TIMSK_Sel); -- TIMSK
end generate;
-- -------------------------------------------------------------------------------------------
-- End of bus interface
-- -------------------------------------------------------------------------------------------
end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -