1 ------------------------------------------------------------------------------- 2 -- File : AxiStreamDepacketizer 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-09-29 5 -- Last update: 2016-07-13 6 ------------------------------------------------------------------------------- 7 -- Description: AXI stream DePacketerizer Module (non-interleave only) 8 -- Formats an AXI-Stream for a transport link. 9 -- Sideband fields are placed into the data stream in a header. 10 -- Long frames are broken into smaller packets. 11 ------------------------------------------------------------------------------- 12 -- This file is part of 'SLAC Firmware Standard Library'. 13 -- It is subject to the license terms in the LICENSE.txt file found in the 14 -- top-level directory of this distribution and at: 15 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 16 -- No part of 'SLAC Firmware Standard Library', including this file, 17 -- may be copied, modified, propagated, or distributed except according to 18 -- the terms contained in the LICENSE.txt file. 19 ------------------------------------------------------------------------------- 22 use ieee.std_logic_1164.
all;
23 use ieee.std_logic_unsigned.
all;
24 use ieee.std_logic_arith.
all;
40 -- AXI-Lite Interface for local registers 44 restart : in sl := '0';
-- Reset the expected frame number back to 0 52 end entity AxiStreamDepacketizer;
66 constant VERSION_C : slv(3 downto 0) := "0000";
68 type StateType is (HEADER_S, BLEED_S, MOVE_S, DONE_S);
70 type RegType is record 72 frameNumber : slv(11 downto 0);
73 packetNumber : slv(23 downto 0);
81 constant REG_INIT_C : RegType := ( 83 frameNumber => (others => '0'), 84 packetNumber => (others => '0'), 89 outputAxisMaster => (others => axiStreamMasterInit(AXIS_CONFIG_C)));
91 signal r : RegType := REG_INIT_C;
101 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 103 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 116 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 118 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 131 ------------------------------------------------------------------------------------------------- 132 -- Accumulation sequencing, DMA ring buffer, and AXI-Lite logic 133 ------------------------------------------------------------------------------------------------- 134 comb :
process (
axisRst, inputAxisMaster, outputAxisSlave, r,
restart)
is 135 variable v : RegType;
145 v.inputAxisSlave.tready := '0';
146 if (outputAxisSlave.tReady = '1') then 147 v.outputAxisMaster(1).tValid := '0';
148 v.outputAxisMaster(0).tValid := '0';
153 v.inputAxisSlave.tready := '1';
154 v.outputAxisMaster(1) := axiStreamMasterInit(AXIS_CONFIG_C);
156 if (r.outputAxisMaster(1).tValid = '1' and v.outputAxisMaster(0).tValid = '0') then 157 v.outputAxisMaster(0) := r.outputAxisMaster(1);
160 -- Process the header 161 if (inputAxisMaster.tValid = '1' and v.outputAxisMaster(1).tValid = '0') then 164 -- Assign sideband fields 165 v.outputAxisMaster(1).tDest(7 downto 0) := inputAxisMaster.tData(47 downto 40);
166 v.outputAxisMaster(1).tId(7 downto 0) := inputAxisMaster.tData(55 downto 48);
167 v.outputAxisMaster(1).tUser(7 downto 0) := inputAxisMaster.tData(63 downto 56);
169 -- Assert SOF if starting a new frame 170 axiStreamSetUserBit(AXIS_CONFIG_C, v.outputAxisMaster(1), SSI_SOF_C, r.sof, 0);
-- SOF 173 -- Check frame and packet number 174 if (r.sof = '1') then 175 v.frameNumber := inputAxisMaster.tData(15 downto 4);
176 v.packetNumber := (others => '0');
177 if ((r.startup = '0' and inputAxisMaster.tData(15 downto 4) /= r.frameNumber+1) or 178 inputAxisMaster.tData(39 downto 16) /= 0) then 179 v.state := BLEED_S;
-- Error - Missing frames 182 v.packetNumber := inputAxisMaster.tData(39 downto 16);
183 if (inputAxisMaster.tData(15 downto 4) /= r.frameNumber or 184 inputAxisMaster.tData(39 downto 16) /= r.packetNumber+1) then 185 v.outputAxisMaster(1).tvalid := '1';
186 v.outputAxisMaster(1).tlast := '1';
187 axiStreamSetUserBit(AXIS_CONFIG_C, v.outputAxisMaster(1), SSI_EOFE_C, '1', 0);
196 -- Blead an entire packet 197 -- Set startup and sof true when done 198 v.inputAxisSlave.tready := '1';
199 v.outputAxisMaster(1).tvalid := '0';
202 if (inputAxisMaster.tLast = '1') then 207 -- Keep the caches copy 208 v.outputAxisMaster(1).tvalid := r.outputAxisMaster(1).tvalid;
209 -- Check if we can move data 210 if (inputAxisMaster.tValid = '1' and v.outputAxisMaster(0).tValid = '0') then 212 v.inputAxisSlave.tReady := '1';
213 -- Advance the pipeline 214 v.outputAxisMaster(1) := inputAxisMaster;
215 v.outputAxisMaster(0) := r.outputAxisMaster(1);
216 -- Keep sideband data from header 217 v.outputAxisMaster(1).tDest := r.outputAxisMaster(1).tDest;
218 v.outputAxisMaster(1).tId := r.outputAxisMaster(1).tId;
219 if (r.sideband = '1') then 220 -- But tUser only for first output txn 221 v.outputAxisMaster(1).tUser := r.outputAxisMaster(1).tUser;
225 if (inputAxisMaster.tLast = '1') then 226 -- Check tkeep to find tail byte (and strip it out) 227 v.outputAxisMaster(1).tKeep := '0' & inputAxisMaster.tKeep(15 downto 1);
228 case (inputAxisMaster.tKeep(7 downto 0)) is 230 -- Single byte tail, append tUser to previous txn which has been held 231 v.outputAxisMaster(1).tValid := '0';
232 v.outputAxisMaster(0).tUser(63 downto 56) := '0' & inputAxisMaster.tData(6 downto 0);
233 v.outputAxisMaster(0).tLast := inputAxisMaster.tData(7);
236 v.outputAxisMaster(1).tUser(7 downto 0) := '0' & inputAxisMaster.tData(14 downto 8);
239 v.outputAxisMaster(1).tUser(15 downto 8) := '0' & inputAxisMaster.tData(22 downto 16);
242 v.outputAxisMaster(1).tUser(23 downto 16) := '0' & inputAxisMaster.tData(30 downto 24);
245 v.outputAxisMaster(1).tUser(31 downto 24) := '0' & inputAxisMaster.tData(38 downto 32);
248 v.outputAxisMaster(1).tUser(39 downto 32) := '0' & inputAxisMaster.tData(46 downto 40);
251 v.outputAxisMaster(1).tUser(47 downto 40) := '0' & inputAxisMaster.tData(54 downto 48);
254 v.outputAxisMaster(1).tUser(55 downto 48) := '0' & inputAxisMaster.tData(62 downto 56);
259 v.outputAxisMaster(1).tLast := v.sof;
266 -- Keep the caches copy 267 v.outputAxisMaster(1).tvalid := r.outputAxisMaster(1).tvalid;
268 -- Check if we can move data 269 if (v.outputAxisMaster(0).tValid = '0') then 270 -- Advance the pipeline 271 v.outputAxisMaster(1).tValid := '0';
272 v.outputAxisMaster(0) := r.outputAxisMaster(1);
278 ---------------------------------------------------------------------------------------------- 279 -- Reset and output assignment 280 ---------------------------------------------------------------------------------------------- 287 inputAxisSlave <= v.inputAxisSlave;
289 -- Hold each out tvalid until next in tvalid arrives 290 outputAxisMaster <= r.outputAxisMaster(0);
297 r <= rin after TPD_G;
301 end architecture rtl;
out mAxisMasterAxiStreamMasterType
PIPE_STAGES_Gnatural range 0 to 16:= 0
natural range 0 to 8 TDEST_BITS_C
out sAxisSlaveAxiStreamSlaveType
natural range 1 to 16 TDATA_BYTES_C
in mAxisSlaveAxiStreamSlaveType
TkeepModeType TKEEP_MODE_C
natural range 0 to 8 TID_BITS_C
in sAxisMasterAxiStreamMasterType
INPUT_PIPE_STAGES_Ginteger := 0
out sAxisSlaveAxiStreamSlaveType
in sAxisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
TUserModeType TUSER_MODE_C
in mAxisSlaveAxiStreamSlaveType
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
natural range 0 to 8 TUSER_BITS_C
out mAxisMasterAxiStreamMasterType
OUTPUT_PIPE_STAGES_Ginteger := 0