Files
Matthias Biermann 29d2fb8183 AXI Schreiben
2025-02-08 17:22:35 +01:00

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;