203 lines
7.0 KiB
Django/Jinja
203 lines
7.0 KiB
Django/Jinja
{% set addr_width = (num_ports - 1).bit_length() %}
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use ieee.math_real.all;
|
|
|
|
entity AXI_Handshaking_Scheduler_{{ num_ports }} is
|
|
generic (
|
|
G_DataWidth : integer := 8;
|
|
G_InBufferStages : integer := 1;
|
|
G_OutBufferStages : integer := 1
|
|
);
|
|
port (
|
|
--@ Clock signal; (**Rising edge** triggered)
|
|
I_CLK : in std_logic;
|
|
--@ Clock enable signal (**Active high**)
|
|
I_CE : in std_logic;
|
|
--@ Synchronous reset signal (**Active high**)
|
|
I_RST : in std_logic;
|
|
|
|
{% for i in range(num_ports) %}
|
|
--@ @virtualbus P{{ i }} @dir in P{{ i }} interface
|
|
I_P{{ i }}_Valid : in std_logic := '0';
|
|
O_P{{ i }}_Ready : out std_logic := '0';
|
|
I_P{{ i }}_Data : in std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
|
--@ @end
|
|
{% endfor %}
|
|
|
|
--@ @virtualbus Out @dir out Output interface
|
|
O_Out_Valid : out std_logic := '0';
|
|
I_Out_Ready : in std_logic := '0';
|
|
O_Out_Data : out std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
|
O_Out_Address : out std_logic_vector({{ addr_width - 1 }} downto 0) := (others => '0')
|
|
--@ @end
|
|
);
|
|
end entity AXI_Handshaking_Scheduler_{{ num_ports }};
|
|
|
|
architecture Rtl of AXI_Handshaking_Scheduler_{{ num_ports }} is
|
|
signal R_SelectRotator : unsigned({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
signal R1_SelectRotator : unsigned({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
|
|
signal C_Select : std_logic_vector({{ num_ports - 1 }} downto 0) := (others => '0');
|
|
signal C_Code : std_logic_vector({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
signal R_Code : std_logic_vector({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
signal C_CodeUnrotated : std_logic_vector({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
|
|
{% for i in range(num_ports) %}
|
|
signal S_P{{ i }}_InBufferEnable : std_logic := '0';
|
|
signal S_P{{ i }}_Ready : std_logic := '0';
|
|
signal S_P{{ i }}_Valid : std_logic := '0';
|
|
signal S_P{{ i }}_Data : std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
|
{% endfor %}
|
|
|
|
signal S_OutBufferEnable : std_logic := '0';
|
|
signal S_Out_Ready : std_logic := '0';
|
|
signal S_Out_Valid : std_logic := '0';
|
|
signal S_Out_Data : std_logic_vector(G_DataWidth - 1 downto 0) := (others => '0');
|
|
signal S_Out_Address : std_logic_vector({{ addr_width - 1 }} downto 0) := (others => '0');
|
|
begin
|
|
|
|
{% for i in range(num_ports) %}
|
|
I_P{{ i }}_InBufferCtrl : entity work.PipelineController
|
|
generic map(
|
|
G_PipelineStages => G_InBufferStages
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_RST => I_RST,
|
|
O_Enable => S_P{{ i }}_InBufferEnable,
|
|
I_Valid => I_P{{ i }}_Valid,
|
|
O_Ready => O_P{{ i }}_Ready,
|
|
O_Valid => S_P{{ i }}_Valid,
|
|
I_Ready => S_P{{ i }}_Ready
|
|
);
|
|
|
|
I_P{{ i }}_InBuffer : entity work.PipelineRegister
|
|
generic map(
|
|
G_PipelineStages => G_InBufferStages,
|
|
G_Width => G_DataWidth,
|
|
G_RegisterBalancing => "forward"
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_Enable => S_P{{ i }}_InBufferEnable,
|
|
I_Data => I_P{{ i }}_Data,
|
|
O_Data => S_P{{ i }}_Data
|
|
);
|
|
{% endfor %}
|
|
|
|
I_PriorityEncoder_{{ num_ports }} : entity work.PriorityEncoder_{{ num_ports }}
|
|
port map(
|
|
I_Select => C_Select,
|
|
O_Code => C_Code
|
|
);
|
|
|
|
P_SelectMux : process (R_SelectRotator
|
|
{%- for i in range(num_ports) %}, S_P{{ i }}_Valid{% endfor %})
|
|
begin
|
|
case R_SelectRotator is
|
|
{%- for r in range(num_ports) %}
|
|
when "{{ '{:0{}b}'.format(r, addr_width) }}" =>
|
|
C_Select <=
|
|
{%- for i in range(num_ports) -%}
|
|
S_P{{ (i + r) % num_ports }}_Valid{% if not loop.last %} & {% endif %}
|
|
{%- endfor %};
|
|
{% endfor %}
|
|
when others =>
|
|
C_Select <= (others => '-');
|
|
end case;
|
|
end process;
|
|
|
|
P_CodeUnrotating : process (R_Code, R1_SelectRotator)
|
|
begin
|
|
C_CodeUnrotated <= std_logic_vector(unsigned(R_Code) + R1_SelectRotator);
|
|
end process;
|
|
|
|
P_OutMux : process (
|
|
C_CodeUnrotated
|
|
{%- for i in range(num_ports) %}, S_P{{ i }}_Data{% endfor %}
|
|
{%- for i in range(num_ports) %}, S_P{{ i }}_Valid{% endfor %}
|
|
, S_Out_Ready)
|
|
begin
|
|
S_Out_Valid <= '0';
|
|
{%- for i in range(num_ports) %}
|
|
S_P{{ i }}_Ready <= '0';
|
|
{%- endfor %}
|
|
S_Out_Data <= (others => '-');
|
|
S_Out_Address <= C_CodeUnrotated;
|
|
|
|
case C_CodeUnrotated is
|
|
{%- for i in range(num_ports) %}
|
|
when "{{ '{:0{}b}'.format(i, addr_width) }}" =>
|
|
S_Out_Valid <= S_P{{ i }}_Valid;
|
|
S_P{{ i }}_Ready <= S_Out_Ready;
|
|
S_Out_Data <= S_P{{ i }}_Data;
|
|
{%- endfor %}
|
|
when others =>
|
|
S_Out_Address <= (others => '-');
|
|
end case;
|
|
end process;
|
|
|
|
P_SelectRotator : process (I_CLK)
|
|
begin
|
|
if rising_edge(I_CLK) then
|
|
if I_CE = '1' then
|
|
if I_RST = '1' then
|
|
R_SelectRotator <= (others => '0');
|
|
R1_SelectRotator <= (others => '0');
|
|
R_Code <= (others => '0');
|
|
else
|
|
R1_SelectRotator <= R_SelectRotator;
|
|
R_Code <= C_Code;
|
|
if I_Out_Ready = '1' then
|
|
R_SelectRotator <= unsigned(C_CodeUnrotated) + 1;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process P_SelectRotator;
|
|
|
|
I_OutBufferCtrl : entity work.PipelineController
|
|
generic map(
|
|
G_PipelineStages => G_OutBufferStages
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_CE => I_CE,
|
|
I_RST => I_RST,
|
|
O_Enable => S_OutBufferEnable,
|
|
I_Valid => S_Out_Valid,
|
|
O_Ready => S_Out_Ready,
|
|
O_Valid => O_Out_Valid,
|
|
I_Ready => I_Out_Ready
|
|
);
|
|
|
|
I_OutDataBuffer : entity work.PipelineRegister
|
|
generic map(
|
|
G_PipelineStages => G_OutBufferStages,
|
|
G_Width => G_DataWidth,
|
|
G_RegisterBalancing => "backward"
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_Enable => S_OutBufferEnable,
|
|
I_Data => S_Out_Data,
|
|
O_Data => O_Out_Data
|
|
);
|
|
|
|
I_OutAddressBuffer : entity work.PipelineRegister
|
|
generic map(
|
|
G_PipelineStages => G_OutBufferStages,
|
|
G_Width => {{ addr_width }},
|
|
G_RegisterBalancing => "backward"
|
|
)
|
|
port map(
|
|
I_CLK => I_CLK,
|
|
I_Enable => S_OutBufferEnable,
|
|
I_Data => S_Out_Address,
|
|
O_Data => O_Out_Address
|
|
);
|
|
end architecture;
|