diff --git a/src/axi3-interconnect.vhd b/src/axi3-interconnect.vhd index 443f573..fd188c2 100644 --- a/src/axi3-interconnect.vhd +++ b/src/axi3-interconnect.vhd @@ -7,6 +7,7 @@ use work.axi_aw_router_pkg.all; use work.axi_ar_router_pkg.all; use work.axi_r_router_pkg.all; use work.axi_w_router_pkg.all; +use work.axi_b_router_pkg.all; entity axi3intercon is port( @@ -41,6 +42,10 @@ 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); begin reset_sync : process(aclk, aresetn) is @@ -140,4 +145,24 @@ begin slaves_in(i).r <= r_slaves_in(i); end generate r_slave_connect; + axi3_intercon_b_router_inst : entity work.axi3_intercon_b_router + port map( + clk => aclk, + rst => rst, + slaves_in => b_slaves_in, + slaves_out => b_slaves_out, + masters_in => b_masters_in, + masters_out => b_masters_out + ); + + b_master_connect : for i in 0 to MASTER_COUNT - 1 generate + b_masters_out(i) <= masters_out(i).b; + masters_in(i).b <= b_masters_in(i); + end generate b_master_connect; + + b_slave_connect : for i in 0 to SLAVE_COUNT - 1 generate + b_slaves_out(i) <= slaves_out(i).b; + slaves_in(i).b <= b_slaves_in(i); + end generate b_slave_connect; + end architecture RTL; diff --git a/src/master2slave/axi3-interconnect-ar-router.vhd b/src/master2slave/axi3-interconnect-ar-router.vhd index 6c10208..6ebb335 100644 --- a/src/master2slave/axi3-interconnect-ar-router.vhd +++ b/src/master2slave/axi3-interconnect-ar-router.vhd @@ -41,6 +41,14 @@ begin end loop; for i in 0 to SLAVE_COUNT loop slaves_in(i).arvalid <= '0'; + slaves_in(i).araddr <= (others => '0'); + slaves_in(i).arburst <= (others => '0'); + slaves_in(i).arcache <= (others => '0'); + slaves_in(i).arid <= (others => '0'); + slaves_in(i).arlen <= (others => '0'); + slaves_in(i).arlock <= (others => '0'); + slaves_in(i).arprot <= (others => '0'); + slaves_in(i).arsize <= (others => '0'); end loop; slave_in_use := (others => '0'); arready_s <= (others => '0'); diff --git a/src/master2slave/axi3-interconnect-aw-router.vhd b/src/master2slave/axi3-interconnect-aw-router.vhd index b6a9964..c7e42f7 100644 --- a/src/master2slave/axi3-interconnect-aw-router.vhd +++ b/src/master2slave/axi3-interconnect-aw-router.vhd @@ -37,16 +37,6 @@ begin 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_in_use : std_logic_vector(0 to SLAVE_COUNT); - -- procedure calculate_slave(address : in std_logic_vector(ADDRESS_BITS - 1 downto 0)) is - -- begin - -- slave_idx := SLAVE_COUNT; - -- for i in 0 to SLAVE_COUNT - 1 loop - -- if (address and mask_array(i)) = address_array(i) then - -- slave_idx := i; - -- end if; - -- end loop; - -- - -- end procedure calculate_slave; begin if rst = '1' then @@ -55,6 +45,14 @@ begin end loop; for i in 0 to SLAVE_COUNT loop slaves_in(i).awvalid <= '0'; + slaves_in(i).awaddr <= (others => '0'); + slaves_in(i).awburst <= (others => '0'); + slaves_in(i).awcache <= (others => '0'); + slaves_in(i).awid <= (others => '0'); + slaves_in(i).awlen <= (others => '0'); + slaves_in(i).awlock <= (others => '0'); + slaves_in(i).awprot <= (others => '0'); + slaves_in(i).awsize <= (others => '0'); end loop; awready_s <= (others => '0'); slave_in_use := (others => '0'); diff --git a/src/master2slave/axi3-interconnect-w-router.vhd b/src/master2slave/axi3-interconnect-w-router.vhd index 49290ac..7991c6d 100644 --- a/src/master2slave/axi3-interconnect-w-router.vhd +++ b/src/master2slave/axi3-interconnect-w-router.vhd @@ -37,6 +37,11 @@ begin end loop; for i in 0 to SLAVE_COUNT loop slaves_in(i).wvalid <= '0'; + slaves_in(i).wid <= (others => '0'); + slaves_in(i).wlast <= '0'; + slaves_in(i).wstrb <= (others => '0'); + slaves_in(i).wuser <= (others => '0'); + slaves_in(i).wdata <= (others => '0'); end loop; elsif rising_edge(clk) then for i in 0 to MASTER_COUNT - 1 loop diff --git a/src/slave2master/axi3-interconnect-b-router.vhd b/src/slave2master/axi3-interconnect-b-router.vhd new file mode 100644 index 0000000..0a85cb2 --- /dev/null +++ b/src/slave2master/axi3-interconnect-b-router.vhd @@ -0,0 +1,70 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.axi3intercon_pkg.all; +use work.axi_b_router_pkg.all; + +entity axi3_intercon_b_router is + port( + clk : in std_logic; + rst : in std_logic; + slaves_in : out axi_b_slaves_in_t(0 to SLAVE_COUNT); + slaves_out : in axi_b_slaves_out_t(0 to SLAVE_COUNT); + masters_in : out axi_b_masters_in_t(0 to MASTER_COUNT - 1); + masters_out : in axi_b_masters_out_t(0 to MASTER_COUNT - 1) + ); +end entity axi3_intercon_b_router; + +architecture RTL of axi3_intercon_b_router is + type master_indexes_t is array (natural range <>) of integer range 0 to MASTER_COUNT - 1; + type b_state_t is (B_READY, B_ACTIVE); + type b_states_t is array (0 to SLAVE_COUNT) of b_state_t; + signal b_states : b_states_t; +begin + b_router : process(clk, rst) is + variable master_in_use : std_logic_vector(0 to MASTER_COUNT - 1) := (others => '0'); + variable master_idx : master_indexes_t(0 to SLAVE_COUNT); + begin + if rst = '1' then + master_in_use := (others => '0'); + for i in 0 to SLAVE_COUNT loop + slaves_in(i).bready <= '0'; + b_states(i) <= B_READY; + end loop; + for i in 0 to MASTER_COUNT - 1 loop + masters_in(i).bvalid <= '0'; + masters_in(i).bid <= (others => '0'); + masters_in(i).bresp <= (others => '0'); + masters_in(i).buser <= (others => '0'); + end loop; + -- TODO: Reset + elsif rising_edge(clk) then + for i in 0 to SLAVE_COUNT loop + case b_states(i) is + when B_READY => + if slaves_out(i).bvalid = '1' then + -- calculate master + master_idx(i) := to_integer(unsigned(slaves_out(i).bid(RID_SLAVE_BITS - 1 downto RID_MASTER_BITS))); + if (master_in_use(master_idx(i)) = '0') then + master_in_use(master_idx(i)) := '1'; + slaves_in(i).bready <= '1'; + masters_in(master_idx(i)).bid <= slaves_out(i).bid(masters_in(master_idx(i)).bid'range); + masters_in(master_idx(i)).bresp <= slaves_out(i).bresp; + masters_in(master_idx(i)).buser <= slaves_out(i).buser; + masters_in(master_idx(i)).bvalid <= '1'; + b_states(i) <= B_ACTIVE; + end if; + end if; + when B_ACTIVE => + slaves_in(i).bready <= '0'; + if masters_out(master_idx(i)).bready = '1' then + masters_in(master_idx(i)).bvalid <= '0'; + master_in_use(master_idx(i)) := '0'; + b_states(i) <= B_READY; + end if; + end case; + end loop; + end if; + end process b_router; + +end architecture RTL; diff --git a/src/slave2master/axi3-interconnect-b-router_pkg.vhd b/src/slave2master/axi3-interconnect-b-router_pkg.vhd new file mode 100644 index 0000000..114b67f --- /dev/null +++ b/src/slave2master/axi3-interconnect-b-router_pkg.vhd @@ -0,0 +1,14 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.axi3intercon_pkg.all; + +package axi_b_router_pkg is + type axi_b_masters_in_t is array (natural range <>) of master_b_in_t; + type axi_b_masters_out_t is array (natural range <>) of master_b_out_t; + type axi_b_slaves_out_t is array (natural range <>) of slave_b_out_t; + type axi_b_slaves_in_t is array (natural range <>) of slave_b_in_t; +end package axi_b_router_pkg; + +-- package body axi_b_router_pkg is +-- end package body axi_b_router_pkg; diff --git a/src/slave2master/axi3-interconnect-r-router.vhd b/src/slave2master/axi3-interconnect-r-router.vhd index d262594..85d3035 100644 --- a/src/slave2master/axi3-interconnect-r-router.vhd +++ b/src/slave2master/axi3-interconnect-r-router.vhd @@ -35,6 +35,11 @@ begin end loop; for i in 0 to MASTER_COUNT - 1 loop masters_in(i).rvalid <= '0'; + masters_in(i).rdata <= (others => '0'); + masters_in(i).rid <= (others => '0'); + masters_in(i).rlast <= '0'; + masters_in(i).rresp <= (others => '0'); + masters_in(i).ruser <= (others => '0'); end loop; -- TODO: Reset elsif rising_edge(clk) then