209 lines
7.8 KiB
VHDL
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; |