📄 timer_counter.vhd
字号:
--**********************************************************************************************
-- Timers/Counters Block Peripheral for the AVR Core
-- Version 1.37? (Special version for the JTAG OCD)
-- Modified 11.06.2004
-- Synchronizer for EXT1/EXT2 inputs was added
-- Designed by Ruslan Lepetenok
-- Note : Only T/C0 and T/C2 are implemented
--**********************************************************************************************
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use WORK.AVRuCPackage.all;
entity Timer_Counter is port(
-- AVR Control
ireset : in std_logic;
cp2 : in std_logic;
cp2en : in std_logic;
tmr_cp2en : in std_logic;
stopped_mode : in std_logic; -- ??
tmr_running : in std_logic; -- ??
adr : in std_logic_vector(5 downto 0);
dbus_in : in std_logic_vector(7 downto 0);
dbus_out : out std_logic_vector(7 downto 0);
iore : in std_logic;
iowe : in std_logic;
out_en : out std_logic;
-- External inputs/outputs
EXT1 : in std_logic;
EXT2 : in std_logic;
OC0_PWM0 : out std_logic;
OC1A_PWM1A : out std_logic;
OC1B_PWM1B : out std_logic;
OC2_PWM2 : out std_logic;
-- Interrupt related signals
TC0OvfIRQ : out std_logic;
TC0OvfIRQ_Ack : in std_logic;
TC0CmpIRQ : out std_logic;
TC0CmpIRQ_Ack : in std_logic;
TC2OvfIRQ : out std_logic;
TC2OvfIRQ_Ack : in std_logic;
TC2CmpIRQ : out std_logic;
TC2CmpIRQ_Ack : in std_logic;
TC1OvfIRQ : out std_logic;
TC1OvfIRQ_Ack : in std_logic;
TC1CmpAIRQ : out std_logic;
TC1CmpAIRQ_Ack : in std_logic;
TC1CmpBIRQ : out std_logic;
TC1CmpBIRQ_Ack : in std_logic;
TC1ICIRQ : out std_logic;
TC1ICIRQ_Ack : in std_logic
);
end Timer_Counter;
architecture RTL of Timer_Counter is
-- Copies of the external signals
signal OC0_PWM0_Int : std_logic;
signal OC2_PWM2_Int : std_logic;
-- Registers
signal TCCR0 : std_logic_vector(7 downto 0);
signal TCCR1A : std_logic_vector(7 downto 0);
signal TCCR1B : std_logic_vector(7 downto 0);
signal TCCR2 : std_logic_vector(7 downto 0);
signal ASSR : std_logic_vector(7 downto 0); -- Asynchronous status register (for TCNT0)
signal TIMSK : std_logic_vector(7 downto 0);
signal TIFR : std_logic_vector(7 downto 0);
signal TCNT0 : std_logic_vector(7 downto 0);
signal TCNT2 : std_logic_vector(7 downto 0);
signal OCR0 : std_logic_vector(7 downto 0);
signal OCR2 : std_logic_vector(7 downto 0);
signal TCNT1H : std_logic_vector(7 downto 0);
signal TCNT1L : std_logic_vector(7 downto 0);
signal OCR1AH : std_logic_vector(7 downto 0);
signal OCR1AL : std_logic_vector(7 downto 0);
signal OCR1BH : std_logic_vector(7 downto 0);
signal OCR1BL : std_logic_vector(7 downto 0);
signal ICR1AH : std_logic_vector(7 downto 0);
signal ICR1AL : std_logic_vector(7 downto 0);
-- TCCR0 Bits
alias CS00 : std_logic is TCCR0(0);
alias CS01 : std_logic is TCCR0(1);
alias CS02 : std_logic is TCCR0(2);
alias CTC0 : std_logic is TCCR0(3);
alias COM00 : std_logic is TCCR0(4);
alias COM01 : std_logic is TCCR0(5);
alias PWM0 : std_logic is TCCR0(6);
-- TCCR1A Bits
alias PWM10 : std_logic is TCCR1A(0);
alias PWM11 : std_logic is TCCR1A(1);
alias COM1B0 : std_logic is TCCR1A(4);
alias COM1B1 : std_logic is TCCR1A(5);
alias COM1A0 : std_logic is TCCR1A(4);
alias COM1A1 : std_logic is TCCR1A(5);
-- TCCR1B Bits
alias CS10 : std_logic is TCCR1A(0);
alias CS11 : std_logic is TCCR1A(1);
alias CS12 : std_logic is TCCR1A(2);
alias CTC1 : std_logic is TCCR1A(3);
alias ICES1 : std_logic is TCCR1A(6);
alias ICNC1 : std_logic is TCCR1A(7);
-- TCCR2 Bits
alias CS20 : std_logic is TCCR2(0);
alias CS21 : std_logic is TCCR2(1);
alias CS22 : std_logic is TCCR2(2);
alias CTC2 : std_logic is TCCR2(3);
alias COM20 : std_logic is TCCR2(4);
alias COM21 : std_logic is TCCR2(5);
alias PWM2 : std_logic is TCCR2(6);
-- ASSR bits
alias TCR0UB : std_logic is ASSR(0);
alias OCR0UB : std_logic is ASSR(1);
alias TCN0UB : std_logic is ASSR(2);
alias AS0 : std_logic is ASSR(3);
-- TIMSK bits
alias TOIE0 : std_logic is TIMSK(0);
alias OCIE0 : std_logic is TIMSK(1);
alias TOIE1 : std_logic is TIMSK(2);
alias OCIE1B : std_logic is TIMSK(3);
alias OCIE1A : std_logic is TIMSK(4);
alias TICIE1 : std_logic is TIMSK(5);
alias TOIE2 : std_logic is TIMSK(6);
alias OCIE2 : std_logic is TIMSK(7);
-- TIFR bits
alias TOV0 : std_logic is TIFR(0);
alias OCF0 : std_logic is TIFR(1);
alias TOV1 : std_logic is TIFR(2);
alias OCF1B : std_logic is TIFR(3);
alias OCF1A : std_logic is TIFR(4);
alias ICF1 : std_logic is TIFR(5);
alias TOV2 : std_logic is TIFR(6);
alias OCF2 : std_logic is TIFR(7);
-- Prescaler1 signals
signal CK8 : std_logic;
signal CK64 : std_logic;
signal CK256 : std_logic;
signal CK1024 : std_logic;
signal Pre1Cnt : std_logic_vector(9 downto 0); -- Prescaler 1 counter (10-bit)
signal EXT1RE : std_logic; -- Rising edge of external input EXT1 (for TCNT1 only)
signal EXT1FE : std_logic; -- Falling edge of external input EXT1 (for TCNT1 only)
signal EXT2RE : std_logic; -- Rising edge of external input EXT2 (for TCNT2 only)
signal EXT2FE : std_logic; -- Falling edge of external input EXT2 (for TCNT2 only)
-- Risign/falling edge detectors
signal EXT1Latched : std_logic;
signal EXT2Latched : std_logic;
-- Prescalers outputs
signal TCNT0_En : std_logic; -- Output of the prescaler 0
signal TCNT1_En : std_logic; -- Output of the prescaler 1
signal TCNT2_En : std_logic; -- Output of the prescaler 1
-- Prescaler0 signals
signal PCK08 : std_logic;
signal PCK032 : std_logic;
signal PCK064 : std_logic;
signal PCK0128 : std_logic;
signal PCK0256 : std_logic;
signal PCK01024 : std_logic;
signal Pre0Cnt : std_logic_vector(9 downto 0); -- Prescaler 0 counter (10-bit)
-- Synchronizer signals
signal EXT1SA : std_logic;
signal EXT1SB : std_logic; -- Output of the synchronizer for EXT1
signal EXT2SA : std_logic;
signal EXT2SB : std_logic; -- Output of the synchronizer for EXT1
-- Temporary registers
signal OCR0_Tmp : std_logic_vector(OCR0'range);
signal OCR2_Tmp : std_logic_vector(OCR2'range);
-- Counters control(Inc/Dec)
signal Cnt0Dir : std_logic;
signal Cnt2Dir : std_logic;
--
signal TCNT0WrFl : std_logic;
signal TCNT0CmpBl : std_logic;
signal TCNT2WrFl : std_logic;
signal TCNT2CmpBl : std_logic;
begin
-- Synchronizers
SyncDFFs:process(cp2,ireset)
begin
if (ireset='0') then -- Reset
EXT1SA <= '0';
EXT1SB <= '0';
EXT2SA <= '0';
EXT2SB <= '0';
elsif (cp2='1' and cp2'event) then -- Clock
if (tmr_cp2en='1') then -- Clock Enable(Note 2)
EXT1SA <= EXT1;
EXT1SB <= EXT1SA;
EXT2SA <= EXT2;
EXT2SB <= EXT2SA;
end if;
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
if (tmr_cp2en='1') then -- Clock Enable
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 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_Cnt:process(cp2,ireset)
begin
if(ireset='0') then -- Reset
Pre0Cnt <= (others => '0');
elsif (cp2='1' and cp2'event) then -- Clock
if (tmr_cp2en='1') then -- Clock Enable(Note 2)
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';
elsif (cp2='1' and cp2'event) then -- Clock
if (tmr_cp2en='1') then -- Clock Enable
PCK08 <= (not PCK08 and(Pre0Cnt(0) and Pre0Cnt(1)and Pre0Cnt(2)));
PCK032 <= (not PCK032 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4)));
PCK064 <= (not PCK064 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5)));
PCK0128 <= (not PCK0128 and(Pre0Cnt(0) and Pre0Cnt(1) and Pre0Cnt(2) and Pre0Cnt(3) and Pre0Cnt(4) and Pre0Cnt(5) and Pre0Cnt(6)));
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)));
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)));
end if;
end if;
end process;
TCNT0_En <= (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
-- -------------------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- Timer/Counter 0
-- -------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -