152 lines
4.7 KiB
VHDL
152 lines
4.7 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 data_channel_control 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 );
|
|
|
|
sink_config : out std_logic;
|
|
source_config : out std_logic;
|
|
|
|
clear : out std_logic;
|
|
empty : in std_logic;
|
|
full : in std_logic;
|
|
level : in std_logic_vector( 9 downto 0 );
|
|
|
|
sink_write : out std_logic;
|
|
sink_writedata : out std_logic_vector( 31 downto 0 );
|
|
|
|
source_read : out std_logic;
|
|
source_readdata : in std_logic_vector( 31 downto 0 )
|
|
);
|
|
end entity data_channel_control;
|
|
|
|
architecture rtl of data_channel_control is
|
|
|
|
type Registers is (
|
|
REG_CONFIG,
|
|
REG_EMPTY,
|
|
REG_FULL,
|
|
REG_LEVEL,
|
|
REG_SINK,
|
|
REG_SOURCE,
|
|
REG_CLEAR
|
|
);
|
|
|
|
constant REG_CONFIG_POS : natural := Registers'pos( REG_CONFIG );
|
|
constant REG_EMPTY_POS : natural := Registers'pos( REG_EMPTY );
|
|
constant REG_FULL_POS : natural := Registers'pos( REG_FULL );
|
|
constant REG_LEVEL_POS : natural := Registers'pos( REG_LEVEL );
|
|
constant REG_SINK_POS : natural := Registers'pos( REG_SINK );
|
|
constant REG_SOURCE_POS : natural := Registers'pos( REG_SOURCE );
|
|
constant REG_CLEAR_POS : natural := Registers'pos( REG_CLEAR );
|
|
|
|
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,
|
|
READ_ONLY,
|
|
READ_ONLY,
|
|
WRITE_ONLY,
|
|
READ_ONLY,
|
|
WRITE_ONLY
|
|
);
|
|
|
|
signal reg_index : integer range 0 to REG_COUNT - 1;
|
|
|
|
-- Internal registers
|
|
signal current_state : work.avalon_slave.State;
|
|
signal next_state : work.avalon_slave.State;
|
|
signal reg_data : RegArray( 0 to REG_COUNT - 1 );
|
|
signal fifo_read_req : std_logic;
|
|
|
|
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_state,
|
|
next_state => next_state,
|
|
reg_index => reg_index
|
|
);
|
|
|
|
sync : process ( clk, reset ) is
|
|
begin
|
|
if ( reset = '1' ) then
|
|
current_state <= SLAVE_IDLE;
|
|
reg_data( REG_CONFIG_POS ) <= ( others => '0' );
|
|
fifo_read_req <= '0';
|
|
clear <= '0';
|
|
|
|
elsif ( rising_edge( clk ) ) then
|
|
current_state <= next_state;
|
|
sink_write <= '0';
|
|
source_read <= '0';
|
|
clear <= '0';
|
|
|
|
case next_state is
|
|
when SLAVE_IDLE =>
|
|
null;
|
|
|
|
when SLAVE_READ =>
|
|
readdata <= ( others => '0' );
|
|
if ( reg_index = REG_CONFIG_POS ) then
|
|
readdata( 1 downto 0 ) <= reg_data( reg_index )( 1 downto 0 );
|
|
elsif ( reg_index = REG_EMPTY_POS ) then
|
|
readdata( 0 ) <= reg_data( reg_index )( 0 );
|
|
elsif ( reg_index = REG_FULL_POS ) then
|
|
readdata( 0 ) <= reg_data( reg_index )( 0 );
|
|
elsif ( reg_index = REG_LEVEL_POS ) then
|
|
readdata( 9 downto 0 ) <= reg_data( reg_index )( 9 downto 0 );
|
|
elsif ( reg_index = REG_SINK_POS ) then
|
|
readdata <= reg_data( reg_index );
|
|
elsif ( reg_index = REG_SOURCE_POS ) then
|
|
readdata <= source_readdata;
|
|
source_read <= '1';
|
|
end if;
|
|
when SLAVE_READ_DATA =>
|
|
null;
|
|
|
|
when SLAVE_WRITE =>
|
|
if ( reg_index = REG_SINK_POS ) then
|
|
sink_write <= '1';
|
|
sink_writedata <= writedata;
|
|
elsif ( reg_index = REG_CLEAR_POS ) then
|
|
clear <= '1';
|
|
else
|
|
reg_data( reg_index ) <= writedata;
|
|
end if;
|
|
end case;
|
|
|
|
reg_data( REG_EMPTY_POS )( 0 ) <= empty;
|
|
reg_data( REG_FULL_POS )( 0 ) <= full;
|
|
reg_data( REG_LEVEL_POS )( level'left downto level'right ) <= level;
|
|
end if;
|
|
end process sync;
|
|
|
|
sink_config <= reg_data( REG_CONFIG_POS )( 0 );
|
|
source_config <= reg_data( REG_CONFIG_POS )( 1 );
|
|
|
|
end architecture rtl;
|
|
|