103 lines
2.8 KiB
VHDL
103 lines
2.8 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
|
|
library work;
|
|
use work.reg32.all;
|
|
use work.avalon_slave.all;
|
|
|
|
entity timer is
|
|
port (
|
|
clk : in std_logic;
|
|
reset : in std_logic;
|
|
|
|
address : in std_logic_vector( 3 downto 0 );
|
|
read : in std_logic;
|
|
readdata : out std_logic_vector( 31 downto 0 );
|
|
write : in std_logic;
|
|
writedata : in std_logic_vector( 31 downto 0 )
|
|
);
|
|
end entity timer;
|
|
|
|
architecture rtl of timer is
|
|
|
|
type Registers is (
|
|
REG_STATE,
|
|
REG_CYCLE_COUNT
|
|
);
|
|
|
|
constant REG_STATE_POS : natural := Registers'pos( REG_STATE );
|
|
constant REG_CYCLE_COUNT_POS : natural := Registers'pos( REG_CYCLE_COUNT );
|
|
constant REG_COUNT : natural := Registers'pos( Registers'right ) + 1;
|
|
|
|
constant REG_ACCESS_TYPES : work.reg32.AccessArray( 0 to REG_COUNT - 1 ) := (
|
|
READ_WRITE,
|
|
READ_ONLY
|
|
);
|
|
|
|
signal reg_index : integer range 0 to REG_COUNT - 1;
|
|
|
|
signal current_avalon_state : work.avalon_slave.State;
|
|
signal next_avalon_state : work.avalon_slave.State;
|
|
|
|
signal running : std_logic;
|
|
signal cycle_count : unsigned( 31 downto 0 );
|
|
|
|
begin
|
|
|
|
u_avalon_slave_transitions: entity work.avalon_slave_transitions
|
|
generic map (
|
|
REG_COUNT => REG_COUNT,
|
|
REG_ACCESS_TYPES => REG_ACCESS_TYPES
|
|
)
|
|
port map (
|
|
address => address,
|
|
read => read,
|
|
write => write,
|
|
|
|
current_state => current_avalon_state,
|
|
next_state => next_avalon_state,
|
|
reg_index => reg_index
|
|
);
|
|
|
|
sync : process ( clk, reset ) is
|
|
begin
|
|
if ( reset = '1' ) then
|
|
current_avalon_state <= SLAVE_IDLE;
|
|
running <= '0';
|
|
|
|
elsif ( rising_edge( clk ) ) then
|
|
current_avalon_state <= next_avalon_state;
|
|
|
|
if ( running = '1' ) then
|
|
cycle_count <= cycle_count + 1;
|
|
end if;
|
|
|
|
case next_avalon_state is
|
|
when SLAVE_IDLE =>
|
|
null;
|
|
|
|
when SLAVE_READ =>
|
|
readdata <= ( others => '0' );
|
|
if ( reg_index = REG_STATE_POS ) then
|
|
readdata( 0 ) <= running;
|
|
elsif ( reg_index = REG_CYCLE_COUNT_POS ) then
|
|
readdata <= std_logic_vector( cycle_count );
|
|
end if;
|
|
|
|
when SLAVE_READ_DATA =>
|
|
null;
|
|
|
|
when SLAVE_WRITE =>
|
|
if ( reg_index = REG_STATE_POS ) then
|
|
running <= writedata( 0 );
|
|
if ( writedata( 0 ) = '1' ) then
|
|
cycle_count <= ( others => '0' );
|
|
end if;
|
|
end if;
|
|
|
|
end case;
|
|
end if;
|
|
end process sync;
|
|
end architecture rtl;
|