📄 timer_counter.vhd
字号:
-- --------------------------------------------------------------------------------------------- Prescalers-- ------------------------------------------------------------------------------------------- -- Prescaler 1 for TCNT1 and TCNT2Prescaler_1:process(cp2,ireset)beginif ireset='0' then -- Reset Pre1Cnt <= (others => '0'); CK8 <= '0'; CK64 <= '0'; CK256 <= '0'; CK1024 <= '0'; EXT1RE <= '0'; EXT1FE <= '0'; EXT2RE <= '0'; EXT2FE <= '0'; EXT1Latched <= '0'; EXT2Latched <= '0'; elsif cp2='1' and cp2'event then -- Clock Pre1Cnt <= Pre1Cnt+1; CK8 <= not CK8 and(Pre1Cnt(0) and Pre1Cnt(1)and Pre1Cnt(2)); CK64 <= not CK64 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5)); CK256 <= not CK256 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5) and Pre1Cnt(6) and Pre1Cnt(7)); CK1024 <= not CK1024 and(Pre1Cnt(0) and Pre1Cnt(1) and Pre1Cnt(2) and Pre1Cnt(3) and Pre1Cnt(4) and Pre1Cnt(5) and Pre1Cnt(6) and Pre1Cnt(7) and Pre1Cnt(8) and Pre1Cnt(9)); EXT1RE <= not EXT1RE and (EXT1SB and not EXT1Latched); EXT1FE <= not EXT1FE and (not EXT1SB and EXT1Latched); EXT2RE <= not EXT2RE and (EXT2SB and not EXT2Latched); EXT2FE <= not EXT2FE and (not EXT2SB and EXT2Latched); EXT1Latched <= EXT1SB; EXT2Latched <= EXT2SB; end if;end process; TCNT1_En <= (not CS12 and not CS11 and CS10) or -- CK "001" (CK8 and not CS12 and CS11 and not CS10) or -- CK/8 "010" (CK64 and not CS12 and CS11 and CS10) or -- CK/64 "011" (CK256 and CS12 and not CS11 and not CS10) or -- CK/256 "100" (CK1024 and CS12 and not CS11 and CS10) or -- CK/1024 "101" (EXT1FE and CS12 and CS11 and not CS10) or -- Falling edge "110" (EXT1RE and CS12 and CS11 and CS10); -- Rising edge "111" TCNT2_En <= (not CS22 and not CS21 and CS20) or -- CK "001" (CK8 and not CS22 and CS21 and not CS20) or -- CK/8 "010" (CK64 and not CS22 and CS21 and CS20) or -- CK/64 "011" (CK256 and CS22 and not CS21 and not CS20) or -- CK/256 "100" (CK1024 and CS22 and not CS21 and CS20) or -- CK/1024 "101" (EXT2FE and CS22 and CS21 and not CS20) or -- Falling edge "110" (EXT2RE and CS22 and CS21 and CS20); -- Rising edge "111"-- Prescaler 0 for TCNT0Tosc1_Rising_Edge_Detector:process(cp2,ireset)begin if ireset='0' then --Reset Tosc1RE <= '0'; Tosc1Latched <= '0'; elsif cp2='1' and cp2'event then -- Clock Tosc1RE <= not Tosc1RE and (not Tosc1Latched and Tosc1SB); Tosc1Latched <= Tosc1SB; end if; end process; PCK0 <= Tosc1RE when AS0='1' else '1'; Prescaler_0_Cnt:process(cp2,ireset)beginif ireset='0' then -- Reset Pre0Cnt <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if PCK0='1' then -- Clock enable Pre0Cnt <= Pre0Cnt+1; end if; end if;end process; Prescaler_0:process(cp2,ireset)beginif ireset='0' then -- Reset PCK08 <= '0'; PCK032 <= '0'; PCK064 <= '0'; PCK0128 <= '0'; PCK0256 <= '0'; PCK01024 <= '0'; PCK0_Del <= '0'; elsif cp2='1' and cp2'event then -- Clock PCK08 <= (not PCK08 and(Pre0Cnt(0) and Pre0Cnt(1)and Pre0Cnt(2)) and PCK0_Del); PCK032 <= (not PCK032 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4)) and PCK0_Del); PCK064 <= (not PCK064 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5)) and PCK0_Del); PCK0128 <= (not PCK0128 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and PCK0_Del)); PCK0256 <= (not PCK0256 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and Pre0Cnt(7)) and PCK0_Del); PCK01024 <= (not PCK01024 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6) and Pre0Cnt(7) and Pre0Cnt(8) and Pre0Cnt(9)) and PCK0_Del); PCK0_Del <= PCK0; end if;end process; TCNT0_En <= (PCK0 and not CS02 and not CS01 and CS00) or -- PCK "001" !!?? (PCK08 and not CS02 and CS01 and not CS00) or -- PCK/8 "010" (PCK032 and not CS02 and CS01 and CS00)or -- PCK/32 "011" (PCK064 and CS02 and not CS01 and not CS00)or -- PCK/64 "100" (PCK0128 and CS02 and not CS01 and CS00)or -- PCK/64 "101" (PCK0256 and CS02 and CS01 and not CS00)or -- PCK/256 "110" (PCK01024 and CS02 and CS01 and CS00); -- PCK/1024 "111"-- --------------------------------------------------------------------------------------------- End of prescalers-- ------------------------------------------------------------------------------------------- -- I/O address decoderTCCR0_Sel <= '1' when adr=TCCR0_Address else '0';TCCR1A_Sel <= '1' when adr=TCCR1A_Address else '0';TCCR1B_Sel <= '1' when adr=TCCR1B_Address else '0';TCCR2_Sel <= '1' when adr=TCCR2_Address else '0';ASSR_Sel <= '1' when adr=ASSR_Address else '0';TIMSK_Sel <= '1' when adr=TIMSK_Address else '0';TIFR_Sel <= '1' when adr=TIFR_Address else '0';TCNT0_Sel <= '1' when adr=TCNT0_Address else '0';TCNT2_Sel <= '1' when adr=TCNT2_Address else '0';OCR0_Sel <= '1' when adr=OCR0_Address else '0';OCR2_Sel <= '1' when adr=OCR2_Address else '0';TCNT1H_Sel <= '1' when adr=TCNT1H_Address else '0';TCNT1L_Sel <= '1' when adr=TCNT1L_Address else '0';OCR1AH_Sel <= '1' when adr=OCR1AH_Address else '0';OCR1AL_Sel <= '1' when adr=OCR1AL_Address else '0';OCR1BH_Sel <= '1' when adr=OCR1BH_Address else '0';OCR1BL_Sel <= '1' when adr=OCR1BL_Address else '0';ICR1AH_Sel <= '1' when adr=ICR1AH_Address else '0';ICR1AL_Sel <= '1' when adr=ICR1AL_Address else '0'; -- --------------------------------------------------------------------------------------------- Timer/Counter0-- --------------------------------------------------------------------------------------------- Attention !!! This model only emulates the asynchronous mode of TCNT0. -- Real TCNT0 of ATmega103/603 operates with two separate clock sources.Counter_0:process(cp2,ireset)beginif ireset='0' then -- Reset TCNT0 <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if (TCNT0_En or TCNT0_Clr or TCNT0_Ld_Imm)='1' then -- Clock enable TCNT0 <= TCNT0_In; end if; end if;end process; Counter_0_Inc:process(cp2,ireset)beginif ireset='0' then -- Reset TCNT0_Inc <= '0'; elsif cp2='1' and cp2'event then -- Clock TCNT0_Inc <= (not TCNT0_Inc and(TCNT0_En and not TCNT0_Ld_Imm))or(TCNT0_Inc and not(TCNT0_Ld_Imm)); end if;end process; TCNT0_In <= TCNT0_Imm_In when TCNT0_Ld_Imm = '1' else -- Immediate value (from dbus_in or TCNT0_Tmp) (others => '0') when TCNT0_Clr ='1' else -- Synchronous clear (for OCR) TCNT0-1 when TCNT0_Cnt_Dir='1' else -- Decrement (for PWM) TCNT0+1; -- Icrement (for counter and PWM) TCNT0_Imm_In <= TCNT0_Tmp when (TCN0UB and not TCN0UB_Tmp and PCK0 and AS0)='1' else dbus_in;TCNT0_Clr <= TCNT0_Cmp_Out and CTC0 and not PWM0;TCNT0_Cmp_Out <= '1' when (TCNT0=OCR0 and OCR0/=x"00" and TCNT0_Inc='1') else '0';TCNT0_Ld_Imm <= (TCNT0_Sel and iowe and not AS0) or (TCN0UB and not TCN0UB_Tmp and PCK0 and AS0); TCCR0_Control:process(cp2,ireset)beginif ireset='0' then -- Reset TCNT0_Cnt_Dir <= '0'; TCR0UB_Tmp <= '0'; OCR0UB_Tmp <= '0'; TCN0UB_Tmp <= '0'; ASSR <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock TCNT0_Cnt_Dir <= (not TCNT0_Cnt_Dir and(TCNT0(7) and TCNT0(6) and TCNT0(5) and TCNT0(4) and TCNT0(3) and TCNT0(2) and TCNT0(1) and not TCNT0(0) and TCNT0_En and PWM0)) or -- 0xFE (TCNT0_Cnt_Dir and not ((not TCNT0(7) and not TCNT0(6) and not TCNT0(5) and not TCNT0(4) and not TCNT0(3) and not TCNT0(2) and not TCNT0(1) and TCNT0(0)and TCNT0_En) or not PWM0)); -- 0x01 TCR0UB_Tmp <= (not TCR0UB_Tmp and (TCCR0_Sel and iowe and AS0))or (TCR0UB_Tmp and not PCK0); OCR0UB_Tmp <= (not OCR0UB_Tmp and (OCR0_Sel and iowe and AS0))or (OCR0UB_Tmp and not PCK0); TCN0UB_Tmp <= (not TCN0UB_Tmp and (TCNT0_Sel and iowe and AS0))or (TCN0UB_Tmp and not PCK0); TCR0UB <= (not TCR0UB and (TCCR0_Sel and iowe and AS0))or (TCR0UB and not (not TCR0UB_Tmp and PCK0)); OCR0UB <= (not OCR0UB and (OCR0_Sel and iowe and AS0))or (OCR0UB and not (not OCR0UB_Tmp and PCK0)); TCN0UB <= (not TCN0UB and (TCNT0_Sel and iowe and AS0))or (TCN0UB and not (not TCN0UB_Tmp and PCK0)); AS0 <= (not AS0 and(ASSR_Sel and iowe and dbus_in(3)))or (AS0 and not(ASSR_Sel and iowe and not dbus_in(3))); end if;end process; -- Temp registers of TCNT0-- This register is used only when TCNT0 operates in the asynchronous modeTCNT0_Temp_Control:process(cp2,ireset)beginif ireset='0' then -- Reset TCCR0_Tmp <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if (TCCR0_Sel and iowe and AS0)='1' then -- Clock enable TCCR0_Tmp <= dbus_in; end if; end if;end process; -- This register is used only when TCNT0 operates in the asynchronous modeTCNT0_Temp_CNT:process(cp2,ireset)beginif ireset='0' then -- Reset TCNT0_Tmp <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if (TCNT0_Sel and iowe and AS0)='1' then -- Clock enable TCNT0_Tmp <= dbus_in; end if; end if;end process; TCNT0_Temp_Compare:process(cp2,ireset)beginif ireset='0' then -- Reset OCR0_Tmp <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if (OCR0_Sel and iowe )='1' then -- Clock enable ??!! was "and (AS0 or PWM0)" OCR0_Tmp <= dbus_in; end if; end if;end process; -- Main registers of TCNT0TCNT0_Control:process(cp2,ireset)beginif ireset='0' then -- Reset TCCR0 <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if ((TCCR0_Sel and iowe and not AS0)or (TCR0UB and not TCR0UB_Tmp and PCK0 and AS0))='1' then -- Clock enable TCCR0(6 downto 0) <= TCCR0_In(6 downto 0); end if; end if;end process; TCCR0_In <= TCCR0_Tmp when (TCR0UB and not TCR0UB_Tmp and PCK0 and AS0)='1' else dbus_in;TCNT0_Compare:process(cp2,ireset)beginif ireset='0' then -- Reset OCR0 <= (others => '0'); elsif cp2='1' and cp2'event then -- Clock if ((((OCR0_Sel and iowe and not AS0)or -- Synchronous non PWM mode (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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -