signal_processing_vorlage/hardware/system/data_channel_control.vhd

152 lines
4.7 KiB
VHDL
Raw Normal View History

2023-10-31 07:47:27 +01:00
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;