1 ------------------------------------------------------------------------------- 2 -- File : AxiStreamDmaV2Read.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2017-02-02 5 -- Last update: 2017-02-02 6 ------------------------------------------------------------------------------- 8 -- Block to transfer a single AXI Stream frame from memory using an AXI 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 ------------------------------------------------------------------------------- 21 use ieee.std_logic_1164.
all;
22 use ieee.std_logic_arith.
all;
23 use ieee.std_logic_unsigned.
all;
45 -- DMA Control Interface 53 -- Streaming Interface 60 end AxiStreamDmaV2Read;
67 type ReqStateType is ( 78 type RegType is record 80 --pendBytes : slv(31 downto 0); 81 size : slv(31 downto 0);
-- Decrementing counter used in data collection engine 82 reqSize : slv(31 downto 0);
-- Decrementing counter used in request engine 83 reqCnt : slv(31 downto 0);
-- Total bytes requested 84 ackCnt : slv(31 downto 0);
-- Total bytes received 92 reqState : ReqStateType;
96 constant REG_INIT_C : RegType := ( 98 --pendBytes => (others => '0'), 99 size => (others => '0'), 100 reqSize => (others => '0'), 101 reqCnt => (others => '0'), 102 ackCnt => (others => '0'), 108 rMaster => axiReadMasterInit(AXI_CONFIG_G, "01", "0000"), 113 signal r : RegType := REG_INIT_C;
114 signal rin : RegType;
119 attribute dont_touch : ;
120 attribute dont_touch of r : signal is "TRUE";
131 variable v : RegType;
132 variable pendBytes: ;
135 -- Latch the current value 141 -- Reset strobing Signals 146 if (sSlave.tReady = '1') then 148 v.sMaster.tLast := '0';
149 v.sMaster.tUser := (others => '0');
150 v.sMaster.tKeep := (others => '1');
151 v.sMaster.tStrb := (others => '1');
154 -- Calculate the pending bytes 155 --v.pendBytes := r.reqCnt - r.ackCnt; 156 pendBytes := conv_integer(r.reqCnt - r.ackCnt);
161 -- Check for the threshold = zero case 163 --if (r.pendBytes = 0) then 164 if (pendBytes = 0) then 168 --if (r.pendBytes < PEND_THRESH_G) then 180 -- Clear descriptor handshake 186 -- Memory Request State machine 188 ---------------------------------------------------------------------- 190 -- Update the variables 196 -- Force address alignment 198 -- Reset the counters 199 v.reqCnt := (others => '0');
200 v.ackCnt := (others => '0');
201 -- Check for DMA request 212 v.reqState := ADDR_S;
214 ---------------------------------------------------------------------- 216 -- Check if ready to make memory request 217 if (r.rMaster.arvalid = '0') then 218 -- Set the memory address 220 -- Determine transfer size aligned to 4k boundaries 222 -- Check for the following: 223 -- 1) There is enough room in the FIFO for a burst 225 -- 3) Last transaction already completed 231 v.reqState := NEXT_S;
234 ---------------------------------------------------------------------- 236 -- Update the request size 237 v.reqCnt := r.reqCnt + getAxiReadBytes(AXI_CONFIG_G,r.rMaster);
238 v.reqSize := r.reqSize - getAxiReadBytes(AXI_CONFIG_G,r.rMaster);
239 -- Update next address 241 -- Back to address state 242 v.reqState := ADDR_S;
243 ---------------------------------------------------------------------- 246 -- Data Collection State machine 248 ---------------------------------------------------------------------- 250 -- Blowoff any out-of-phase data (should never happen) 252 ---------------------------------------------------------------------- 256 if (v.sMaster.tValid = '0') then 260 -- Check if ready to move data 266 if r.first = '1' then 269 -- Set the tUser for the first byte transferred 270 axiStreamSetUserField( 275 -- Check the read size 278 v.size := (others => '0');
279 -- Top out at dma.size 282 -- Decrement the counter 284 -- Increment the counter 287 -- Check for completion 289 -- Terminate the frame 291 v.sMaster.tKeep := genTKeep(conv_integer(r.size(4 downto 0)));
292 v.sMaster.tStrb := genTKeep(conv_integer(r.size(4 downto 0)));
293 -- Set last user field 302 ---------------------------------------------------------------------- 304 -- Check for ACK completion 308 -- Check if no leftover memory request data 309 if r.leftovers = '0' then 311 v.reqState := IDLE_S;
315 v.state := BLOWOFF_S;
318 ---------------------------------------------------------------------- 322 -- Check for last transfer 325 v.reqState := IDLE_S;
328 ---------------------------------------------------------------------- 331 -- Forward the state of the state machine 332 if v.state = IDLE_S then 345 -- Register the variable for next clock cycle 359 if (rising_edge(axiClk)) then 360 r <= rin after TPD_G;
PIPE_STAGES_Gnatural range 0 to 16:= 0
slv( 63 downto 0) address
out dmaRdDescRetAxiReadDmaDescRetType
slv( 1023 downto 0) rdata
PEND_THRESH_Gnatural := 0
in dmaRdDescReqAxiReadDmaDescReqType
AxiReadDmaDescRetType :=(valid => '0',buffId =>( others => '0'),result =>( others => '0')) AXI_READ_DMA_DESC_RET_INIT_C
slv( 7 downto 0) firstUser
in axisSlaveAxiStreamSlaveType
AXIS_READY_EN_Gboolean := false
PIPE_STAGES_Gnatural := 1
out sAxisSlaveAxiStreamSlaveType
natural range 1 to 16 TDATA_BYTES_C
in mAxisSlaveAxiStreamSlaveType
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
positive range 12 to 64 ADDR_WIDTH_C
slv( 7 downto 0) lastUser
in sAxisMasterAxiStreamMasterType
AxiReadDmaDescReqType :=(valid => '0',address =>( others => '0'),buffId =>( others => '0'),firstUser =>( others => '0'),lastUser =>( others => '0'),size =>( others => '0'),continue => '0',id =>( others => '0'),dest =>( others => '0')) AXI_READ_DMA_DESC_REQ_INIT_C
out axiReadMasterAxiReadMasterType
in axiCacheslv( 3 downto 0)
natural range 0 to 8 TUSER_BITS_C
out mAxisMasterAxiStreamMasterType
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 4,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_NORMAL_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_NORMAL_C) AXI_STREAM_CONFIG_INIT_C
positive range 1 to 128 DATA_BYTES_C
in axisCtrlAxiStreamCtrlType
in axiReadSlaveAxiReadSlaveType
out axisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
AxiConfigType :=axiConfig(ADDR_WIDTH_C => 32,DATA_BYTES_C => 4,ID_BITS_C => 12,LEN_BITS_C => 4) AXI_CONFIG_INIT_C
AXIS_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
BURST_BYTES_Ginteger range 1 to 4096:= 4096