diff --git a/src/axi3-interconnect-decerr.vhd b/src/axi3-interconnect-decerr.vhd index c525f7c..9890ae2 100644 --- a/src/axi3-interconnect-decerr.vhd +++ b/src/axi3-interconnect-decerr.vhd @@ -2,7 +2,7 @@ -- Title : Error Handler -- Project : AXI-3 Crossbar Switch ------------------------------------------------------------------------------- --- File : axi3-interconnect-decerr.vhd +-- File : axi3-interconnect-decerr.vhd -- Author : Mario Hüttel -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- @@ -18,7 +18,7 @@ -- -- 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 +-- 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 @@ -33,11 +33,11 @@ use work.axi3intercon_pkg.all; entity axi3decerr is port( - clk : in std_logic; - rst : in std_logic; - slave_in : in axi_slave_in_t; + 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 @@ -51,24 +51,24 @@ begin read_error : process(clk, rst) is begin if rst = '1' then - r_state <= R_READY; - slave_out.ar.arready <= '0'; - 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'; + 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 - r_state <= R_ERROR; - slave_out.r.rid <= slave_in.ar.arid; + 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) = 1 then + if unsigned(slave_in.ar.arlen) = 0 then slave_out.r.rlast <= '1'; else slave_out.r.rlast <= '0'; @@ -78,13 +78,15 @@ begin when R_ERROR => slave_out.r.rvalid <= '1'; if slave_in.r.rready = '1' then - r_len <= r_len - 1; - if r_len = 2 then - slave_out.r.rlast <= '1'; + 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 - r_state <= R_READY; - slave_out.r.rvalid <= '0'; + slave_out.r.rlast <= '1'; end if; end if; end case; @@ -94,13 +96,13 @@ begin 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) + 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'); + 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'; @@ -108,15 +110,16 @@ begin case w_state is when W_READY => if slave_in.w.wvalid = '1' then - w_state <= W_ERROR; - slave_out.b.bid <= slave_in.w.wid; + 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; + w_state <= W_READY; end if; end case; end if; diff --git a/src/axi3-interconnect_pkg.vhd b/src/axi3-interconnect_pkg.vhd index febbe7c..8a08ed2 100644 --- a/src/axi3-interconnect_pkg.vhd +++ b/src/axi3-interconnect_pkg.vhd @@ -45,8 +45,8 @@ package axi3intercon_pkg is constant USER_BITS : natural := 4; - constant MASTER_COUNT : natural := 2; - constant SLAVE_COUNT : natural := 2; + constant MASTER_COUNT : natural := 1; + constant SLAVE_COUNT : natural := 1; -- Constant definitions for signals @@ -265,6 +265,9 @@ package body axi3intercon_pkg is slave_idx := i; end if; end loop; + + report "Calculated slave address: " & integer'image(slave_idx) severity note; + return slave_idx; end function calculate_slave; diff --git a/src/master2slave/axi3-interconnect-ar-router.vhd b/src/master2slave/axi3-interconnect-ar-router.vhd index d1e1937..9e4972f 100644 --- a/src/master2slave/axi3-interconnect-ar-router.vhd +++ b/src/master2slave/axi3-interconnect-ar-router.vhd @@ -2,7 +2,7 @@ -- Title : AR Router -- Project : AXI-3 Crossbar Switch ------------------------------------------------------------------------------- --- File : master2slave/axi3-interconnect-ar-router.vhd +-- File : master2slave/axi3-interconnect-ar-router.vhd -- Author : Mario Hüttel -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- @@ -18,7 +18,7 @@ -- -- 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 +-- 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 @@ -35,15 +35,15 @@ use work.axi_ar_router_pkg.all; entity axi3intercon_ar_router is port( - aclk : in std_logic; - rst : in std_logic; + aclk : in std_logic; + rst : in std_logic; masters_out : in axi_ar_masters_out_t(0 to MASTER_COUNT - 1); masters_in : out axi_ar_masters_in_t(0 to MASTER_COUNT - 1); slaves_out : in axi_ar_slaves_out_t(0 to SLAVE_COUNT); slaves_in : out axi_ar_slaves_in_t(0 to SLAVE_COUNT); address_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1); mask_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1) - ); + ); end entity axi3intercon_ar_router; architecture RTL of axi3intercon_ar_router is @@ -53,6 +53,7 @@ architecture RTL of axi3intercon_ar_router is signal ar_states : ar_states_t; signal arready_s : std_logic_vector(0 to MASTER_COUNT - 1); type slave_indexes_t is array (0 to MASTER_COUNT - 1) of integer range 0 to SLAVE_COUNT; + signal debug_idx : integer range 0 to SLAVE_COUNT; begin arready_gen : for i in 0 to MASTER_COUNT - 1 generate masters_in(i).arready <= arready_s(i); @@ -81,37 +82,38 @@ begin slave_in_use := (others => '0'); arready_s <= (others => '0'); elsif rising_edge(clk) then - for i in 0 to MASTER_COUNT - 1 loop -- Loop for every master + for i in 0 to MASTER_COUNT - 1 loop -- Loop for every master case ar_states(i) is when AR_READY => if masters_out(i).arvalid = '1' then slave_idx(i) := calculate_slave(masters_out(i).araddr, address_array, mask_array); + debug_idx <= slave_idx(i); if slave_in_use(slave_idx(i)) /= '1' then slave_in_use(slave_idx(i)) := '1'; - masters_in(i).arready <= '1'; - -- Write request to slave + arready_s(i) <= '1'; + -- Write request to slave if slave_idx(i) = SLAVE_COUNT then slaves_in(slave_idx(i)).araddr <= masters_out(i).araddr; else slaves_in(slave_idx(i)).araddr <= masters_out(i).araddr and (not mask_array(slave_idx(i))); end if; - slaves_in(slave_idx(i)).arid <= std_logic_vector(to_unsigned(i, RID_SLAVE_BITS - RID_MASTER_BITS)) & masters_out(i).arid; + slaves_in(slave_idx(i)).arid <= std_logic_vector(to_unsigned(i, RID_SLAVE_BITS - RID_MASTER_BITS)) & masters_out(i).arid; slaves_in(slave_idx(i)).arburst <= masters_out(i).arburst; slaves_in(slave_idx(i)).arcache <= masters_out(i).arcache; - slaves_in(slave_idx(i)).arlen <= masters_out(i).arlen; - slaves_in(slave_idx(i)).arlock <= masters_out(i).arlock; - slaves_in(slave_idx(i)).arprot <= masters_out(i).arprot; - slaves_in(slave_idx(i)).arsize <= masters_out(i).arsize; + slaves_in(slave_idx(i)).arlen <= masters_out(i).arlen; + slaves_in(slave_idx(i)).arlock <= masters_out(i).arlock; + slaves_in(slave_idx(i)).arprot <= masters_out(i).arprot; + slaves_in(slave_idx(i)).arsize <= masters_out(i).arsize; slaves_in(slave_idx(i)).arvalid <= '1'; - ar_states(i) <= AR_ACTIVE; + ar_states(i) <= AR_ACTIVE; end if; end if; when AR_ACTIVE => arready_s(i) <= '0'; if slaves_out(slave_idx(i)).arready = '1' then slaves_in(slave_idx(i)).arvalid <= '0'; - ar_states(i) <= AR_READY; - slave_in_use(slave_idx(i)) := '0'; + ar_states(i) <= AR_READY; + slave_in_use(slave_idx(i)) := '0'; end if; end case; diff --git a/src/master2slave/axi3-interconnect-aw-router.vhd b/src/master2slave/axi3-interconnect-aw-router.vhd index 20ed442..3944add 100644 --- a/src/master2slave/axi3-interconnect-aw-router.vhd +++ b/src/master2slave/axi3-interconnect-aw-router.vhd @@ -2,7 +2,7 @@ -- Title : AW Router -- Project : AXI-3 Crossbar Switch ------------------------------------------------------------------------------- --- File : master2slave/axi3-interconnect-aw-router.vhd +-- File : master2slave/axi3-interconnect-aw-router.vhd -- Author : Mario Hüttel -- Standard : VHDL'93/02 ------------------------------------------------------------------------------- @@ -18,7 +18,7 @@ -- -- 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 +-- 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 @@ -35,17 +35,17 @@ use work.axi_aw_router_pkg.all; entity axi3intercon_aw_router is port( - aclk : in std_logic; - rst : in std_logic; + aclk : in std_logic; + rst : in std_logic; masters_out : in axi_aw_masters_out_t(0 to MASTER_COUNT - 1); masters_in : out axi_aw_masters_in_t(0 to MASTER_COUNT - 1); slaves_out : in axi_aw_slaves_out_t(0 to SLAVE_COUNT); slaves_in : out axi_aw_slaves_in_t(0 to SLAVE_COUNT); - write_locks : out write_locks_t(0 to MASTER_COUNT - 1); -- write_* signals come/go from/to the write router. + write_locks : out write_locks_t(0 to MASTER_COUNT - 1); -- write_* signals come/go from/to the write router. write_releases : in write_releases_t; address_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1); mask_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1) - ); + ); end entity axi3intercon_aw_router; architecture RTL of axi3intercon_aw_router is @@ -63,13 +63,15 @@ begin end generate awready_gen; aw_router : process(clk, rst) is - variable slave_idx : integer range 0 to SLAVE_COUNT := SLAVE_COUNT; -- 1 more slave than connected for handling bad requests. + variable slave_idx : integer range 0 to SLAVE_COUNT := SLAVE_COUNT; -- 1 more slave than connected for handling bad requests. variable slave_in_use : std_logic_vector(0 to SLAVE_COUNT); begin if rst = '1' then for i in 0 to MASTER_COUNT - 1 loop - aw_states(i) <= AW_READY; + aw_states(i) <= AW_READY; + write_locks_s(i).slave_idx <= 0; + write_locks_s(i).locked <= '0'; end loop; for i in 0 to SLAVE_COUNT loop slaves_in(i).awvalid <= '0'; @@ -85,17 +87,17 @@ begin awready_s <= (others => '0'); slave_in_use := (others => '0'); elsif rising_edge(clk) then - for i in 0 to MASTER_COUNT - 1 loop -- Loop for every master + for i in 0 to MASTER_COUNT - 1 loop -- Loop for every master case aw_states(i) is when AW_READY => - if masters_out(i).awvalid = '1' then -- check awready. just to prevent glitches + if masters_out(i).awvalid = '1' then -- check awready. just to prevent glitches slave_idx := calculate_slave(masters_out(i).awaddr, address_array, mask_array); if slave_in_use(slave_idx) /= '1' then - awready_s(i) <= '1'; + awready_s(i) <= '1'; write_locks_s(i).slave_idx <= slave_idx; - write_locks_s(i).locked <= '1'; - slave_in_use(slave_idx) := '1'; - -- output request to slave + write_locks_s(i).locked <= '1'; + slave_in_use(slave_idx) := '1'; + -- output request to slave if slave_idx = SLAVE_COUNT then slaves_in(slave_idx).awaddr <= masters_out(i).awaddr; else @@ -109,21 +111,21 @@ begin slaves_in(slave_idx).awprot <= masters_out(i).awprot; slaves_in(slave_idx).awsize <= masters_out(i).awsize; slaves_in(slave_idx).awvalid <= '1'; - -- Active state waits for awready to be asserted - aw_states(i) <= AW_ACTIVE; + -- Active state waits for awready to be asserted + aw_states(i) <= AW_ACTIVE; end if; end if; when AW_ACTIVE => awready_s(i) <= '0'; if slaves_out(write_locks_s(i).slave_idx).awready = '1' then slaves_in(write_locks_s(i).slave_idx).awvalid <= '0'; - aw_states(i) <= AW_BLOCK; + aw_states(i) <= AW_BLOCK; end if; when AW_BLOCK => if write_releases(i) = '1' then slave_in_use(write_locks_s(i).slave_idx) := '0'; - write_locks_s(i).locked <= '0'; - aw_states(i) <= AW_READY; + write_locks_s(i).locked <= '0'; + aw_states(i) <= AW_READY; end if; end case;