SURF  1.0
AxiStreamDeMux.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamDeMux.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-25
5 -- Last update: 2016-09-06
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Block to connect a single incoming AXI stream to multiple outgoing AXI
9 -- streams based upon the incoming tDest value.
10 -------------------------------------------------------------------------------
11 -- This file is part of 'SLAC Firmware Standard Library'.
12 -- It is subject to the license terms in the LICENSE.txt file found in the
13 -- top-level directory of this distribution and at:
14 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
15 -- No part of 'SLAC Firmware Standard Library', including this file,
16 -- may be copied, modified, propagated, or distributed except according to
17 -- the terms contained in the LICENSE.txt file.
18 -------------------------------------------------------------------------------
19 
20 library ieee;
21 use ieee.std_logic_1164.all;
22 use ieee.NUMERIC_STD.all;
23 use work.StdRtlPkg.all;
24 use work.ArbiterPkg.all;
25 use work.AxiStreamPkg.all;
26 
27 --! @see entity
28  --! @ingroup axi
29 entity AxiStreamDeMux is
30  generic (
31  TPD_G : time := 1 ns;
32  NUM_MASTERS_G : integer range 1 to 32 := 12;
33  MODE_G : string := "INDEXED"; -- Or "ROUTED"
34  TDEST_ROUTES_G : slv8Array := (0 => "--------"); -- Only used in ROUTED mode
35  PIPE_STAGES_G : integer range 0 to 16 := 0;
36  TDEST_HIGH_G : integer range 0 to 7 := 7;
37  TDEST_LOW_G : integer range 0 to 7 := 0);
38  port (
39  -- Slave
42  -- Masters
45  -- Clock and reset
46  axisClk : in sl;
47  axisRst : in sl);
48 end AxiStreamDeMux;
49 
50 architecture structure of AxiStreamDeMux is
51 
52  type RegType is record
55  end record RegType;
56 
57  constant REG_INIT_C : RegType := (
59  masters => (others => AXI_STREAM_MASTER_INIT_C));
60 
63 
64  signal r : RegType := REG_INIT_C;
65  signal rin : RegType;
66 
67 begin
68 
69  assert (MODE_G /= "INDEXED" or (TDEST_HIGH_G - TDEST_LOW_G + 1 >= log2(NUM_MASTERS_G)))
70  report "In INDEXED mode, TDest range " & integer'image(TDEST_HIGH_G) & " downto " & integer'image(TDEST_LOW_G) &
71  " is too small for NUM_MASTERS_G=" & integer'image(NUM_MASTERS_G)
72  severity error;
73 
74  assert (MODE_G /= "ROUTED" or (TDEST_ROUTES_G'length = NUM_MASTERS_G))
75  report "In ROUTED mode, length of TDEST_ROUTES_G: " & integer'image(TDEST_ROUTES_G'length) &
76  " must equal NUM_MASTERS_G: " & integer'image(NUM_MASTERS_G)
77  severity error;
78 
79  comb : process (axisRst, pipeAxisSlaves, r, sAxisMaster) is
80  variable v : RegType;
81  variable idx : natural;
82  variable i : natural;
83  begin
84  -- Latch the current value
85  v := r;
86 
87  -- Reset strobing signals
88  v.slave.tReady := '0';
89 
90  -- Update tValid register
91  for i in 0 to NUM_MASTERS_G-1 loop
92  if pipeAxisSlaves(i).tReady = '1' then
93  v.masters(i).tValid := '0';
94  end if;
95  end loop;
96 
97  -- Decode destination
98  if (MODE_G = "INDEXED") then
99  -- TDEST indicates the output port
100  idx := to_integer(unsigned(sAxisMaster.tDest(TDEST_HIGH_G downto TDEST_LOW_G)));
101  elsif (MODE_G = "ROUTED") then
102  -- Output port determined by TDEST_ROUTES_G
103  -- Set to invalid idx first, if non match then frame will be dumped
104  idx := NUM_MASTERS_G;
105  -- Search for a matching MASK in ascending order of mask array
106  for i in 0 to NUM_MASTERS_G-1 loop
107  if (std_match(sAxisMaster.tDest, TDEST_ROUTES_G(i))) then
108  idx := i;
109  end if;
110  end loop;
111  end if;
112 
113  -- Check for invalid destination
114  if idx >= NUM_MASTERS_G then
115  -- Blow off the data
116  v.slave.tReady := '1';
117  -- Check if ready to move data
118  elsif (v.masters(idx).tValid = '0') and (sAxisMaster.tValid = '1') then
119  -- Accept the data
120  v.slave.tReady := '1';
121  -- Move the data
122  v.masters(idx) := sAxisMaster;
123  end if;
124 
125  -- Reset
126  if (axisRst = '1') then
127  v := REG_INIT_C;
128  end if;
129 
130  -- Register the variable for next clock cycle
131  rin <= v;
132 
133  -- Outputs
134  sAxisSlave <= v.slave;
136 
137  end process comb;
138 
139  GEN_VEC :
140  for i in (NUM_MASTERS_G-1) downto 0 generate
141 
142  U_Pipeline : entity work.AxiStreamPipeline
143  generic map (
144  TPD_G => TPD_G,
146  port map (
147  axisClk => axisClk,
148  axisRst => axisRst,
152  mAxisSlave => mAxisSlaves(i));
153 
154  end generate GEN_VEC;
155 
156  seq : process (axisClk) is
157  begin
158  if (rising_edge(axisClk)) then
159  r <= rin after TPD_G;
160  end if;
161  end process seq;
162 
163 end structure;
164 
PIPE_STAGES_Ginteger range 0 to 16:= 0
PIPE_STAGES_Gnatural range 0 to 16:= 0
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
std_logic sl
Definition: StdRtlPkg.vhd:28
RegType :=(slave => AXI_STREAM_SLAVE_INIT_C,masters =>( others => AXI_STREAM_MASTER_INIT_C)) REG_INIT_C
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
RegType := REG_INIT_C r
out mAxisMastersAxiStreamMasterArray( NUM_MASTERS_G- 1 downto 0)
out sAxisSlaveAxiStreamSlaveType
in mAxisSlaveAxiStreamSlaveType
out sAxisSlaveAxiStreamSlaveType
AxiStreamMasterArray( NUM_MASTERS_G- 1 downto 0) masters
TDEST_LOW_Ginteger range 0 to 7:= 0
in sAxisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
TPD_Gtime := 1 ns
in sAxisMasterAxiStreamMasterType
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
AxiStreamSlaveArray( NUM_MASTERS_G- 1 downto 0) pipeAxisSlaves
out mAxisMasterAxiStreamMasterType
slv( 7 downto 0) tDest
in mAxisSlavesAxiStreamSlaveArray( NUM_MASTERS_G- 1 downto 0)
TDEST_HIGH_Ginteger range 0 to 7:= 7
AxiStreamMasterArray( NUM_MASTERS_G- 1 downto 0) pipeAxisMasters
AxiStreamSlaveType slave
TDEST_ROUTES_Gslv8Array :=( 0=> "--------")
_library_ ieeeieee
NUM_MASTERS_Ginteger range 1 to 32:= 12
MODE_Gstring := "INDEXED"