📄 timer_counter.vhd
字号:
end if;
end process;
-- -------------------------------------------------------------------------------------------
-- Prescalers
-- -------------------------------------------------------------------------------------------
-- Prescaler 1 for TCNT1 and TCNT2
Prescaler_1:process(cp2,ireset)
begin
if 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"
(CK64 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"
(CK64 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 TCNT0
Tosc1_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)
begin
if 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)
begin
if 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 decoder
TCCR0_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)
begin
if 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)
begin
if 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)
begin
if 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 mode
TCNT0_Temp_Control:process(cp2,ireset)
begin
if 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 mode
TCNT0_Temp_CNT:process(cp2,ireset)
begin
if 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)
begin
if 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 TCNT0
TCNT0_Control:process(cp2,ireset)
begin
if 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)
begin
if 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -