diff --git a/src/axi3-interconnect-decerr.vhd b/src/axi3-interconnect-decerr.vhd index b52e635..a693984 100644 --- a/src/axi3-interconnect-decerr.vhd +++ b/src/axi3-interconnect-decerr.vhd @@ -3,19 +3,22 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.axi3intercon_pkg.all; -entity filename is +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 filename; +end entity axi3decerr; -architecture RTL of filename is +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 @@ -61,4 +64,36 @@ begin end if; end process read_error; + -- 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 + slave_out.w.wready <= '0'; + 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 + slave_out.w.wready <= '1'; + w_state <= W_ERROR; + slave_out.b.bid <= slave_in.w.wid; + slave_out.b.bresp <= AXI_RESP_DECERR; + slave_out.b.bvalid <= '1'; + r_len <= unsigned(slave_in.ar.arlen); + end if; + when W_ERROR => + slave_out.w.wready <= '0'; + 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; + end architecture RTL; diff --git a/src/axi3-interconnect.vhd b/src/axi3-interconnect.vhd index fd188c2..a1d43da 100644 --- a/src/axi3-interconnect.vhd +++ b/src/axi3-interconnect.vhd @@ -42,10 +42,13 @@ architecture RTL of axi3intercon is signal r_slaves_out : axi_r_slaves_out_t(0 to SLAVE_COUNT); signal r_masters_in : axi_r_masters_in_t(0 to MASTER_COUNT - 1); signal r_masters_out : axi_r_masters_out_t(0 to MASTER_COUNT - 1); - signal b_slaves_in : axi_b_slaves_in_t(0 to SLAVE_COUNT); - signal b_slaves_out : axi_b_slaves_out_t(0 to SLAVE_COUNT); - signal b_masters_in : axi_b_masters_in_t(0 to MASTER_COUNT - 1); - signal b_masters_out : axi_b_masters_out_t(0 to MASTER_COUNT - 1); + signal b_slaves_in : axi_b_slaves_in_t(0 to SLAVE_COUNT); + signal b_slaves_out : axi_b_slaves_out_t(0 to SLAVE_COUNT); + signal b_masters_in : axi_b_masters_in_t(0 to MASTER_COUNT - 1); + signal b_masters_out : axi_b_masters_out_t(0 to MASTER_COUNT - 1); + + signal decerr_in : axi_slave_in_t; + signal decerr_out : axi_slave_out_t; begin reset_sync : process(aclk, aresetn) is @@ -164,5 +167,27 @@ begin b_slaves_out(i) <= slaves_out(i).b; slaves_in(i).b <= b_slaves_in(i); end generate b_slave_connect; - + + -- ERROR slave connections + + axi3decerr_inst : entity work.axi3decerr + port map( + clk => aclk, + rst => rst, + slave_in => decerr_in, + slave_out => decerr_out + ); + + decerr_in.ar <= ar_slaves_in(SLAVE_COUNT); + decerr_in.aw <= aw_slaves_in(SLAVE_COUNT); + decerr_in.r <= r_slaves_in(SLAVE_COUNT); + decerr_in.w <= w_slaves_in(SLAVE_COUNT); + decerr_in.b <= b_slaves_in(SLAVE_COUNT); + + ar_slaves_out(SLAVE_COUNT) <= decerr_out.ar; + aw_slaves_out(SLAVE_COUNT) <= decerr_out.aw; + r_slaves_out(SLAVE_COUNT) <= decerr_out.r; + w_slaves_out(SLAVE_COUNT) <= decerr_out.w; + b_slaves_out(SLAVE_COUNT) <= decerr_out.b; + end architecture RTL;