ar router, aw router fixed
This commit is contained in:
parent
cc9223d089
commit
d272ed687b
80
src/axi3-interconnect-ar-router.vhd
Normal file
80
src/axi3-interconnect-ar-router.vhd
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
use work.axi3intercon_pkg.all;
|
||||||
|
use work.axi_ar_router_pkg.all;
|
||||||
|
|
||||||
|
entity axi3intercon_ar_router is
|
||||||
|
port(
|
||||||
|
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
|
||||||
|
alias clk is aclk;
|
||||||
|
type ar_state_t is (AR_READY, AR_ACTIVE);
|
||||||
|
type ar_states_t is array (0 to MASTER_COUNT - 1) of ar_state_t;
|
||||||
|
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;
|
||||||
|
begin
|
||||||
|
arready_gen : for i in 0 to MASTER_COUNT - 1 generate
|
||||||
|
masters_in(i).arready <= arready_s(i);
|
||||||
|
end generate arready_gen;
|
||||||
|
|
||||||
|
ar_router : process(clk, rst) is
|
||||||
|
variable slave_idx : slave_indexes_t;
|
||||||
|
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
|
||||||
|
ar_states(i) <= AR_READY;
|
||||||
|
|
||||||
|
end loop;
|
||||||
|
slave_in_use := (others => '0');
|
||||||
|
arready_s <= (others => '1');
|
||||||
|
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
|
||||||
|
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';
|
||||||
|
-- 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 - 1)) & 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)).arvalid <= '1';
|
||||||
|
ar_states(i) <= AR_ACTIVE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when AR_ACTIVE =>
|
||||||
|
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';
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
end process ar_router;
|
||||||
|
|
||||||
|
end architecture RTL;
|
14
src/axi3-interconnect-ar-router_pkg.vhd
Normal file
14
src/axi3-interconnect-ar-router_pkg.vhd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use work.axi3intercon_pkg.all;
|
||||||
|
|
||||||
|
package axi_ar_router_pkg is
|
||||||
|
type axi_ar_masters_in_t is array (natural range <>) of master_ar_in_t;
|
||||||
|
type axi_ar_masters_out_t is array (natural range <>) of master_ar_out_t;
|
||||||
|
type axi_ar_slaves_out_t is array (natural range <>) of slave_ar_out_t;
|
||||||
|
type axi_ar_slaves_in_t is array (natural range <>) of slave_ar_in_t;
|
||||||
|
end package axi_ar_router_pkg;
|
||||||
|
|
||||||
|
-- package body filename is
|
||||||
|
-- end package body filename;
|
@ -32,46 +32,49 @@ begin
|
|||||||
aw_router : process(clk, rst) is
|
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);
|
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
|
-- procedure calculate_slave(address : in std_logic_vector(ADDRESS_BITS - 1 downto 0)) is
|
||||||
begin
|
-- begin
|
||||||
slave_idx := SLAVE_COUNT;
|
-- slave_idx := SLAVE_COUNT;
|
||||||
for i in 0 to SLAVE_COUNT - 1 loop
|
-- for i in 0 to SLAVE_COUNT - 1 loop
|
||||||
if (address and mask_array(i)) = address_array(i) then
|
-- if (address and mask_array(i)) = address_array(i) then
|
||||||
slave_idx := i;
|
-- slave_idx := i;
|
||||||
end if;
|
-- end if;
|
||||||
end loop;
|
-- end loop;
|
||||||
|
--
|
||||||
end procedure calculate_slave;
|
-- end procedure calculate_slave;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
for i in 0 to MASTER_COUNT - 1 loop
|
for i in 0 to MASTER_COUNT - 1 loop
|
||||||
aw_states(i) <= AW_READY;
|
aw_states(i) <= AW_READY;
|
||||||
masters_in(i).awready <= '1';
|
masters_in(i).awready <= '1';
|
||||||
|
slave_in_use := (others => '0');
|
||||||
end loop;
|
end loop;
|
||||||
elsif rising_edge(clk) then
|
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
|
case aw_states(i) is
|
||||||
when AW_READY =>
|
when AW_READY =>
|
||||||
masters_in(i).awready <= '1';
|
masters_in(i).awready <= '1';
|
||||||
if masters_out(i).awvalid = '1' and masters_in(i).awready = '1' and slave_in_use(i) = '0' then -- check awready. just to prevent glitches
|
if masters_out(i).awvalid = '1' and masters_in(i).awready = '1' then -- check awready. just to prevent glitches
|
||||||
calculate_slave(masters_out(i).awaddr);
|
slave_idx := calculate_slave(masters_out(i).awaddr, address_array, mask_array);
|
||||||
write_locks_s(i).slave_idx <= slave_idx;
|
if slave_in_use(slave_idx) /= '1' then
|
||||||
write_locks_s(i).locked <= '1';
|
write_locks_s(i).slave_idx <= slave_idx;
|
||||||
slave_in_use(slave_idx) := '1';
|
write_locks_s(i).locked <= '1';
|
||||||
masters_in(i).awready <= '0';
|
slave_in_use(slave_idx) := '1';
|
||||||
-- output request to slave
|
masters_in(i).awready <= '0';
|
||||||
slaves_in(slave_idx).awaddr <= masters_out(i).awaddr;
|
-- output request to slave
|
||||||
slaves_in(slave_idx).awid <= std_logic_vector(to_unsigned(i, WID_SLAVE_BITS - WID_MASTER_BITS - 1)) & masters_out(i).awid;
|
slaves_in(slave_idx).awaddr <= masters_out(i).awaddr;
|
||||||
slaves_in(slave_idx).awburst <= masters_out(i).awburst;
|
slaves_in(slave_idx).awid <= std_logic_vector(to_unsigned(i, WID_SLAVE_BITS - WID_MASTER_BITS - 1)) & masters_out(i).awid;
|
||||||
slaves_in(slave_idx).awcache <= masters_out(i).awcache;
|
slaves_in(slave_idx).awburst <= masters_out(i).awburst;
|
||||||
slaves_in(slave_idx).awlen <= masters_out(i).awlen;
|
slaves_in(slave_idx).awcache <= masters_out(i).awcache;
|
||||||
slaves_in(slave_idx).awlock <= masters_out(i).awlock;
|
slaves_in(slave_idx).awlen <= masters_out(i).awlen;
|
||||||
slaves_in(slave_idx).awprot <= masters_out(i).awprot;
|
slaves_in(slave_idx).awlock <= masters_out(i).awlock;
|
||||||
slaves_in(slave_idx).awsize <= masters_out(i).awsize;
|
slaves_in(slave_idx).awprot <= masters_out(i).awprot;
|
||||||
slaves_in(slave_idx).awvalid <= '1';
|
slaves_in(slave_idx).awsize <= masters_out(i).awsize;
|
||||||
-- Active state waits for awready to be asserted
|
slaves_in(slave_idx).awvalid <= '1';
|
||||||
aw_states(i) <= AW_ACTIVE;
|
-- Active state waits for awready to be asserted
|
||||||
|
aw_states(i) <= AW_ACTIVE;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when AW_ACTIVE =>
|
when AW_ACTIVE =>
|
||||||
if slaves_out(write_locks_s(i).slave_idx).awready = '1' then
|
if slaves_out(write_locks_s(i).slave_idx).awready = '1' then
|
||||||
@ -81,8 +84,8 @@ begin
|
|||||||
when AW_BLOCK =>
|
when AW_BLOCK =>
|
||||||
if write_releases(i) = '1' then
|
if write_releases(i) = '1' then
|
||||||
slave_in_use(write_locks_s(i).slave_idx) := '0';
|
slave_in_use(write_locks_s(i).slave_idx) := '0';
|
||||||
write_locks_s(i).locked <= '0';
|
write_locks_s(i).locked <= '0';
|
||||||
aw_states(i) <= AW_READY;
|
aw_states(i) <= AW_READY;
|
||||||
end if;
|
end if;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use ieee.numeric_std.all;
|
|||||||
-- "work" denotes the curent library. Similar to this in C++, C# etc...
|
-- "work" denotes the curent library. Similar to this in C++, C# etc...
|
||||||
use work.axi3intercon_pkg.all;
|
use work.axi3intercon_pkg.all;
|
||||||
use work.axi_aw_router_pkg.all;
|
use work.axi_aw_router_pkg.all;
|
||||||
|
use work.axi_ar_router_pkg.all;
|
||||||
|
|
||||||
entity axi3intercon is
|
entity axi3intercon is
|
||||||
port(
|
port(
|
||||||
|
@ -88,7 +88,7 @@ package axi3intercon_pkg is
|
|||||||
end record master_ar_out_t;
|
end record master_ar_out_t;
|
||||||
|
|
||||||
type master_ar_in_t is record
|
type master_ar_in_t is record
|
||||||
awready : std_logic;
|
arready : std_logic;
|
||||||
end record master_ar_in_t;
|
end record master_ar_in_t;
|
||||||
|
|
||||||
type slave_ar_in_t is record
|
type slave_ar_in_t is record
|
||||||
@ -103,7 +103,7 @@ package axi3intercon_pkg is
|
|||||||
arvalid : std_logic; -- Data valid
|
arvalid : std_logic; -- Data valid
|
||||||
end record slave_ar_in_t;
|
end record slave_ar_in_t;
|
||||||
|
|
||||||
subtype slave_ar_out is master_ar_in_t;
|
subtype slave_ar_out_t is master_ar_in_t;
|
||||||
|
|
||||||
-- type decalarations for W channel
|
-- type decalarations for W channel
|
||||||
type master_w_out_t is record
|
type master_w_out_t is record
|
||||||
@ -128,7 +128,7 @@ package axi3intercon_pkg is
|
|||||||
wready : std_logic;
|
wready : std_logic;
|
||||||
end record master_w_in_t;
|
end record master_w_in_t;
|
||||||
|
|
||||||
subtype slave_w_out is master_w_in_t;
|
subtype slave_w_out_t is master_w_in_t;
|
||||||
|
|
||||||
-- Type declarations for R channel
|
-- Type declarations for R channel
|
||||||
type master_r_in_t is record
|
type master_r_in_t is record
|
||||||
@ -204,8 +204,8 @@ package axi3intercon_pkg is
|
|||||||
|
|
||||||
type axi_slave_out_t is record
|
type axi_slave_out_t is record
|
||||||
aw : slave_aw_out_t;
|
aw : slave_aw_out_t;
|
||||||
ar : slave_ar_out;
|
ar : slave_ar_out_t;
|
||||||
w : slave_w_out;
|
w : slave_w_out_t;
|
||||||
r : slave_r_out_t;
|
r : slave_r_out_t;
|
||||||
b : slave_b_out_t;
|
b : slave_b_out_t;
|
||||||
end record axi_slave_out_t;
|
end record axi_slave_out_t;
|
||||||
@ -219,7 +219,23 @@ package axi3intercon_pkg is
|
|||||||
-- Address translation mapping
|
-- Address translation mapping
|
||||||
type axi_slave_addresses_t is array (natural range <>) of std_logic_vector(ADDRESS_BITS - 1 downto 0);
|
type axi_slave_addresses_t is array (natural range <>) of std_logic_vector(ADDRESS_BITS - 1 downto 0);
|
||||||
|
|
||||||
|
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;
|
end package axi3intercon_pkg;
|
||||||
|
|
||||||
-- package body axi3intercon_pkg is
|
package body axi3intercon_pkg is
|
||||||
-- end package body axi3intercon_pkg;
|
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 is
|
||||||
|
variable slave_idx : integer range 0 to SLAVE_COUNT := SLAVE_COUNT;
|
||||||
|
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;
|
||||||
|
return slave_idx;
|
||||||
|
end function calculate_slave;
|
||||||
|
end package body axi3intercon_pkg;
|
||||||
|
Loading…
Reference in New Issue
Block a user