axi3-interconnect/src/axi3-interconnect-decerr.vhd

131 lines
4.1 KiB
VHDL

-------------------------------------------------------------------------------
-- Title : Error Handler
-- Project : AXI-3 Crossbar Switch
-------------------------------------------------------------------------------
-- File : axi3-interconnect-decerr.vhd
-- Author : Mario Hüttel <mario.huettel@gmx.net>
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2016
--
-- This file is part of AXI-3 Crossbar Switch.
--
-- AXI-3 Crossabr Switch is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, version 2 of the License.
--
-- This code is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this code. If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi3intercon_pkg.all;
entity axi3decerr is
port(
clk : in std_logic;
rst : in std_logic;
slave_in : in axi_slave_in_t;
slave_out : out axi_slave_out_t
);
end entity axi3decerr;
architecture RTL of axi3decerr is
type r_state_t is (R_READY, R_ERROR);
type w_state_t is (W_READY, W_ERROR);
signal w_state : w_state_t;
signal r_state : r_state_t;
signal r_len : unsigned(7 downto 0);
begin
read_error : process(clk, rst) is
begin
if rst = '1' then
r_state <= R_READY;
slave_out.r.rdata <= (others => '0');
slave_out.r.rid <= (others => '0');
slave_out.r.rlast <= '0';
slave_out.r.rresp <= (others => '0');
slave_out.r.ruser <= (others => '0');
slave_out.r.rvalid <= '0';
elsif rising_edge(clk) then
case r_state is
when R_READY =>
slave_out.r.rlast <= '0';
if slave_in.ar.arvalid = '1' then
report "Decoder error for READ on address detected" severity note;
r_state <= R_ERROR;
slave_out.r.rid <= slave_in.ar.arid;
slave_out.r.rresp <= AXI_RESP_DECERR;
slave_out.r.rvalid <= '1';
if unsigned(slave_in.ar.arlen) = 0 then
slave_out.r.rlast <= '1';
else
slave_out.r.rlast <= '0';
end if;
r_len <= unsigned(slave_in.ar.arlen);
end if;
when R_ERROR =>
slave_out.r.rvalid <= '1';
if slave_in.r.rready = '1' then
if r_len /= to_unsigned(0, r_len'length) then
r_len <= r_len - 1;
else
r_state <= R_READY;
slave_out.r.rvalid <= '0';
slave_out.r.rlast <= '0';
end if;
if r_len = to_unsigned(1, r_len'length) then
slave_out.r.rlast <= '1';
end if;
end if;
end case;
end if;
end process read_error;
slave_out.ar.arready <= '1' when r_state = R_READY else '0';
-- AW Acceptor:
slave_out.aw.awready <= '1'; -- Always accept write transactions (interconnect will manage that only one is active)
write_error : process(clk, rst) is
begin
if rst = '1' then
w_state <= W_READY;
slave_out.b.bid <= (others => '0');
slave_out.b.bresp <= (others => '0');
slave_out.b.buser <= (others => '0');
slave_out.b.bvalid <= '0';
elsif rising_edge(clk) then
case w_state is
when W_READY =>
if slave_in.w.wvalid = '1' then
report "Decoder error in write transaction" severity note;
w_state <= W_ERROR;
slave_out.b.bid <= slave_in.w.wid;
slave_out.b.bresp <= AXI_RESP_DECERR;
slave_out.b.bvalid <= '1';
end if;
when W_ERROR =>
if slave_in.b.bready = '1' then
slave_out.b.bvalid <= '0';
w_state <= W_READY;
end if;
end case;
end if;
end process write_error;
slave_out.w.wready <= '1' when w_state = W_READY else '0';
end architecture RTL;