Compare commits

...

2 commits

Author SHA1 Message Date
Retrocamara42
25b49e9832 feat: arbiter component created 2025-05-18 04:17:49 -05:00
Retrocamara42
1f479ff452 fix: ack signals removed, router tb added 2025-05-15 06:40:41 -05:00
10 changed files with 386 additions and 502 deletions

163
arbiter.vhdl Normal file
View file

@ -0,0 +1,163 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.router_types.all;
use work.routing_functions.all;
entity arbiter is
generic(
level : integer := 1;
num_paths_up : integer := 1;
num_paths_down : integer := 1
);
port (
rout_pos : in t_pos_addr;
packets : in t_DATA(num_paths_up+num_paths_down*4-1 downto 0);
avai_paths : in std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0);
data_out : out t_DATA(num_paths_up+num_paths_down*4-1 downto 0);
wr_req : out std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0)
);
end arbiter;
architecture impl of arbiter is
constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4;
signal dirs : t_DATA_DIRS(TOT_NUM_PATHS-1 downto 0);
signal ps_dirs : t_DATA_DIRS(TOT_NUM_PATHS-1 downto 0);
signal avai_pos : t_AVAI_POS(TOT_NUM_PATHS-1 downto 0);
begin
get_rout_dir: process(rout_pos, packets)
variable pack_dest : t_pos_addr;
variable header : std_logic_vector(3 downto 0);
begin
for i in 0 to packets'length-1 loop
header := packets(i)(63 downto 60);
if header /= "0000" then
pack_dest.chip_x := packets(i)(59 downto 55);
pack_dest.chip_y := packets(i)(54 downto 50);
pack_dest.core_x := packets(i)(49 downto 45);
pack_dest.core_y := packets(i)(44 downto 40);
pack_dest.copy_x := packets(i)(39 downto 35);
pack_dest.copy_y := packets(i)(34 downto 30);
dirs(i) <= single_packet_rout_dir_det(level, pack_dest, rout_pos);
else
dirs(i) <= (others => '0');
end if;
end loop;
end process;
rout_path_determination: process(packets, dirs, avai_paths)
variable sum_dirs : integer;
variable n_j : integer;
variable avai_path : std_logic;
variable avai_pos_sizes : t_AVAI_POS_SIZES;
begin
avai_pos_sizes := (others => 0);
-- find available paths and n_j (avai pos sizes)
for i in 0 to TOT_NUM_PATHS loop
avai_path := avai_paths(i);
if i < num_paths_up then
if avai_path = '1' then
avai_pos(avai_pos_sizes(0)) <= i;
avai_pos_sizes(0) := avai_pos_sizes(0) + 1;
end if;
elsif i < num_paths_up + num_paths_down then
if avai_path = '1' then
avai_pos(avai_pos_sizes(1)) <= i;
avai_pos_sizes(1) := avai_pos_sizes(1) + 1;
end if;
elsif i < num_paths_up + num_paths_down*2 then
if avai_path = '1' then
avai_pos(avai_pos_sizes(2)) <= i;
avai_pos_sizes(2) := avai_pos_sizes(2) + 1;
end if;
elsif i < num_paths_up + num_paths_down*3 then
if avai_path = '1' then
avai_pos(avai_pos_sizes(3)) <= i;
avai_pos_sizes(3) := avai_pos_sizes(3) + 1;
end if;
else
if avai_path = '1' then
avai_pos(avai_pos_sizes(4)) <= i;
avai_pos_sizes(4) := avai_pos_sizes(4) + 1;
end if;
end if;
end loop;
-- set rout_dirs to 0 when no more avai_pos (avai_pos_sizes(i) = 0)
for i in 0 to TOT_NUM_PATHS-1 loop
if dirs(i) /= (others => '0') then
sum_dirs := 0;
for j in 0 to NUM_DIRS loop
sum_dirs := sum_dirs + to_integer(unsigned(dirs(j)));
end loop;
-- unicast
if sum_dirs = 1 then
if dirs(i)(0) = '1' then
n_j := avai_pos_sizes(0);
avai_pos_sizes(0) := avai_pos_sizes(0)-1;
elsif dirs(i)(1) = '1' then
n_j := avai_pos_sizes(1);
avai_pos_sizes(1) := avai_pos_sizes(1)-1;
elsif dirs(i)(2) = '1' then
n_j := avai_pos_sizes(2);
avai_pos_sizes(2) := avai_pos_sizes(2)-1;
elsif dirs(i)(3) = '1' then
n_j := avai_pos_sizes(3);
avai_pos_sizes(3) := avai_pos_sizes(3)-1;
elsif dirs(i)(4) = '1' then
n_j := avai_pos_sizes(4);
avai_pos_sizes(4) := avai_pos_sizes(4)-1;
end if;
if n_j <= 0 then
ps_dirs(i) <= (others => '0');
end if;
-- 1 to 2 multicast
elsif sum_dirs = 2 then
if dirs(i)(2) = '1' and dirs(i)(4) = '1' then
if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then
ps_dirs(i) <= (others => '0');
end if;
elsif dirs(i)(1) = '1' and dirs(i)(3) = '1' then
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then
ps_dirs(i) <= (others => '0');
end if;
elsif dirs(i)(3) = '1' and dirs(i)(4) = '1' then
if avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then
ps_dirs(i) <= (others => '0');
end if;
elsif dirs(i)(1) = '1' and dirs(i)(2) = '1' then
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 then
ps_dirs(i) <= (others => '0');
end if;
end if;
-- 1 to 4 multicast
else
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 or
avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then
ps_dirs(i) <= (others => '0');
end if;
end if;
end if;
end loop;
end process;
set_out_buffer: process(dirs, packets, avai_pos)
variable path_index, out_index : integer;
begin
data_out <= (others => (others => '0'));
wr_req <= (others => '0');
for j in 0 to NUM_DIRS loop
path_index := 0;
for i in 0 to TOT_NUM_PATHS-1 loop
if dirs(i)(j)='1' then
out_index := retrieve_avai_path_index(j, path_index,
num_paths_up, num_paths_down, avai_pos);
path_index := path_index + 1;
data_out(out_index) <= packets(i);
wr_req(out_index) <= '1';
end if;
end loop;
end loop;
end process;
end impl;

View file

@ -7,11 +7,11 @@ entity fifo is
generic ( generic (
WIDTH : integer := 32; WIDTH : integer := 32;
DEPTH : integer := 8; DEPTH : integer := 8;
F_PTR_SIZE : integer := 4 F_PTR_SIZE : integer := 4
); );
port( port(
arstN, clk, wr_req, rd_req : in std_logic; arstN, clk, wr_req, rd_req : in std_logic;
wr_ack, rd_ack, full, empty : out std_logic; full, empty : out std_logic;
data_in : in std_logic_vector(WIDTH-1 downto 0); data_in : in std_logic_vector(WIDTH-1 downto 0);
data_out : out std_logic_vector(WIDTH-1 downto 0) data_out : out std_logic_vector(WIDTH-1 downto 0)
); );
@ -23,7 +23,6 @@ type T_FIFO is array (0 to DEPTH-1) of std_logic_vector(WIDTH-1 downto 0);
signal wr_ptr, rd_ptr : unsigned(F_PTR_SIZE-1 downto 0); signal wr_ptr, rd_ptr : unsigned(F_PTR_SIZE-1 downto 0);
signal wr_ptr_nxt, rd_ptr_nxt : unsigned(F_PTR_SIZE-1 downto 0); signal wr_ptr_nxt, rd_ptr_nxt : unsigned(F_PTR_SIZE-1 downto 0);
signal wr_ack_nxt, rd_ack_nxt : std_logic;
signal full_nxt, empty_nxt : std_logic; signal full_nxt, empty_nxt : std_logic;
signal data_out_nxt : std_logic_vector(WIDTH-1 downto 0); signal data_out_nxt : std_logic_vector(WIDTH-1 downto 0);
signal fifo, fifo_nxt : T_FIFO; signal fifo, fifo_nxt : T_FIFO;
@ -39,8 +38,6 @@ begin
fifo <= fifo_nxt; fifo <= fifo_nxt;
wr_ptr <= wr_ptr_nxt; wr_ptr <= wr_ptr_nxt;
rd_ptr <= rd_ptr_nxt; rd_ptr <= rd_ptr_nxt;
wr_ack <= wr_ack_nxt;
rd_ack <= rd_ack_nxt;
full <= full_nxt; full <= full_nxt;
empty <= empty_nxt; empty <= empty_nxt;
data_out <= data_out_nxt; data_out <= data_out_nxt;
@ -50,10 +47,8 @@ begin
update_wr_ptr: process(wr_req, full_nxt, wr_ptr) update_wr_ptr: process(wr_req, full_nxt, wr_ptr)
begin begin
if wr_req = '1' and full_nxt = '0' then if wr_req = '1' and full_nxt = '0' then
wr_ack_nxt <= '1';
wr_ptr_nxt <= wr_ptr + 1; wr_ptr_nxt <= wr_ptr + 1;
else else
wr_ack_nxt <= '0';
wr_ptr_nxt <= wr_ptr; wr_ptr_nxt <= wr_ptr;
end if; end if;
end process; end process;
@ -82,10 +77,8 @@ begin
update_rd_ptr: process(rd_req, empty_nxt, rd_ptr) update_rd_ptr: process(rd_req, empty_nxt, rd_ptr)
begin begin
if rd_req = '1' and empty_nxt = '0' then if rd_req = '1' and empty_nxt = '0' then
rd_ack_nxt <= '1';
rd_ptr_nxt <= rd_ptr + 1; rd_ptr_nxt <= rd_ptr + 1;
else else
rd_ack_nxt <= '0';
rd_ptr_nxt <= rd_ptr; rd_ptr_nxt <= rd_ptr;
end if; end if;
end process; end process;

View file

@ -1,56 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity input_buffer is
generic (
WIDTH: integer := 32;
DEPTH: integer := 8
);
port (
rstN, clk, wr_req : in std_logic;
data_valid : inout std_logic;
wr_ack, full : out std_logic;
data_in : in std_logic_vector(WIDTH-1 downto 0);
data_out : out std_logic_vector(WIDTH-1 downto 0)
);
end input_buffer;
architecture impl of input_buffer is
component fifo is
generic (
WIDTH: integer;
DEPTH: integer
);
port(
rstN, clk, wr_req, rd_req, only_peek : in std_logic;
wr_ack, rd_ack, full, empty : out std_logic;
data_in : in std_logic_vector(WIDTH-1 downto 0);
data_out : out std_logic_vector(WIDTH-1 downto 0)
);
end component fifo;
signal rd_req, rd_ack, empty, only_peek : std_logic;
begin
fifo_us: fifo
generic map(WIDTH => WIDTH, DEPTH => DEPTH)
port map(rstN => rstN, clk => clk, wr_req => wr_req, wr_ack => wr_ack,
rd_req => rd_req, rd_ack => rd_ack, data_in => data_in,
data_out => data_out, full => full, empty => empty,
only_peek => only_peek);
start_read: process(empty, data_valid)
begin
if empty = '0' and data_valid = '0' then
rd_req <= '1'; -- read from fifo
end if;
end process;
read: process(rd_ack)
begin
if rd_ack = '1' then
rd_req <= '0';
data_valid <= '1';
end if;
end process;
end impl;

View file

@ -10,109 +10,96 @@ entity router is
generic ( generic (
num_paths_up : integer := 1; num_paths_up : integer := 1;
num_paths_down : integer := 1; num_paths_down : integer := 1;
rd_data_b_size : integer := 3;
level : integer := 1; level : integer := 1;
buffer_width : integer := 64; buffer_width : integer := 64;
buffer_depth : integer := 4; buffer_depth : integer := 4;
val_chip_r_x : integer := 0; chip_x : std_logic_vector(4 downto 0);
val_chip_r_y : integer := 0; chip_y : std_logic_vecto_nxtr(4 downto 0)
val_core_r_x : integer := 0;
val_core_r_y : integer := 0
); );
port ( port (
clk : in std_logic; clk : in std_logic;
rstN : in std_logic; arstN : in std_logic;
buffers_in : inout t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0); rcv_buffers_in : in t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0);
buffers_out : inout t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0) snd_buffers_out : out t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0)
); );
end router; end router;
architecture impl of router is architecture impl of router is
constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4; constant TOT_NUM_PATHS : positive := num_paths_up + num_paths_down*4;
signal chip_r_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); signal rcv_buffers_out : t_PORT_OUT(TOT_NUM_PATHS-1 downto 0);
signal chip_r_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); signal snd_buffers_in : t_PORT_IN(TOT_NUM_PATHS-1 downto 0);
signal core_r_x : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); --signal snd_buffers_in_nxt : t_PORT_IN(TOT_NUM_PATHS-1 downto 0);
signal core_r_y : std_logic_vector(DEST_ADDR_SIZE-level-1 downto 0); signal rout_pos : t_pos_addr;
signal rd_data, rd_data_nxt : t_DATA(TOT_NUM_PATHS downto 0); signal read_data, data_to_send : t_DATA(TOT_NUM_PATHS-1 downto 0);
signal rd_data_valid : t_DATA_VAL(TOT_NUM_PATHS downto 0); signal wr_reqs : std_logic_vector(TOT_NUM_PATHS-1 downto 0);
signal avai_paths : t_PATHS(TOT_NUM_PATHS downto 0); signal avai_paths : std_logic_vector(TOT_NUM_PATHS-1 downto 0);
signal out_buff_if : t_PORT_IN(TOT_NUM_PATHS-1 downto 0);
begin begin
-- implements all buffers for each path
g_IN_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate g_IN_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate
input_buffer_x: input_buffer input_fifo: fifo
generic map(WIDTH => buffer_width, DEPTH => buffer_depth) generic map(WIDTH => buffer_width, DEPTH => buffer_depth)
port map(rstN => rstN, clk => clk, wr_req => buffers_in(i).req, port map(arstN => arstN, clk => clk, wr_req => rcv_buffers_in(i).wr_req,
wr_ack => buffers_in(i).ack, full => buffers_in(i).full, rd_req => not rcv_buffers_out(i).empty,
data_valid => rd_data_valid(i), data_in => buffers_in(i).data_in, data_in => rcv_buffers_in(i).data,
data_out => rd_data_nxt(i)); data_out => rcv_buffers_out(i).data,
full => rcv_buffers_out(i).full, empty => rcv_buffers_out(i).empty);
end generate; end generate;
g_OUT_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate g_OUT_BUFF_GEN: for i in 0 to TOT_NUM_PATHS-1 generate
output_fifo: fifo output_fifo: fifo
generic map(WIDTH => buffer_width, DEPTH => buffer_depth) generic map(WIDTH => buffer_width, DEPTH => buffer_depth)
port map(rstN => rstN, clk => clk, wr_req => out_buff_if(i).req, port map(arstN => arstN, clk => clk, wr_req => snd_buffers_in(i).wr_req,
wr_ack => out_buff_if(i).ack, rd_req => buffers_out(i).req, rd_req => snd_buffers_in(i).rd_req, data_in => snd_buffers_in(i).data,
rd_ack => buffers_out(i).ack, data_in => out_buff_if(i).data_in, data_out => snd_buffers_out(i).data, full => snd_buffers_out(i).full,
data_out => buffers_out(i).data_out, full => out_buff_if(i).full, empty => snd_buffers_out(i).empty);
empty => buffers_out(i).empty,
only_peek => out_buff_if(i).only_peek);
end generate; end generate;
set_avai_paths: process(out_buff_if) arbiter0: arbiter
variable ds_ind : integer; generic map(
variable dir : positive; level => level,
num_paths_up=>num_paths_up,
num_paths_down=>num_paths_down
)
port map(
rout_pos => rout_pos,
packets => read_data,
avai_paths => avai_paths,
data_out => data_to_send,
wr_req => wr_reqs
);
set_read_data: process(rcv_buffers_out)
begin begin
for i in 0 to TOT_NUM_PATHS-1 loop for i in 0 to TOT_NUM_PATHS-1 loop
if i < num_paths_up then read_data(i) <= rcv_buffers_out(i).data;
avai_paths(i)(0) <= not out_buff_if(i).full;
elsif i < num_paths_up + num_paths_down then
ds_ind := i - num_paths_up;
avai_paths(i)(1) <= not out_buff_if(i).full;
elsif i < num_paths_up + num_paths_down*2 then
ds_ind := i - num_paths_up - num_paths_down;
avai_paths(i)(2) <= not out_buff_if(i).full;
elsif i < num_paths_up + num_paths_down*3 then
ds_ind := i - num_paths_up - num_paths_down*2;
avai_paths(i)(3) <= not out_buff_if(i).full;
else
ds_ind := i - num_paths_up - num_paths_down*3;
avai_paths(i)(4) <= not out_buff_if(i).full;
end if;
end loop; end loop;
end process; end process;
end_wr_req: process(out_buff_if) set_avai_paths: process(snd_buffers_out)
begin begin
for i in 0 to TOT_NUM_PATHS-1 loop for i in 0 to TOT_NUM_PATHS-1 loop
if out_buff_if(i).ack = '1' then avai_paths(i) <= not snd_buffers_out(i).full;
out_buff_if(i).req <= '0';
end if;
end loop; end loop;
end process; end process;
switching: process(rstN, clk) set_snd_buffers_in: process(wr_reqs, data_to_send)
variable rout_dirs : t_DATA_DIRS(tot_num_paths-1 downto 0);
variable avai_pos : t_AVAI_POS(tot_num_paths-1 downto 0);
variable path_index, out_index : integer;
begin begin
if rstN = '0' then for i in 0 to TOT_NUM_PATHS-1 loop
rd_data <= (others => (others => '0')); snd_buffers_in(i).wr_req <= wr_reqs(i);
rd_data_valid <= (others => '0'); snd_buffers_in(i).data <= data_to_send(i);
chip_r_x <= std_logic_vector(to_unsigned( end loop;
val_chip_r_x, chip_r_x'length)); end process;
chip_r_y <= std_logic_vector(to_unsigned(
val_chip_r_y, chip_r_y'length)); switching: process(arstN, clk)
core_r_x <= std_logic_vector(to_unsigned( begin
val_core_r_x, core_r_x'length)); if arstN = '0' then
core_r_y <= std_logic_vector(to_unsigned( rout_pos.chip_x <= chip_x;
val_core_r_y, core_r_y'length)); rout_pos.chip_y <= chip_y;
elsif rising_edge(clk) then rout_pos.core_x <= core_x;
rd_data <= rd_data_nxt; rout_pos.core_y <= core_y;
routing(level, rd_data, rd_data_valid, chip_r_x, chip_r_y, core_r_x, --elsif rising_edge(clk) then
core_r_y, avai_paths, num_paths_up, num_paths_down, out_buff_if); -- snd_buffers_in <= snd_buffers_in_nxt;
end if; end if;
end process; end process;
end impl; end impl;

View file

@ -1,6 +1,7 @@
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use work.router_types.all;
package router_components is package router_components is
component fifo is component fifo is
@ -9,24 +10,25 @@ package router_components is
DEPTH: integer DEPTH: integer
); );
port( port(
rstN, clk, wr_req, rd_req, only_peek : in std_logic; arstN, clk, wr_req, rd_req : in std_logic;
wr_ack, rd_ack, full, empty : out std_logic; full, empty : out std_logic;
data_in : in std_logic_vector(WIDTH-1 downto 0); data_in : in std_logic_vector(WIDTH-1 downto 0);
data_out : out std_logic_vector(WIDTH-1 downto 0) data_out : out std_logic_vector(WIDTH-1 downto 0)
); );
end component fifo; end component fifo;
component input_buffer is component arbiter is
generic ( generic(
WIDTH: integer; level : integer := 1;
DEPTH: integer num_paths_up : integer := 1;
num_paths_down : integer := 1
); );
port( port (
rstN, clk, wr_req : in std_logic; rout_pos : in t_pos_addr;
data_valid : inout std_logic; packets : in t_DATA(num_paths_up+num_paths_down*4-1 downto 0);
wr_ack, full : out std_logic; avai_paths : in std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0);
data_in : in std_logic_vector(WIDTH-1 downto 0); data_out : out t_DATA(num_paths_up+num_paths_down*4-1 downto 0);
data_out : out std_logic_vector(WIDTH-1 downto 0) wr_req : out std_logic_vector(num_paths_up+num_paths_down*4-1 downto 0)
); );
end component input_buffer; end component arbiter;
end package; end package;

View file

@ -1,32 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.router_types.all;
entity router_tb is
end router_tb;
architecture impl of router_tb is
component router is
generic (
num_paths_up : integer;
num_paths_down : integer;
rd_data_b_size : integer;
level : integer;
buffer_width : integer;
buffer_depth : integer;
val_chip_r_x : integer;
val_chip_r_y : integer;
val_core_r_x : integer;
val_core_r_y : integer
);
port (
clk : in std_logic;
rstN : in std_logic;
buffers_in : inout t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0);
buffers_out : inout t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0)
);
end component;
begin
end impl;

View file

@ -11,40 +11,35 @@ package router_types is
constant CHIP_ADDR_SIZE : integer := 5; -- * constant CHIP_ADDR_SIZE : integer := 5; -- *
subtype WORD is std_logic_vector(63 downto 0); subtype WORD is std_logic_vector(63 downto 0);
type t_PATHS is array (integer range <>) of type t_PATHS is array (integer range <>) of
std_logic_vector(NUM_DIRS-1 downto 0); std_logic_vector(NUM_DIRS-1 downto 0);
type t_AVAI_POS is array (integer range <>) of type t_AVAI_POS is array(integer range <>) of integer;
std_logic_vector(AV_POS_SIZE-1 downto 0); type t_AVAI_POS_SIZES is array(NUM_DIRS-1 downto 0) of integer;
type t_AVAI_POS_SIZ is array (NUM_DIRS-1 downto 0) of integer;
type t_fifo_in is record type t_fifo_in is record
data_in : WORD; data : WORD;
req : std_logic; wr_req : std_logic;
ack : std_logic; rd_req : std_logic;
full : std_logic;
only_peek : std_logic;
end record; end record;
type t_fifo_out is record type t_fifo_out is record
data_out : WORD; data : WORD;
req : std_logic;
ack : std_logic;
empty : std_logic; empty : std_logic;
full : std_logic;
end record; end record;
type t_dest_addr is record type t_pos_addr is record
chip_d_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); chip_x : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
chip_d_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); chip_y : std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_d_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); core_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0);
core_d_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); core_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0);
copy_d_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); copy_x : std_logic_vector(DEST_ADDR_SIZE-1 downto 0);
copy_d_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0); copy_y : std_logic_vector(DEST_ADDR_SIZE-1 downto 0);
end record; end record;
type t_PORT_IN is array (integer range <>) of t_fifo_in; type t_PORT_IN is array (integer range <>) of t_fifo_in;
type t_PORT_OUT is array (integer range <>) of t_fifo_out; type t_PORT_OUT is array (integer range <>) of t_fifo_out;
type t_DATA is array (integer range <>) of WORD; type t_DATA is array (integer range <>) of WORD;
type t_DATA_VAL is array (integer range <>) of std_logic;
type t_DATA_DIRS is array (integer range <>) of type t_DATA_DIRS is array (integer range <>) of
std_logic_vector(NUM_DIRS-1 downto 0); std_logic_vector(NUM_DIRS-1 downto 0);
end package; end package;

View file

@ -6,49 +6,11 @@ use work.router_types.all;
package routing_functions is package routing_functions is
function single_packet_rout_dir_det ( function single_packet_rout_dir_det (
level : in positive; level : in positive;
dest : in t_dest_addr; pack_dest : in t_pos_addr;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); rout_pos : in t_pos_addr
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector
) return std_logic_vector; ) return std_logic_vector;
procedure rout_dir_determination (
level : in positive;
read_data : in t_DATA;
read_data_valid : in t_DATA_VAL;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector;
rout_dirs : out t_DATA_DIRS
);
procedure rout_path_determination (
read_data : in t_DATA; -- stored in buffers
read_data_valid : in t_DATA_VAL;
rout_dirs : inout t_DATA_DIRS; -- got from routing function
paths : in t_PATHS;
num_paths_up : in positive;
num_paths_down : in positive;
avai_pos : out t_AVAI_POS
);
procedure routing (
level : in positive;
read_data : in t_DATA;
read_data_valid : in t_DATA_VAL;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector;
paths : in t_PATHS;
num_paths_up : in positive;
num_paths_down : in positive;
signal out_buff_if : out t_PORT_IN
);
function retrieve_avai_path_index ( function retrieve_avai_path_index (
dir : in positive; dir : in positive;
path_index : in integer; path_index : in integer;
@ -56,283 +18,79 @@ package routing_functions is
num_paths_down : in positive; num_paths_down : in positive;
avai_pos : in t_AVAI_POS avai_pos : in t_AVAI_POS
) return integer; ) return integer;
procedure set_out_buffer (
num_paths_up, num_paths_down : in integer;
rd_data : in t_DATA;
rd_data_valid : in t_DATA_VAL;
rout_dirs : in t_DATA_DIRS;
avai_pos : in t_AVAI_POS;
signal out_buff_if : out t_PORT_IN
);
end package; end package;
package body routing_functions is package body routing_functions is
function single_packet_rout_dir_det ( function single_packet_rout_dir_det (
level : in positive; level : in positive;
dest : in t_dest_addr; pack_dest : in t_pos_addr;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0); rout_pos : in t_pos_addr
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector
) return std_logic_vector is ) return std_logic_vector is
variable dest_x, dest_y, copy_x, copy_y : std_logic; variable dest_x, dest_y, copy_x, copy_y : std_logic;
variable is_other_chip, is_cousin_core : boolean; variable is_other_chip, is_cousin_core : boolean;
begin begin
dest_x := dest.core_d_x(level-1); dest_x := pack_dest.core_x(level-1);
dest_y := dest.core_d_y(level-1); dest_y := pack_dest.core_y(level-1);
copy_x := dest.copy_d_x(level-1); copy_x := pack_dest.copy_x(level-1);
copy_y := dest.copy_d_y(level-1); copy_y := pack_dest.copy_y(level-1);
is_other_chip := dest.chip_d_x /= chip_r_x or dest.chip_d_y /= chip_r_y; is_other_chip := pack_dest.chip_x /= rout_pos.chip_x or
is_cousin_core := pack_dest.chip_y /= rout_pos.chip_y;
dest.core_d_x(DEST_ADDR_SIZE-1 downto level) /= core_r_x or is_cousin_core :=
dest.core_d_y(DEST_ADDR_SIZE-1 downto level) /= core_r_y; pack_dest.core_x(DEST_ADDR_SIZE-1 downto level) /= rout_pos.core_x or
pack_dest.core_y(DEST_ADDR_SIZE-1 downto level) /= rout_pos.core_y;
if is_other_chip or is_cousin_core then
return "10000"; if is_other_chip or is_cousin_core then
elsif copy_x = '0' and copy_y = '0' then --unicast return "10000";
if dest_x = '0' and dest_y = '0' then elsif copy_x = '0' and copy_y = '0' then --unicast
return "01000"; if dest_x = '0' and dest_y = '0' then
elsif dest_x = '0' and dest_y = '1' then return "01000";
return "00100"; elsif dest_x = '0' and dest_y = '1' then
elsif dest_x = '1' and dest_y = '0' then return "00100";
return "00010"; elsif dest_x = '1' and dest_y = '0' then
else return "00010";
return "00001";
end if;
elsif copy_x = '1' and copy_y = '0' then -- X 1 to 2 multicast
if dest_y = '0' then
return "01010";
else
return "00101";
end if;
elsif copy_x = '0' and copy_y = '1' then -- Y 1 to 2 multicast
if dest_x = '0' then
return "01100";
else
return "00011";
end if;
else -- 1 to 4 multicast
return "01111";
end if;
end function;
procedure rout_dir_determination (
level : in positive;
read_data : in t_DATA;
read_data_valid : in t_DATA_VAL;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector;
rout_dirs : out t_DATA_DIRS
) is
variable dest : t_dest_addr;
begin
for i in 0 to read_data'length-1 loop
if read_data_valid(i) = '1' then
dest.chip_d_x := read_data(i)(59 downto 55);
dest.chip_d_y := read_data(i)(54 downto 50);
dest.core_d_x := read_data(i)(49 downto 45);
dest.core_d_y := read_data(i)(44 downto 40);
dest.copy_d_x := read_data(i)(39 downto 35);
dest.copy_d_y := read_data(i)(34 downto 30);
rout_dirs(i) := single_packet_rout_dir_det (
level, dest, chip_r_x, chip_r_y, core_r_x, core_r_y);
else
rout_dirs(i) := (others => '0');
end if;
end loop;
end procedure;
procedure rout_path_determination (
read_data : in t_DATA;--(tot_num_paths); -- stored in buffers
read_data_valid : in t_DATA_VAL;
rout_dirs : inout t_DATA_DIRS;--(tot_num_paths); -- got from routing function
paths : in t_PATHS;
num_paths_up : in positive;
num_paths_down : in positive;
avai_pos : out t_AVAI_POS
) is
variable sum_dirs : integer;
variable num_paths : positive;
variable n_j : integer;
variable avai_path : std_logic_vector(NUM_DIRS-1 downto 0);
variable avai_pos_sizes : t_AVAI_POS_SIZ;
begin
num_paths := num_paths_up + num_paths_down*4;
avai_pos_sizes := (others => 0);
for i in 0 to num_paths loop
avai_path := paths(i);
if i < num_paths_up then
if avai_path(0) = '1' then
avai_pos(avai_pos_sizes(0)) :=
std_logic_vector(to_unsigned(i,AV_POS_SIZE));
avai_pos_sizes(0) := avai_pos_sizes(0) + 1;
end if;
elsif i < num_paths_up + num_paths_down then
if avai_path(1) = '1' then
avai_pos(avai_pos_sizes(1)) :=
std_logic_vector(to_unsigned(i,AV_POS_SIZE));
avai_pos_sizes(1) := avai_pos_sizes(1) + 1;
end if;
elsif i < num_paths_up + num_paths_down*2 then
if avai_path(2) = '1' then
avai_pos(avai_pos_sizes(2)) :=
std_logic_vector(to_unsigned(i,AV_POS_SIZE));
avai_pos_sizes(2) := avai_pos_sizes(2) + 1;
end if;
elsif i < num_paths_up + num_paths_down*3 then
if avai_path(3) = '1' then
avai_pos(avai_pos_sizes(3)) :=
std_logic_vector(to_unsigned(i,AV_POS_SIZE));
avai_pos_sizes(3) := avai_pos_sizes(3) + 1;
end if;
else
if avai_path(4) = '1' then
avai_pos(avai_pos_sizes(4)) :=
std_logic_vector(to_unsigned(i,AV_POS_SIZE));
avai_pos_sizes(4) := avai_pos_sizes(4) + 1;
end if;
end if;
end loop;
for i in 0 to read_data'length-1 loop
if read_data_valid(i) = '1' then
sum_dirs := 0;
for j in 0 to NUM_DIRS loop
sum_dirs := sum_dirs + to_integer(unsigned(rout_dirs(j)));
end loop;
-- unicast
if sum_dirs = 1 then
if rout_dirs(i)(0) = '1' then
n_j := avai_pos_sizes(0);
avai_pos_sizes(0) := avai_pos_sizes(0)-1;
elsif rout_dirs(i)(1) = '1' then
n_j := avai_pos_sizes(1);
avai_pos_sizes(1) := avai_pos_sizes(1)-1;
elsif rout_dirs(i)(2) = '1' then
n_j := avai_pos_sizes(2);
avai_pos_sizes(2) := avai_pos_sizes(2)-1;
elsif rout_dirs(i)(3) = '1' then
n_j := avai_pos_sizes(3);
avai_pos_sizes(3) := avai_pos_sizes(3)-1;
elsif rout_dirs(i)(4) = '1' then
n_j := avai_pos_sizes(4);
avai_pos_sizes(4) := avai_pos_sizes(4)-1;
end if;
if n_j <= 0 then
rout_dirs(i) := (others => '0');
end if;
-- 1 to 2 multicast
elsif sum_dirs = 2 then
if rout_dirs(i)(2) = '1' and rout_dirs(i)(4) = '1' then
if avai_pos_sizes(2) <= 0 or avai_pos_sizes(4) <= 0 then
rout_dirs(i) := (others => '0');
end if;
elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(3) = '1' then
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(3) <= 0 then
rout_dirs(i) := (others => '0');
end if;
elsif rout_dirs(i)(3) = '1' and rout_dirs(i)(4) = '1' then
if avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then
rout_dirs(i) := (others => '0');
end if;
elsif rout_dirs(i)(1) = '1' and rout_dirs(i)(2) = '1' then
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 then
rout_dirs(i) := (others => '0');
end if;
end if;
-- 1 to 4 multicast
else else
if avai_pos_sizes(1) <= 0 or avai_pos_sizes(2) <= 0 or return "00001";
avai_pos_sizes(3) <= 0 or avai_pos_sizes(4) <= 0 then
rout_dirs(i) := (others => '0');
end if;
end if; end if;
elsif copy_x = '1' and copy_y = '0' then -- X 1 to 2 multicast
if dest_y = '0' then
return "01010";
else
return "00101";
end if;
elsif copy_x = '0' and copy_y = '1' then -- Y 1 to 2 multicast
if dest_x = '0' then
return "01100";
else
return "00011";
end if;
else -- 1 to 4 multicast
return "01111";
end if; end if;
end loop; end function;
end procedure;
function retrieve_avai_path_index ( function retrieve_avai_path_index (
dir : in positive; dir : in positive;
path_index : in integer; path_index : in integer;
num_paths_up : in positive; num_paths_up : in positive;
num_paths_down : in positive; num_paths_down : in positive;
avai_pos : in t_AVAI_POS avai_pos : in t_AVAI_POS
) return integer is ) return integer is
variable avai_pos_index : integer; variable avai_pos_index : integer;
begin begin
if dir = 0 then if dir = 0 then
return to_integer(unsigned(avai_pos(path_index))); return avai_pos(path_index);
elsif dir = 1 then elsif dir = 1 then
avai_pos_index := path_index+num_paths_up; avai_pos_index := path_index+num_paths_up;
return to_integer(unsigned(avai_pos(avai_pos_index))); return avai_pos(avai_pos_index);
elsif dir = 2 then elsif dir = 2 then
avai_pos_index := path_index+num_paths_up+num_paths_down; avai_pos_index := path_index+num_paths_up+num_paths_down;
return to_integer(unsigned(avai_pos(avai_pos_index))); return avai_pos(avai_pos_index);
elsif dir = 3 then elsif dir = 3 then
avai_pos_index := path_index+num_paths_up+num_paths_down*2; avai_pos_index := path_index+num_paths_up+num_paths_down*2;
return to_integer(unsigned(avai_pos(avai_pos_index))); return avai_pos(avai_pos_index);
else else
avai_pos_index := path_index+num_paths_up+num_paths_down*3; avai_pos_index := path_index+num_paths_up+num_paths_down*3;
return to_integer(unsigned(avai_pos(avai_pos_index))); return avai_pos(avai_pos_index);
end if; end if;
end retrieve_avai_path_index; end retrieve_avai_path_index;
procedure set_out_buffer (
num_paths_up, num_paths_down : in integer;
rd_data : in t_DATA;
rd_data_valid : in t_DATA_VAL;
rout_dirs : in t_DATA_DIRS;
avai_pos : in t_AVAI_POS;
signal out_buff_if : out t_PORT_IN
)
is
variable path_index, out_index, tot_num_paths : integer;
begin
tot_num_paths := num_paths_up+num_paths_down*4;
for i in 0 to tot_num_paths-1 loop
out_buff_if(i).data_in <= (others => '0');
out_buff_if(i).req <= '0';
end loop;
for j in 0 to NUM_DIRS loop
path_index := 0;
for i in 0 to tot_num_paths-1 loop
if rd_data_valid(i)='1' and rout_dirs(i)(j)='1' then
out_index := retrieve_avai_path_index(j, path_index,
num_paths_up, num_paths_down, avai_pos);
path_index := path_index + 1;
out_buff_if(out_index).data_in <= rd_data(i);
out_buff_if(i).req <= '1';
end if;
end loop;
end loop;
end set_out_buffer;
procedure routing (
level : in positive;
read_data : in t_DATA;
read_data_valid : in t_DATA_VAL;
chip_r_x : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
chip_r_y : in std_logic_vector(CHIP_ADDR_SIZE-1 downto 0);
core_r_x : in std_logic_vector;
core_r_y : in std_logic_vector;
paths : in t_PATHS;
num_paths_up : in positive;
num_paths_down : in positive;
signal out_buff_if : out t_PORT_IN
) is
variable rout_dirs : t_DATA_DIRS(num_paths_up+num_paths_down*4 downto 0);
variable avai_pos : t_AVAI_POS(num_paths_up+num_paths_down*4 downto 0);
begin
rout_dir_determination(level, read_data, read_data_valid, chip_r_x,
chip_r_y, core_r_x, core_r_y, rout_dirs);
rout_path_determination(read_data, read_data_valid, rout_dirs, paths,
num_paths_up, num_paths_down, avai_pos);
set_out_buffer(num_paths_up, num_paths_down, read_data, read_data_valid,
rout_dirs, avai_pos, out_buff_if);
end routing;
end package body; end package body;

View file

@ -18,8 +18,6 @@ architecture bench of fifo_tb is
signal clk : std_logic; signal clk : std_logic;
signal wr_req : std_logic; signal wr_req : std_logic;
signal rd_req : std_logic; signal rd_req : std_logic;
signal wr_ack : std_logic;
signal rd_ack : std_logic;
signal full : std_logic; signal full : std_logic;
signal empty : std_logic; signal empty : std_logic;
signal data_in : std_logic_vector(WIDTH-1 downto 0); signal data_in : std_logic_vector(WIDTH-1 downto 0);
@ -37,8 +35,6 @@ begin
clk => clk, clk => clk,
wr_req => wr_req, wr_req => wr_req,
rd_req => rd_req, rd_req => rd_req,
wr_ack => wr_ack,
rd_ack => rd_ack,
full => full, full => full,
empty => empty, empty => empty,
data_in => data_in, data_in => data_in,
@ -59,19 +55,19 @@ begin
wait for CLK_PERIOD; wait for CLK_PERIOD;
arstN <= '1'; arstN <= '1';
for value_sent in 6 downto 0 loop for value_sent in 10 downto 0 loop
wr_req <= '1'; wr_req <= '1';
data_in <= std_logic_vector(to_unsigned(value_sent, data_in'length)); data_in <= std_logic_vector(to_unsigned(value_sent, data_in'length));
wait until wr_ack = '1'; wait for clk_period;
wr_req <= '0'; wr_req <= '0';
wait until wr_ack = '0'; wait for clk_period;
end loop; end loop;
for counter in 0 to 6 loop for counter in 0 to 10 loop
rd_req <= '1'; rd_req <= '1';
wait until rd_ack = '1'; wait for clk_period;
rd_req <= '0'; --rd_req <= '0';
wait until rd_ack = '0'; --wait for clk_period;
end loop; end loop;
wait; wait;
end process; end process;

78
test/router_tb.vhdl Normal file
View file

@ -0,0 +1,78 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.router_types.all;
entity router_tb is
end;
architecture bench of router_tb is
-- Clock period
constant clk_period : time := 5 ns;
-- Generics
constant num_paths_up : integer := 1;
constant num_paths_down : integer := 1;
constant level : integer := 1;
constant buffer_width : integer := 64;
constant buffer_depth : integer := 4;
constant val_chip_r_x : integer := 0;
constant val_chip_r_y : integer := 0;
constant val_core_r_x : integer := 0;
constant val_core_r_y : integer := 0;
-- Ports
signal clk : std_logic;
signal arstN : std_logic;
signal buffers_in : t_PORT_IN(num_paths_up+num_paths_down*4-1 downto 0);
signal buffers_out : t_PORT_OUT(num_paths_up+num_paths_down*4-1 downto 0);
begin
router_inst : entity work.router
generic map (
num_paths_up => num_paths_up,
num_paths_down => num_paths_down,
level => level,
buffer_width => buffer_width,
buffer_depth => buffer_depth,
val_chip_r_x => val_chip_r_x,
val_chip_r_y => val_chip_r_y,
val_core_r_x => val_core_r_x,
val_core_r_y => val_core_r_y
)
port map (
clk => clk,
arstN => arstN,
buffers_in => buffers_in,
buffers_out => buffers_out
);
clock_gen: process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
test: process
begin
buffers_in(0).data_in <= "0001"&"00000"&"00000"&"00001"&"00001"&
std_logic_vector(to_unsigned(3, 40));
buffers_in(0).req <= '1';
buffers_in(1).data_in <= (others => '0');
buffers_in(1).req <= '0';
buffers_in(2).data_in <= "0001"&"00000"&"10000"&"10001"&"00001"&
std_logic_vector(to_unsigned(4, 40));
buffers_in(2).req <= '1';
buffers_in(3).data_in <= (others => '0');
buffers_in(3).req <= '0';
buffers_in(4).data_in <= "0001"&"00000"&"00000"&"00000"&"00001"&
std_logic_vector(to_unsigned(5, 40));
buffers_in(4).req <= '1';
wait;
end process;
end bench;