151 lines
5.9 KiB
VHDL
151 lines
5.9 KiB
VHDL
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
entity axi3_slave_verif is
|
|
generic (
|
|
DWIDTH : positive := 32;
|
|
IDWIDTH : positive := 1;
|
|
MAX_BURSTLEN : positive := 16
|
|
);
|
|
port (
|
|
CLK : in std_logic;
|
|
RESETN : in std_logic;
|
|
|
|
-- AXI Read Address Channel
|
|
S_AXI_ARVALID : in std_logic;
|
|
S_AXI_ARREADY : out std_logic := '0';
|
|
S_AXI_ARADDR : in std_logic_vector(31 downto 0);
|
|
S_AXI_ARID : in std_logic_vector(IDWIDTH-1 downto 0);
|
|
S_AXI_ARLEN : in std_logic_vector( 3 downto 0);
|
|
S_AXI_ARSIZE : in std_logic_vector( 2 downto 0);
|
|
S_AXI_ARBURST : in std_logic_vector( 1 downto 0);
|
|
|
|
-- AXI Read Data Channel
|
|
S_AXI_RVALID : out std_logic := '0';
|
|
S_AXI_RREADY : in std_logic;
|
|
S_AXI_RDATA : out std_logic_vector(DWIDTH-1 downto 0);
|
|
S_AXI_RRESP : out std_logic_vector( 1 downto 0);
|
|
S_AXI_RID : out std_logic_vector(IDWIDTH-1 downto 0);
|
|
S_AXI_RLAST : out std_logic := '0';
|
|
|
|
-- AXI Write Address Channel
|
|
S_AXI_AWVALID : in std_logic;
|
|
S_AXI_AWREADY : out std_logic := '0';
|
|
S_AXI_AWADDR : in std_logic_vector(31 downto 0);
|
|
S_AXI_AWLEN : in std_logic_vector( 3 downto 0);
|
|
S_AXI_AWSIZE : in std_logic_vector( 2 downto 0);
|
|
S_AXI_AWBURST : in std_logic_vector( 1 downto 0);
|
|
|
|
-- AXI Write Data Channel
|
|
S_AXI_WVALID : in std_logic;
|
|
S_AXI_WREADY : out std_logic := '0';
|
|
S_AXI_WDATA : in std_logic_vector(DWIDTH-1 downto 0);
|
|
S_AXI_WSTRB : in std_logic_vector(DWIDTH/8-1 downto 0);
|
|
S_AXI_WLAST : in std_logic;
|
|
|
|
-- AXI Write Response Channel
|
|
S_AXI_BVALID : out std_logic := '0';
|
|
S_AXI_BREADY : in std_logic;
|
|
S_AXI_BRESP : out std_logic_vector( 1 downto 0)
|
|
);
|
|
end axi3_slave_verif;
|
|
|
|
architecture Behavioral of axi3_slave_verif is
|
|
-- Getrennte Zustände für Lese- und Schreibprozesse
|
|
type read_state_type is (IDLE, READ_RESP, CLEAR_LAST);
|
|
type write_state_type is (IDLE, WRITE_WAIT, WRITE_RESP);
|
|
|
|
signal read_state : read_state_type := IDLE;
|
|
signal write_state : write_state_type := IDLE;
|
|
|
|
signal read_addr : std_logic_vector(31 downto 0);
|
|
signal write_addr : std_logic_vector(31 downto 0);
|
|
|
|
begin
|
|
|
|
process(CLK)
|
|
variable read_burst_count : integer range 0 to MAX_BURSTLEN := 0;
|
|
variable write_burst_count : integer range 0 to MAX_BURSTLEN := 0;
|
|
variable dummy_data : unsigned(31 downto 0) := (others=>'0');
|
|
begin
|
|
if rising_edge(CLK) then
|
|
if RESETN = '0' then
|
|
-- Reset aller Signale
|
|
read_state <= IDLE;
|
|
write_state <= IDLE;
|
|
|
|
S_AXI_ARREADY <= '0';
|
|
S_AXI_RVALID <= '0';
|
|
S_AXI_AWREADY <= '0';
|
|
S_AXI_WREADY <= '0';
|
|
S_AXI_BVALID <= '0';
|
|
else
|
|
-- Leseprozess (Lesen kann parallel zum Schreiben laufen)
|
|
case read_state is
|
|
when IDLE =>
|
|
S_AXI_ARREADY <= '1';
|
|
if S_AXI_ARVALID = '1' then
|
|
read_addr <= S_AXI_ARADDR;
|
|
read_burst_count := to_integer(unsigned(S_AXI_ARLEN)) + 1;
|
|
S_AXI_ARREADY <= '0';
|
|
read_state <= READ_RESP;
|
|
end if;
|
|
|
|
when READ_RESP =>
|
|
S_AXI_RVALID <= '1';
|
|
S_AXI_RDATA <= std_logic_vector(dummy_data);
|
|
dummy_data := dummy_data + 1;
|
|
S_AXI_RRESP <= "00"; -- OKAY response
|
|
|
|
if S_AXI_RREADY = '1' then
|
|
if read_burst_count > 1 then
|
|
read_burst_count := read_burst_count - 1;
|
|
else
|
|
S_AXI_RLAST <= '1';
|
|
read_state <= CLEAR_LAST;
|
|
end if;
|
|
end if;
|
|
when CLEAR_LAST =>
|
|
S_AXI_RLAST <= '0';
|
|
S_AXI_RVALID <= '0';
|
|
read_state <= IDLE;
|
|
end case;
|
|
|
|
-- Schreibprozess (Schreiben läuft unabhängig)
|
|
case write_state is
|
|
when IDLE =>
|
|
S_AXI_AWREADY <= '1';
|
|
if S_AXI_AWVALID = '1' then
|
|
write_addr <= S_AXI_AWADDR;
|
|
write_burst_count := to_integer(unsigned(S_AXI_AWLEN)) + 1;
|
|
S_AXI_AWREADY <= '0';
|
|
write_state <= WRITE_WAIT;
|
|
end if;
|
|
|
|
when WRITE_WAIT =>
|
|
S_AXI_WREADY <= '1';
|
|
if S_AXI_WVALID = '1' then
|
|
if write_burst_count >= 1 then
|
|
write_burst_count := write_burst_count - 1;
|
|
else
|
|
S_AXI_WREADY <= '0';
|
|
|
|
S_AXI_BVALID <= '1';
|
|
S_AXI_BRESP <= "00"; -- OKAY response
|
|
|
|
write_state <= WRITE_RESP;
|
|
end if;
|
|
end if;
|
|
|
|
when WRITE_RESP =>
|
|
if S_AXI_BREADY = '1' then
|
|
S_AXI_BVALID <= '0';
|
|
write_state <= IDLE;
|
|
end if;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
end Behavioral;
|