------------------------------------------------------------------------------- -- Title : Error Handler -- Project : AXI-3 Crossbar Switch ------------------------------------------------------------------------------- -- File : axi3-interconnect-decerr.vhd -- Author : Mario Hüttel -- 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 . -- ------------------------------------------------------------------------------- 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;