📄 timer_counter.vhd
字号:
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 PB4Output_TCNT0:process(cp2,ireset)beginif ireset='0' then -- Reset OC0_PWM0_Int <= '0'; elsif cp2='1' and cp2'event then -- Clock case OC0_PWM0_Int is-- Setwhen '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;-- Resetwhen '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)beginif 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; TCNT2_Ld_Imm <= TCNT2_Sel and iowe; -- Write to TCNT2Counter_2_Inc:process(cp2,ireset)beginif 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 registerTCNT2_In <= dbus_in when TCNT2_Ld_Imm = '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)beginif 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 PWM2)) 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 PWM2)); -- 0x01 end if;end process; TCNT2_Temp_Compare:process(cp2,ireset)beginif 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 TCNT2TCNT2_Control:process(cp2,ireset)beginif 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)beginif 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 PB7Output_TCNT2:process(cp2,ireset)beginif ireset='0' then -- Reset OC2_PWM2_Int <= '0'; elsif cp2='1' and cp2'event then -- Clock case OC2_PWM2_Int is-- Setwhen '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;-- Resetwhen '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)beginif ireset='0' then TIFR <= (others => '0');elsif cp2='1' and cp2'event then-- Timer/Counter0TOV0 <= (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))));OCF0 <= (not OCF0 and TCNT0_En and TCNT0_Cmp_Out)or (OCF0 and not(TC0CmpIRQ_Ack or(TIFR_Sel and iowe and dbus_in(1))));-- Timer/Counter2TOV2 <= (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))));OCF2 <= (not OCF2 and TCNT2_En 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)beginif ireset='0' then TIMSK <= (others => '0');elsif cp2='1' and cp2'event thenif (TIMSK_Sel and iowe)='1' thenTIMSK <= dbus_in; end if; end if; end process;-- Interrupt flags of Timer/Counter0TC0OvfIRQ <= TOV0 and TOIE0; -- Interrupt on overflow of TCNT0TC0CmpIRQ <= OCF0 and OCIE0; -- Interrupt on compare match of TCNT0-- Interrupt flags of Timer/Counter0TC2OvfIRQ <= TOV2 and TOIE2; -- Interrupt on overflow of TCNT2TC2CmpIRQ <= 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) and iore;Common_Out_Mux: for i in dbus_out'range generatedbus_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); -- TIMSKend generate; -- --------------------------------------------------------------------------------------------- End of bus interface-- -------------------------------------------------------------------------------------------end rtl;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -