131 lines
4.1 KiB
VHDL
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;
|