ar router, aw router fixed

This commit is contained in:
Mario Hüttel 2016-08-21 20:44:06 +02:00
parent cc9223d089
commit d272ed687b
5 changed files with 151 additions and 37 deletions

View 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;

View 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;

View File

@ -32,30 +32,32 @@ 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);
if slave_in_use(slave_idx) /= '1' then
write_locks_s(i).slave_idx <= slave_idx; write_locks_s(i).slave_idx <= slave_idx;
write_locks_s(i).locked <= '1'; write_locks_s(i).locked <= '1';
slave_in_use(slave_idx) := '1'; slave_in_use(slave_idx) := '1';
@ -73,6 +75,7 @@ begin
-- Active state waits for awready to be asserted -- Active state waits for awready to be asserted
aw_states(i) <= AW_ACTIVE; 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
slaves_in(write_locks_s(i).slave_idx).awvalid <= '0'; slaves_in(write_locks_s(i).slave_idx).awvalid <= '0';

View File

@ -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(

View File

@ -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;