DMA_for_RoCC/noc_files/vc_allocator.vhd

160 lines
7.9 KiB
VHDL

-------------------------------------------------------------------------------
-- Title : Virtual channel allocator
-- Project : Modular, heterogenous 3D NoC
-------------------------------------------------------------------------------
-- File : vc_allocator.vhd
-- Author : Lennart Bamberg <lennart@t440s>
-- Company :
-- Created : 2018-11-11
-- Last update: 2018-11-28
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: New package are detected in an input port, then the required
-- informations (routing & packet length) are decoded from the
-- header. Finally, a suitable output virtual channel is assigned.
-- COMMENT:
-- Currently, this version is not used (but the high perf. one)!
-------------------------------------------------------------------------------
-- Copyright (c) 2018
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2018-11-11 1.0 lennart Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use work.NOC_3D_PACKAGE.all;
use work.TURNS_3D_NOC.all;
entity vc_allocator is
generic (
port_num : positive := 7;
-- Integer range has to be / is (0 to port_num-1)
port_exist : integer_vec := (0, 1, 2, 3, 4, 5, 6);
Xis : natural := 1;
Yis : natural := 1;
Zis : natural := 1;
header_incl_in_packet_length : boolean := true;
rout_algo : string := "DXYU";
vc_num_vec : integer_vec := (4 ,4 ,4 ,4 ,4 ,4 ,4 );
vc_num_out_vec : integer_vec := (4 ,4 ,4 ,4 ,4 ,4 ,4 ));
port (
clk, rst : in std_logic;
header : in header_inf_vector(int_vec_sum(vc_num_vec)-1 downto 0);
enr_vc : in std_logic_vector(int_vec_sum(vc_num_vec)-1 downto 0);
valid_data_vc_vec : in std_logic_vector(int_vec_sum(vc_num_vec)-1 downto 0);
input_vc_in_use : out std_logic_vector(int_vec_sum(vc_num_vec)-1 downto 0);
crossbar_ctrl_vec : out std_logic_vector(int_vec_sum(vc_num_out_vec)*
bit_width(port_num-1)-1 downto 0);
vc_sel_enc_vec : out vc_status_array_enc(int_vec_sum(vc_num_out_vec)-1 downto 0);
output_vc_in_use : out std_logic_vector(int_vec_sum(vc_num_out_vec)-1 downto 0)
);
end entity vc_allocator;
architecture rtl of vc_allocator is
constant poss_routes : turn_table_3D := routes_3D(rout_algo);
constant sel_width : positive := bit_width(port_num-1);
signal ack_input : std_logic_vector(port_num-1 downto 0);
signal packet_end : std_logic_vector(int_vec_sum(vc_num_vec)-1 downto 0);
type rq_array is array (port_num-1 downto 0) of std_logic_vector(port_num-1 downto 0);
type rq_array_filt is array (port_num-1 downto 0) of std_logic_vector(port_num-2 downto 0);
signal granted_rq_array : rq_array;
signal rq_vc_out_array : rq_array_filt;
type vc_status_array_filt is array (port_num-1 downto 0) of vc_status_array(port_num-2 downto 0);
signal packet_end_sort : vc_status_array_filt;
signal granted_vc_sort : vc_status_array_filt;
signal granted_vc : std_logic_vector(int_vec_sum(vc_num_vec)-1 downto 0);
type ack_array_vc_out is array(port_num-1 downto 0) of std_logic_vector(port_num-2 downto 0);
signal ack_rq_vc_out : ack_array_vc_out;
begin -- architecture rtl
GEN_PER_PORT : for i in 0 to port_num-1 generate
constant ur_vc_in : natural := upper_range(vc_num_vec, i);
constant lr_vc_in : natural := lower_range(vc_num_vec, i);
constant ur_vc_out : natural := upper_range(vc_num_out_vec, i);
constant lr_vc_out : natural := lower_range(vc_num_out_vec, i);
begin
---------------------------------------------------------------------------
-- Header decoder and input arbiter per port-------------------------------
---------------------------------------------------------------------------
input_first_arbiter_i : entity work.header_arbiter_and_decoder
generic map (
Xis => Xis,
Yis => Yis,
Zis => Zis,
port_num => port_num,
port_exist => port_exist,
port_is => port_exist(i),
vc_num => vc_num_vec(i),
header_incl_in_packet_length => header_incl_in_packet_length,
rout_algo => rout_algo)
port map (
clk => clk,
rst => rst,
valid_data_vc => valid_data_vc_vec(ur_vc_in downto lr_vc_in),
header => header(ur_vc_in downto lr_vc_in),
enr_vc => enr_vc(ur_vc_in downto lr_vc_in),
ack_vc => ack_input(i),
granted_rq => granted_rq_array(i),
input_vc_in_use => input_vc_in_use(ur_vc_in downto lr_vc_in),
packet_end => packet_end(ur_vc_in downto lr_vc_in),
granted_vc => granted_vc(ur_vc_in downto lr_vc_in));
---------------------------------------------------------------------------
-- Output VC arbiter/allocator per port -----------------------------------
---------------------------------------------------------------------------
output_last_arbiter_i : entity work.vc_output_allocator
generic map (
port_num => port_num,
vc_num_out => vc_num_out_vec(i))
port map (
clk => clk,
rst => rst,
rq_vc_out => rq_vc_out_array(i),
granted_vc => granted_vc_sort(i),
packet_end => packet_end_sort(i),
crossbar_ctrl_vec => crossbar_ctrl_vec((ur_vc_out+1)*sel_width-1 downto lr_vc_out*sel_width),
vc_sel_enc => vc_sel_enc_vec(ur_vc_out downto lr_vc_out),
output_vc_in_use => output_vc_in_use(ur_vc_out downto lr_vc_out),
ack_rq_vc_out => ack_rq_vc_out(i)
);
end generate;
-----------------------------------------------------------------------------
-- Clock Wise Wiring --------------------------------------------------------
-----------------------------------------------------------------------------
WIRING_INAR_TO_OUTAR : process(ack_rq_vc_out, granted_rq_array, granted_vc,
packet_end)
variable var_in : natural;
variable ack_rq_vc_out_var : std_logic_vector(port_num-1 downto 0);
begin
rq_vc_out_array <= (others => (others => '0'));
granted_vc_sort <= (others => (others => (others => '0')));
packet_end_sort <= (others => (others => (others => '0')));
ack_rq_vc_out_var := (others => '0');
for y in 0 to port_num-1 loop -- For the VC-out allocator y,
for x in 0 to port_num-2 loop -- the X^th input is
if y+x < port_num-1 then
var_in := y+x+1;
else -- Modulo (start from beginning)
var_in := y+x-port_num+1;
end if;
if poss_routes(port_exist(var_in))(port_exist(y)) then
rq_vc_out_array(y)(x) <= granted_rq_array(var_in)(y);
granted_vc_sort(y)(x)(vc_num_vec(var_in)-1 downto 0)
<= slice(granted_vc, vc_num_vec, var_in);
packet_end_sort(y)(x)(vc_num_vec(var_in)-1 downto 0)
<= slice(packet_end, vc_num_vec, var_in);
ack_rq_vc_out_var(var_in) := ack_rq_vc_out_var(var_in) or
ack_rq_vc_out(y)(x); --feedback ack
end if;
end loop;
end loop;
ack_input <= ack_rq_vc_out_var;
end process;
end architecture rtl;