diff --git a/src/axi3-interconnect.vhd b/src/axi3-interconnect.vhd index 155a70e..443f573 100644 --- a/src/axi3-interconnect.vhd +++ b/src/axi3-interconnect.vhd @@ -5,6 +5,8 @@ use ieee.numeric_std.all; use work.axi3intercon_pkg.all; 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; entity axi3intercon is port( @@ -14,8 +16,8 @@ entity axi3intercon is masters_out : in axi_masters_out_t(0 to MASTER_COUNT - 1); slaves_in : out axi_slaves_in_t(0 to SLAVE_COUNT - 1); slaves_out : in axi_slaves_out_t(0 to SLAVE_COUNT - 1); - address_array : axi_slave_addresses_t(0 to SLAVE_COUNT - 1); - mask_array : axi_slave_addresses_t(0 to SLAVE_COUNT - 1) + 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; @@ -31,6 +33,14 @@ architecture RTL of axi3intercon is signal ar_masters_in : axi_ar_masters_in_t(0 to MASTER_COUNT - 1); signal ar_slaves_out : axi_ar_slaves_out_t(0 to SLAVE_COUNT); signal ar_slaves_in : axi_ar_slaves_in_t(0 to SLAVE_COUNT); + signal w_masters_in : axi_w_masters_in_t(0 to MASTER_COUNT - 1); + signal w_masters_out : axi_w_masters_out_t(0 to MASTER_COUNT - 1); + signal w_slaves_in : axi_w_slaves_in_t(0 to SLAVE_COUNT); + signal w_slaves_out : axi_w_slaves_out_t(0 to SLAVE_COUNT); + signal r_slaves_in : axi_r_slaves_in_t(0 to SLAVE_COUNT); + 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); begin reset_sync : process(aclk, aresetn) is @@ -88,4 +98,46 @@ begin slaves_in(i).ar <= ar_slaves_in(i); end generate ar_slave_connect; + axi3_intercon_w_router_inst : entity work.axi3_intercon_w_router + port map( + clk => aclk, + rst => rst, + masters_in => w_masters_in, + masters_out => w_masters_out, + slaves_in => w_slaves_in, + slaves_out => w_slaves_out, + write_locks => write_locks, + write_releases => write_releases + ); + + w_master_connect : for i in 0 to MASTER_COUNT - 1 generate + w_masters_out(i) <= masters_out(i).w; + masters_in(i).w <= w_masters_in(i); + end generate w_master_connect; + + w_slave_connect : for i in 0 to SLAVE_COUNT - 1 generate + w_slaves_out(i) <= slaves_out(i).w; + slaves_in(i).w <= w_slaves_in(i); + end generate w_slave_connect; + + axi3_intercon_r_router_inst : entity work.axi3_intercon_r_router + port map( + clk => aclk, + rst => rst, + slaves_in => r_slaves_in, + slaves_out => r_slaves_out, + masters_in => r_masters_in, + masters_out => r_masters_out + ); + + r_master_connect : for i in 0 to MASTER_COUNT - 1 generate + r_masters_out(i) <= masters_out(i).r; + masters_in(i).r <= r_masters_in(i); + end generate r_master_connect; + + r_slave_connect : for i in 0 to SLAVE_COUNT - 1 generate + r_slaves_out(i) <= slaves_out(i).r; + slaves_in(i).r <= r_slaves_in(i); + end generate r_slave_connect; + end architecture RTL; diff --git a/src/axi3-interconnect_pkg.vhd b/src/axi3-interconnect_pkg.vhd index 86e3049..b8498a6 100644 --- a/src/axi3-interconnect_pkg.vhd +++ b/src/axi3-interconnect_pkg.vhd @@ -153,7 +153,7 @@ package axi3intercon_pkg is rready : std_logic; end record master_r_out_t; - subtype slave_r_in is master_r_out_t; + subtype slave_r_in_t is master_r_out_t; -- Type declarations for B channel type master_b_in_t is record @@ -198,7 +198,7 @@ package axi3intercon_pkg is aw : slave_aw_in_t; ar : slave_ar_in_t; w : slave_w_in_t; - r : slave_r_in; + r : slave_r_in_t; b : slave_b_in_t; end record axi_slave_in_t; @@ -222,6 +222,7 @@ package axi3intercon_pkg is function calculate_slave(address : in std_logic_vector(ADDRESS_BITS - 1 downto 0); address_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1); mask_array : in axi_slave_addresses_t(0 to SLAVE_COUNT - 1)) return integer; + end package axi3intercon_pkg; package body axi3intercon_pkg is @@ -238,4 +239,5 @@ package body axi3intercon_pkg is end loop; return slave_idx; end function calculate_slave; + end package body axi3intercon_pkg; diff --git a/src/master2slave/axi3-interconnect-ar-router.vhd b/src/master2slave/axi3-interconnect-ar-router.vhd index c060583..6c10208 100644 --- a/src/master2slave/axi3-interconnect-ar-router.vhd +++ b/src/master2slave/axi3-interconnect-ar-router.vhd @@ -43,20 +43,19 @@ begin slaves_in(i).arvalid <= '0'; end loop; slave_in_use := (others => '0'); - arready_s <= (others => '1'); + arready_s <= (others => '0'); elsif rising_edge(clk) then for i in 0 to MASTER_COUNT - 1 loop -- Loop for every master case ar_states(i) is when AR_READY => - arready_s(i) <= '1'; - if masters_out(i).arvalid = '1' and arready_s(i) = '1' then + if masters_out(i).arvalid = '1' then slave_idx(i) := calculate_slave(masters_out(i).araddr, address_array, mask_array); if slave_in_use(slave_idx(i)) /= '1' then slave_in_use(slave_idx(i)) := '1'; - masters_in(i).arready <= '0'; + masters_in(i).arready <= '1'; -- Write request to slave slaves_in(slave_idx(i)).araddr <= masters_out(i).araddr; - slaves_in(slave_idx(i)).arid <= std_logic_vector(to_unsigned(i, WID_SLAVE_BITS - WID_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; @@ -68,6 +67,7 @@ begin 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; diff --git a/src/master2slave/axi3-interconnect-aw-router.vhd b/src/master2slave/axi3-interconnect-aw-router.vhd index e686ba0..b6a9964 100644 --- a/src/master2slave/axi3-interconnect-aw-router.vhd +++ b/src/master2slave/axi3-interconnect-aw-router.vhd @@ -56,20 +56,19 @@ begin for i in 0 to SLAVE_COUNT loop slaves_in(i).awvalid <= '0'; end loop; - awready_s <= (others => '1'); + 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 case aw_states(i) is when AW_READY => - masters_in(i).awready <= '1'; - if masters_out(i).awvalid = '1' and awready_s(i) = '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'; write_locks_s(i).slave_idx <= slave_idx; write_locks_s(i).locked <= '1'; slave_in_use(slave_idx) := '1'; - awready_s(i) <= '0'; -- output request to slave slaves_in(slave_idx).awaddr <= masters_out(i).awaddr; slaves_in(slave_idx).awid <= std_logic_vector(to_unsigned(i, WID_SLAVE_BITS - WID_MASTER_BITS)) & masters_out(i).awid; @@ -85,6 +84,7 @@ begin 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; diff --git a/src/master2slave/axi3-interconnect-w-router.vhd b/src/master2slave/axi3-interconnect-w-router.vhd index d9ede86..49290ac 100644 --- a/src/master2slave/axi3-interconnect-w-router.vhd +++ b/src/master2slave/axi3-interconnect-w-router.vhd @@ -32,20 +32,18 @@ begin begin if rst = '1' then for i in 0 to MASTER_COUNT - 1 loop - wready_s(i) <= '0'; + 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 => + when W_READY => wready_s(i) <= '1'; if wready_s(i) = '1' and masters_out(i).wvalid = '1' then wready_s(i) <= '0'; @@ -58,13 +56,13 @@ begin if masters_out(i).wlast = '1' then write_releases(i) <= '1'; end if; - w_states(i) <= W_ACTIVE; - + 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; + w_states(i) <= W_READY; end if; end case; else diff --git a/src/slave2master/axi3-interconnect-r-router.vhd b/src/slave2master/axi3-interconnect-r-router.vhd new file mode 100644 index 0000000..d262594 --- /dev/null +++ b/src/slave2master/axi3-interconnect-r-router.vhd @@ -0,0 +1,71 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.axi3intercon_pkg.all; +use work.axi_r_router_pkg.all; + +entity axi3_intercon_r_router is + port( + clk : in std_logic; + rst : in std_logic; + slaves_in : out axi_r_slaves_in_t(0 to SLAVE_COUNT); + slaves_out : in axi_r_slaves_out_t(0 to SLAVE_COUNT); + masters_in : out axi_r_masters_in_t(0 to MASTER_COUNT - 1); + masters_out : in axi_r_masters_out_t(0 to MASTER_COUNT - 1) + ); +end entity axi3_intercon_r_router; + +architecture RTL of axi3_intercon_r_router is + type master_indexes_t is array (natural range <>) of integer range 0 to MASTER_COUNT - 1; + type r_state_t is (R_READY, R_ACTIVE); + type r_states_t is array (0 to SLAVE_COUNT) of r_state_t; + signal r_states : r_states_t; +begin + r_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).rready <= '0'; + + r_states(i) <= R_READY; + end loop; + for i in 0 to MASTER_COUNT - 1 loop + masters_in(i).rvalid <= '0'; + end loop; + -- TODO: Reset + elsif rising_edge(clk) then + for i in 0 to SLAVE_COUNT loop + case r_states(i) is + when R_READY => + if slaves_out(i).rvalid = '1' then + -- calculate master + master_idx(i) := to_integer(unsigned(slaves_out(i).rid(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).rready <= '1'; + masters_in(master_idx(i)).rid <= slaves_out(i).rid(masters_in(master_idx(i)).rid'range); + masters_in(master_idx(i)).rdata <= slaves_out(i).rdata; + masters_in(master_idx(i)).rlast <= slaves_out(i).rlast; + masters_in(master_idx(i)).rresp <= slaves_out(i).rresp; + masters_in(master_idx(i)).ruser <= slaves_out(i).ruser; + masters_in(master_idx(i)).rvalid <= '1'; + r_states(i) <= R_ACTIVE; + end if; + end if; + when R_ACTIVE => + slaves_in(i).rready <= '0'; + if masters_out(master_idx(i)).rready = '1' then + masters_in(master_idx(i)).rvalid <= '0'; + master_in_use(master_idx(i)) := '0'; + r_states(i) <= R_READY; + end if; + end case; + end loop; + end if; + end process r_router; + +end architecture RTL; diff --git a/src/slave2master/axi3-interconnect-r-router_pkg.vhd b/src/slave2master/axi3-interconnect-r-router_pkg.vhd new file mode 100644 index 0000000..cac4bd0 --- /dev/null +++ b/src/slave2master/axi3-interconnect-r-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_r_router_pkg is + type axi_r_masters_in_t is array (natural range <>) of master_r_in_t; + type axi_r_masters_out_t is array (natural range <>) of master_r_out_t; + type axi_r_slaves_out_t is array (natural range <>) of slave_r_out_t; + type axi_r_slaves_in_t is array (natural range <>) of slave_r_in_t; +end package axi_r_router_pkg; + +-- package body axi_r_router_pkg is +-- end package body axi_r_router_pkg;