Files
es-abschlussprojekt/Archiv/Hardware/crc_axi_master.vhd
T
2025-01-31 17:47:31 +01:00

209 lines
7.8 KiB
VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity crc_axi_master is
generic (
DWIDTH : positive := 32;
IDWIDTH : positive := 1;
MAX_BURSTLEN : positive := 16;
LUTRAM_AWIDTH : positive := 4
);
port (
CLK : in std_logic;
RESETN : in std_logic;
-- Control signals
start : in std_logic;
write : in std_logic;
addr_axi : in std_logic_vector(DWIDTH-1 downto 0);
size : in std_logic_vector(3 downto 0);
ip_idle : out std_logic;
-- Interface to LUTRAM
waddr : out std_logic_vector(LUTRAM_AWIDTH-1 downto 0);
wdata : out std_logic_vector(DWIDTH-1 downto 0);
we : out std_logic;
raddr : out std_logic_vector(LUTRAM_AWIDTH-1 downto 0);
rdata : in std_logic_vector(DWIDTH-1 downto 0);
re : out std_logic;
-- AXI Master Interface (Memory)
M_AXI_ARREADY : in std_logic;
M_AXI_ARVALID : out std_logic := '0';
M_AXI_ARADDR : out std_logic_vector(31 downto 0);
M_AXI_ARID : out std_logic_vector(IDWIDTH-1 downto 0);
M_AXI_ARLEN : out std_logic_vector( 3 downto 0);
M_AXI_ARSIZE : out std_logic_vector( 2 downto 0);
M_AXI_ARBURST : out std_logic_vector( 1 downto 0);
M_AXI_ARPROT : out std_logic_vector( 2 downto 0);
M_AXI_ARCACHE : out std_logic_vector( 3 downto 0);
M_AXI_RREADY : out std_logic;
M_AXI_RVALID : in std_logic;
M_AXI_RDATA : in std_logic_vector(DWIDTH-1 downto 0);
M_AXI_RRESP : in std_logic_vector( 1 downto 0);
M_AXI_RID : in std_logic_vector(IDWIDTH-1 downto 0);
M_AXI_RLAST : in std_logic;
M_AXI_AWREADY : in std_logic := '0';
M_AXI_AWVALID : out std_logic := '0';
M_AXI_AWADDR : out std_logic_vector(31 downto 0);
M_AXI_AWLEN : out std_logic_vector( 3 downto 0);
M_AXI_AWSIZE : out std_logic_vector( 2 downto 0);
M_AXI_AWID : out std_logic_vector(IDWIDTH-1 downto 0);
M_AXI_AWBURST : out std_logic_vector( 1 downto 0);
M_AXI_AWPROT : out std_logic_vector( 2 downto 0);
M_AXI_AWCACHE : out std_logic_vector( 3 downto 0);
M_AXI_WREADY : in std_logic := '0';
M_AXI_WVALID : out std_logic := '0';
M_AXI_WDATA : out std_logic_vector(DWIDTH-1 downto 0);
M_AXI_WSTRB : out std_logic_vector(DWIDTH/8-1 downto 0);
M_AXI_WLAST : out std_logic;
M_AXI_WID : out std_logic_vector(DWIDTH-1 downto 0);
M_AXI_BREADY : out std_logic;
M_AXI_BVALID : in std_logic := '0';
M_AXI_BID : in std_logic_vector( DWIDTH-1 downto 0);
M_AXI_BRESP : in std_logic_vector( 1 downto 0)
);
end entity;
architecture rtl of crc_axi_master is
type state_t is (IDLE, R_REQ, R_WAIT_REQ_ACCEPT, READ_DATA, W_REQ, W_WAIT_REQ_ACCEPT, GET_FIRST_WORD, WRITE_DATA);
signal state : state_t := IDLE;
signal addr_LUTRAM : unsigned(LUTRAM_AWIDTH-1 downto 0) := (others=>'0');
signal addr_mem : unsigned(31 downto 0) := (others=>'0');
begin
--------------------------------
-- AXI Read/Write Request Engine
--------------------------------
-- static outputs
M_AXI_ARSIZE <= "010" when DWIDTH=32 else "011"; -- Data width 32/64
M_AXI_ARBURST <= "01";
M_AXI_ARPROT <= "000";
M_AXI_ARCACHE <= "0000";
M_AXI_ARID <= (others=>'0');
M_AXI_RREADY <= '1';
M_AXI_AWSIZE <= "010" when DWIDTH=32 else "011"; -- Data width 32/64
M_AXI_AWBURST <= "01";
M_AXI_AWPROT <= "000";
M_AXI_AWCACHE <= "0000";
M_AXI_BREADY <= '1';
M_AXI_WSTRB <= (others=>'1');
M_AXI_AWID <= (others=>'0');
M_AXI_WID <= (others=>'0');
-- Interface to LUT Ram
M_AXI_WDATA <= rdata;
raddr <= std_logic_vector(addr_LUTRAM);
re <= '1' when (state = WRITE_DATA) else '0';
waddr <= std_logic_vector(addr_LUTRAM);
wdata <= M_AXI_RDATA;
we <= M_AXI_RVALID;
process
variable data_cnt : integer range 0 to MAX_BURSTLEN := 0;
begin
wait until rising_edge(CLK);
if RESETN = '0' then
M_AXI_ARVALID <= '0';
M_AXI_ARADDR <= (others=>'0');
M_AXI_ARLEN <= (others=>'0');
M_AXI_WVALID <= '0';
M_AXI_AWVALID <= '0';
M_AXI_AWADDR <= (others=>'0');
M_AXI_AWLEN <= (others=>'0');
M_AXI_WLAST <= '0';
state <= IDLE;
else
case state is
when IDLE =>
if start = '1' then
addr_LUTRAM <= (others=>'0');
addr_mem <= unsigned(addr_axi);
data_cnt := to_integer(unsigned(size))+1;
ip_idle <= '0';
if write = '0' then
state <= R_REQ;
else
state <= W_REQ;
end if;
end if;
when R_REQ =>
M_AXI_ARADDR <= std_logic_vector(addr_mem);
M_AXI_ARLEN <= size;
M_AXI_ARVALID <= '1';
state <= R_WAIT_REQ_ACCEPT;
when R_WAIT_REQ_ACCEPT =>
if M_AXI_ARREADY = '1' then
M_AXI_ARVALID <= '0';
state <= READ_DATA;
end if;
when READ_DATA =>
if M_AXI_RVALID = '1' then
addr_LUTRAM <= addr_LUTRAM + 1;
if M_AXI_RLAST = '1' then
ip_idle <= '1';
state <= IDLE;
end if;
end if;
when W_REQ =>
M_AXI_AWVALID <= '1';
M_AXI_AWADDR <= std_logic_vector(addr_mem);
M_AXI_AWLEN <= size;
state <= W_WAIT_REQ_ACCEPT;
when W_WAIT_REQ_ACCEPT =>
if M_AXI_AWREADY = '1' then
M_AXI_AWVALID <= '0';
if data_cnt = 1 then
M_AXI_WLAST <= '1';
end if;
M_AXI_WVALID <= '1';
-- re <= '1';
state <= WRITE_DATA;
end if;
when WRITE_DATA =>
if M_AXI_WREADY = '1' then
-- get next word from Block RAM
data_cnt := data_cnt - 1;
addr_LUTRAM <= addr_LUTRAM + 1;
if data_cnt = 1 then
M_AXI_WLAST <= '1';
end if;
if data_cnt = 0 then
M_AXI_WLAST <= '0';
M_AXI_WVALID <= '0';
-- re <= '0';
ip_idle <= '1';
state <= IDLE;
end if;
end if;
when others => null;
end case;
end if;
end process;
end architecture;