CLK_EN : in std_logic;
-- Media direction port
MED_DATAREADY_IN: in STD_LOGIC;
- MED_DATA_IN: in STD_LOGIC_VECTOR (BUS_WIDTH downto 0); -- highest
+ MED_DATA_IN: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest
-- bits are
-- mult.
MED_READ_OUT: out STD_LOGIC;
MED_DATAREADY_OUT: in STD_LOGIC;
- MED_DATA_OUT: in STD_LOGIC_VECTOR (BUS_WIDTH downto 0); -- highest
+ MED_DATA_OUT: in STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0); -- highest
-- bits are
-- mult.
MED_READ_IN: out STD_LOGIC;
-- Internal direction port
- INT_DATAREADY_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0);
- INT_DATA_OUT: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH) downto 0);
- INT_READ_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0);
+ INT_DATAREADY_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0);
+ INT_DATA_OUT: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0);
+ INT_READ_IN: in STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0);
INT_DATAREADY_IN: out STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0);
- INT_DATA_IN: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH) downto 0);
- INT_READ_OUT: in STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0);
+ INT_DATA_IN: out STD_LOGIC_VECTOR ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH)-1 downto 0);
+ INT_READ_OUT: in STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0);
generic (MULT_WIDTH : integer := 3);
port(
- INPUT_IN : in STD_LOGIC_VECTOR (MULT_WIDTH downto 0);
- RESULT_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH downto 0)
+ INPUT_IN : in STD_LOGIC_VECTOR (MULT_WIDTH-1 downto 0);
+ RESULT_OUT: out STD_LOGIC_VECTOR (2**MULT_WIDTH-1 downto 0)
);
END component;
- signal current_demux_buffer, next_demux_buffer: STD_LOGIC_VECTOR (BUS_WIDTH downto 0);
+ signal current_demux_buffer, next_demux_buffer: STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0);
signal current_demux_empty, next_demux_empty: STD_LOGIC;
signal current_demux_READ, next_demux_READ: STD_LOGIC;
- signal current_demux_dr, next_demux_dr: STD_LOGIC_VECTOR ((2**MULT_WIDTH) downto 0);
+ signal current_demux_dr, next_demux_dr: STD_LOGIC_VECTOR ((2**MULT_WIDTH)-1 downto 0);
signal demux_read: STD_LOGIC; -- buffer is read out and killed
+ signal current_mux_buffer, next_mux_buffer: STD_LOGIC_VECTOR (BUS_WIDTH-1 downto 0);
+ signal current_mux_empty, next_mux_empty: STD_LOGIC;
+ signal current_mux_DR, next_mux_DR: STD_LOGIC;
+ signal current_mux_read, next_mux_read: STD_LOGIC_VECTOR ((2**MULT_WIDTH)-1 downto 0);
+ signal mux_read: STD_LOGIC; -- buffer is read out and killed
begin
-------------------------------------------------------------------------------
-- DEMUX
--------------------------------------------------------------------------------
-
+------------------------------------------------------------------------------
-- the simpler part is the demux
+
+ demux_read <= (current_demux_dr and INT_READ_IN)
+
comb_demux : process (current_demux_empty, demux_read, current_demux_buffer,
- current_demux_READ, MED_DATAREADY_IN)
+ current_demux_READ, MED_DATAREADY_IN, current_demux_dr,
+ INT_READ_IN)
begin -- process
next_demux_READ <= '0';
next_demux_buffer <= current_demux_buffer;
- if current_demux_empty = '1' or demux_read = '1' then -- no problem to read in next step
+ demux_read <='1';
+ next_demux_empty <= current_demux_empty;
+ if (current_demux_dr and INT_READ_IN) = (others => '0') then
+ demux_read <= '0'; -- no read from int point
+ end if;
+ if current_demux_empty = '1' or demux_read = '1' then
+-- no problem to read in next step
next_demux_READ <= '1';
end if;
if current_demux_READ = '1' and MED_DATAREADY_IN = '1' then
--definition of read
next_demux_buffer <= MED_DATA_IN;
+ next_demux_empty <= '0';
+ elsif demux_read = '1' then -- only read from int
+ next_demux_empty <= '1';
end if;
end process;
DEF_DR: trb_net_pattern_gen
generic map (MULT_WIDTH => MULT_WIDTH)
port map (
- INPUT_IN => next_demux_buffer (BUS_WIDTH downto (BUS_WIDTH-MULT_WIDTH)),
+ INPUT_IN => next_demux_buffer (BUS_WIDTH-1 downto (BUS_WIDTH-MULT_WIDTH)),
RESULT_OUT => next_demux_dr
);
end process;
INT_DATAREADY_OUT <= current_demux_dr;
- INT_DATA_OUT <= current_demux_buffer ((BUS_WIDTH-MULT_WIDTH)*(2**MULT_WIDTH) downto 0);
+ -- logic is much simpler when hardwire the fan-out
+ -- this might cause problems with timing, lets see
+
+ G1: for i in 2**MULT_WIDTH-1 downto 0 generate
+ INT_DATA_OUT((BUS_WIDTH-MULT_WIDTH)*(2**(i+1))-1 downto (BUS_WIDTH-MULT_WIDTH)*(2**i))
+ <= current_demux_buffer ;
+ end generate;
+
end trb_net_io_multiplexer_arch;
--- /dev/null
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.STD_LOGIC_ARITH.ALL;
+USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+use work.trb_net_std.all;
+
+entity trb_net_priority_arbiter is
+
+ generic (WIDTH : integer := 8);
+
+ port(
+ INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0)
+ );
+END trb_net_priority_arbiter;
+
+architecture trb_net_priority_arbiter_arch of trb_net_priority_arbiter is
+
+ component trb_net_priority_encoder is
+
+ generic (WIDTH : integer := 8);
+
+ port(
+ INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ PATTERN_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0)
+ );
+ END component;
+
+ signal next_fixed_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ signal next_rr_pattern, current_rr_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ signal next_p1_pattern, current_p1_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ signal next_p2_pattern, current_p2_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ signal sampled_rr_pattern1, sampled_rr_pattern2: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+
+ begin
+
+ ---------------------------------------------------------------------------
+ -- fixed pattern generator
+ ---------------------------------------------------------------------------
+
+ ENC1: trb_net_priority_encoder
+ generic map (WIDTH => WIDTH)
+ port map(
+ INPUT_IN => INPUT_IN,
+ RESULT_OUT => next_fixed_pattern
+ );
+
+-------------------------------------------------------------------------------
+-- round robin: determine next pattern
+-------------------------------------------------------------------------------
+
+ -- from the current p1 and p2 pattern, look what would be the next rr pattern
+ -- find out what would be the next rr pattern
+ -- we call this proposed pattern
+
+ ENC2: trb_net_priority_encoder
+ generic map (WIDTH => WIDTH)
+ port map(
+ INPUT_IN => sampled_rr_pattern1,
+ RESULT_OUT => proposed_rr_pattern1,
+ PATTERN_OUT => leading_rr_pattern2
+ );
+
+ ENC3: trb_net_priority_encoder
+ generic map (WIDTH => WIDTH)
+ port map(
+ INPUT_IN => sampled_rr_pattern2,
+ RESULT_OUT => proposed_rr_pattern2,
+ PATTERN_OUT => leading_rr_pattern2
+ );
+
+ sampled_rr_pattern1 <= INPUT_IN and current_p1_pattern;
+ sampled_rr_pattern2 <= INPUT_IN and current_p2_pattern;
+
+ comb_rr : process(CLK)
+ begin
+ next_rr_pattern <= current_rr_pattern;
+ next_p1_pattern <= current_p1_pattern;
+ next_p2_pattern <= current_p2_pattern;
+
+ if use_rr = '1' then
+ -- without using the rr, nothing will happen
+ if or_all(sampled_rr_pattern1) then
+ -- pattern 1 has higher priority
+ next_rr_pattern <= proposed_rr_pattern;
+ next_p1_pattern <= leading_rr_pattern1 xor proposed_rr_pattern;
+ next_p2_pattern <= not leading_rr_pattern1;
+ elsif or_all(sampled_rr_pattern2) then
+ else
+ end if;
+ end if;
+
+ end process;
+
+
+end trb_net_riority_arbiter_arch;
+
--- /dev/null
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.STD_LOGIC_ARITH.ALL;
+USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+use work.trb_net_std.all;
+
+entity trb_net_priority_encoder is
+
+ generic (WIDTH : integer := 8);
+
+ port(
+ INPUT_IN : in STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ PATTERN_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0)
+ );
+END trb_net_priority_encoder;
+
+architecture trb_net_priority_encoder_arch of trb_net_priority_encoder is
+
+ signal fixed_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+ signal leading_pattern: STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+
+ begin
+
+ G1: for i in 0 to WIDTH-1 generate
+
+ G2: if i = 0 generate
+ fixed_pattern(0) <= INPUT_IN(0);
+ leading_pattern(0) <= INPUT_IN(0);
+ end generate;
+ G3: if i > 0 generate
+ comb : process (INPUT_IN)
+ begin
+ fixed_pattern(i) <= '0';
+ leading_pattern(i) <= leading_pattern(i-1);
+ if INPUT_IN = '1' and leading_pattern(i-1) = '0' then
+ fixed_pattern(i) <= '1';
+ leading_pattern(i) <= '1';
+ end if;
+ end process;
+ end generate;
+ end generate;
+
+ RESULT_OUT <= fixed_pattern;
+ PATTERN_OUT <= leading_pattern;
+
+
+end trb_net_riority_encoder_arch;
+