From 431adb134788a719301bc96fca0da12cdbd12672 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Wed, 24 Jan 2007 12:46:29 +0000 Subject: [PATCH] some tmp work from home, Ingo --- trb_net_io_multiplexer.vhd | 58 ++++++++++++++------- trb_net_priority_arbiter.vhd | 99 ++++++++++++++++++++++++++++++++++++ trb_net_priority_encoder.vhd | 50 ++++++++++++++++++ 3 files changed, 190 insertions(+), 17 deletions(-) create mode 100755 trb_net_priority_arbiter.vhd create mode 100755 trb_net_priority_encoder.vhd diff --git a/trb_net_io_multiplexer.vhd b/trb_net_io_multiplexer.vhd index 0348415..1ed7330 100644 --- a/trb_net_io_multiplexer.vhd +++ b/trb_net_io_multiplexer.vhd @@ -21,25 +21,25 @@ entity trb_net_io_multiplexer is 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); @@ -55,37 +55,54 @@ architecture trb_net_io_multiplexer_arch of trb_net_io_multiplexer is 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; @@ -93,7 +110,7 @@ architecture trb_net_io_multiplexer_arch of trb_net_io_multiplexer is 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 ); @@ -120,8 +137,15 @@ architecture trb_net_io_multiplexer_arch of trb_net_io_multiplexer is 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; diff --git a/trb_net_priority_arbiter.vhd b/trb_net_priority_arbiter.vhd new file mode 100755 index 0000000..51a6c8f --- /dev/null +++ b/trb_net_priority_arbiter.vhd @@ -0,0 +1,99 @@ +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; + diff --git a/trb_net_priority_encoder.vhd b/trb_net_priority_encoder.vhd new file mode 100755 index 0000000..dfe6349 --- /dev/null +++ b/trb_net_priority_encoder.vhd @@ -0,0 +1,50 @@ +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; + -- 2.43.0