diff --git a/src/axi3-interconnect-ar-router.vhd b/src/axi3-interconnect-ar-router.vhd index cb74b31..c060583 100644 --- a/src/axi3-interconnect-ar-router.vhd +++ b/src/axi3-interconnect-ar-router.vhd @@ -38,7 +38,9 @@ begin if rst = '1' then for i in 0 to MASTER_COUNT - 1 loop ar_states(i) <= AR_READY; - + end loop; + for i in 0 to SLAVE_COUNT loop + slaves_in(i).arvalid <= '0'; end loop; slave_in_use := (others => '0'); arready_s <= (others => '1'); diff --git a/src/axi3-interconnect-aw-router.vhd b/src/axi3-interconnect-aw-router.vhd index 47c661c..e686ba0 100644 --- a/src/axi3-interconnect-aw-router.vhd +++ b/src/axi3-interconnect-aw-router.vhd @@ -14,7 +14,7 @@ entity axi3intercon_aw_router is 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_releases : in write_release_t; + 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) ); @@ -53,6 +53,9 @@ begin for i in 0 to MASTER_COUNT - 1 loop aw_states(i) <= AW_READY; end loop; + for i in 0 to SLAVE_COUNT loop + slaves_in(i).awvalid <= '0'; + end loop; awready_s <= (others => '1'); slave_in_use := (others => '0'); elsif rising_edge(clk) then diff --git a/src/axi3-interconnect-aw-router_pkg.vhd b/src/axi3-interconnect-aw-router_pkg.vhd index eadaaad..29f4804 100644 --- a/src/axi3-interconnect-aw-router_pkg.vhd +++ b/src/axi3-interconnect-aw-router_pkg.vhd @@ -15,7 +15,7 @@ package axi_aw_router_pkg is end record write_lock_t; type write_locks_t is array (natural range <>) of write_lock_t; - subtype write_release_t is std_logic_vector(0 to MASTER_COUNT - 1); + subtype write_releases_t is std_logic_vector(0 to MASTER_COUNT - 1); end package axi_aw_router_pkg; diff --git a/src/axi3-interconnect-w-router.vhd b/src/axi3-interconnect-w-router.vhd new file mode 100644 index 0000000..d9ede86 --- /dev/null +++ b/src/axi3-interconnect-w-router.vhd @@ -0,0 +1,78 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.axi3intercon_pkg.all; +use work.axi_aw_router_pkg.all; +use work.axi_w_router_pkg.all; + +entity axi3_intercon_w_router is + port( + clk : in std_logic; + rst : in std_logic; + masters_in : out axi_w_masters_in_t(0 to MASTER_COUNT - 1); + masters_out : in axi_w_masters_out_t(0 to MASTER_COUNT - 1); + slaves_in : out axi_w_slaves_in_t(0 to SLAVE_COUNT); + slaves_out : in axi_w_slaves_out_t(0 to SLAVE_COUNT); + write_locks : in write_locks_t; + write_releases : out write_releases_t + ); +end entity axi3_intercon_w_router; + +architecture RTL of axi3_intercon_w_router is + type w_state_t is (W_READY, W_ACTIVE); + type w_states_t is array (0 to MASTER_COUNT - 1) of w_state_t; + signal w_states : w_states_t; + signal wready_s : std_logic_vector(0 to MASTER_COUNT - 1); +begin + wready_gen : for i in 0 to MASTER_COUNT - 1 generate + masters_in(i).wready <= wready_s(i); + end generate wready_gen; + + w_router_sync : process(clk, rst) is + begin + if rst = '1' then + for i in 0 to MASTER_COUNT - 1 loop + wready_s(i) <= '0'; + write_releases(i) <= '0'; + end loop; + for i in 0 to SLAVE_COUNT loop + slaves_in(i).wvalid <= '0'; + end loop; + elsif rising_edge(clk) then + + for i in 0 to MASTER_COUNT - 1 loop + write_releases(i) <= '0'; + if write_locks(i).locked = '1' then + + case w_states(i) is + when W_READY => + wready_s(i) <= '1'; + if wready_s(i) = '1' and masters_out(i).wvalid = '1' then + wready_s(i) <= '0'; + slaves_in(write_locks(i).slave_idx).wdata <= masters_out(i).wdata; + slaves_in(write_locks(i).slave_idx).wid <= std_logic_vector(to_unsigned(i, WID_SLAVE_BITS - WID_MASTER_BITS)) & masters_out(i).wid; + slaves_in(write_locks(i).slave_idx).wlast <= masters_out(i).wlast; + slaves_in(write_locks(i).slave_idx).wstrb <= masters_out(i).wstrb; + slaves_in(write_locks(i).slave_idx).wuser <= masters_out(i).wuser; + slaves_in(write_locks(i).slave_idx).wvalid <= '1'; + if masters_out(i).wlast = '1' then + write_releases(i) <= '1'; + end if; + w_states(i) <= W_ACTIVE; + + end if; + when W_ACTIVE => + if slaves_out(write_locks(i).slave_idx).wready = '1' then + slaves_in(write_locks(i).slave_idx).wvalid <= '0'; + w_states(i) <= W_READY; + end if; + end case; + else + slaves_in(i).wvalid <= '0'; + wready_s(i) <= '0'; + end if; + end loop; + end if; + end process w_router_sync; + +end architecture RTL; diff --git a/src/axi3-interconnect-w-router_pkg.vhd b/src/axi3-interconnect-w-router_pkg.vhd new file mode 100644 index 0000000..121ae71 --- /dev/null +++ b/src/axi3-interconnect-w-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_w_router_pkg is + type axi_w_masters_in_t is array (natural range <>) of master_w_in_t; + type axi_w_masters_out_t is array (natural range <>) of master_w_out_t; + type axi_w_slaves_out_t is array (natural range <>) of slave_w_out_t; + type axi_w_slaves_in_t is array (natural range <>) of slave_w_in_t; +end package axi_w_router_pkg; + +-- package body axi_w_router_pkg is +-- end package body axi_w_router_pkg; diff --git a/src/axi3-interconnect.vhd b/src/axi3-interconnect.vhd index ffc6f15..155a70e 100644 --- a/src/axi3-interconnect.vhd +++ b/src/axi3-interconnect.vhd @@ -22,7 +22,7 @@ end entity axi3intercon; architecture RTL of axi3intercon is signal rst : std_logic; signal write_locks : write_locks_t(0 to MASTER_COUNT - 1); - signal write_releases : write_release_t; + signal write_releases : write_releases_t; signal aw_masters_out : axi_aw_masters_out_t(0 to MASTER_COUNT - 1); signal aw_masters_in : axi_aw_masters_in_t(0 to MASTER_COUNT - 1); signal aw_slaves_out : axi_aw_slaves_out_t(0 to SLAVE_COUNT);