1 ------------------------------------------------------------------------------- 2 -- File : AxiStreamDmaRingRead.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-09-29 5 -- Last update: 2016-08-02 6 ------------------------------------------------------------------------------- 7 -- Description: AXI Stream to DMA Ring Buffer Read Module 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_unsigned.
all;
21 use ieee.std_logic_arith.
all;
46 -- AXI-Lite Interface for local registers 67 -- AXI4 Interface for RAM 73 end entity AxiStreamDmaRingRead;
89 type RegType is record 90 startAddr : slv(63 downto 0);
91 endAddr : slv(63 downto 0);
92 mode : slv(31 downto 0);
99 constant REG_INIT_C : RegType := ( 100 startAddr => (others => '0'), 101 endAddr => (others => '0'), 102 mode => (others => '0'), 103 state => START_LOW_S, 108 signal r : RegType := REG_INIT_C;
109 signal rin : RegType;
123 -- Assert that stream config has enough tdest bits for the number of buffers being tracked 126 -- Axi Lite Bus master 133 req => r.axilReq,
-- [in] 134 ack => axilAck,
-- [out] 152 dmaReq => dmaReqAxi,
-- [in] 153 dmaAck => dmaAckAxi,
-- [out] 160 -- Main logic runs on AXI-Lite clk, which may be different from the DMA AXI clk 161 -- Synchronize the request/ack bus if necessary 170 dataIn => r.dmaReq.request,
-- [in] 171 dataOut => dmaReqAxi.request
);
-- [out] 182 dataIn
(63 downto 0) => r.dmaReq.address,
183 dataIn
(95 downto 64) => r.dmaReq.size,
184 dataIn
(103 downto 96) => r.dmaReq.firstUser,
185 dataIn
(111 downto 104) => r.dmaReq.lastUser,
186 dataIn
(119 downto 112) => r.dmaReq.dest,
187 dataIn
(127 downto 120) => r.dmaReq.id,
188 dataOut
(63 downto 0) => dmaReqAxi.address,
189 dataOut
(95 downto 64) => dmaReqAxi.size,
190 dataOut
(103 downto 96) => dmaReqAxi.firstUser,
191 dataOut
(111 downto 104) => dmaReqAxi.lastUser,
192 dataOut
(119 downto 112) => dmaReqAxi.dest,
193 dataOut
(127 downto 120) => dmaReqAxi.id
);
203 dataIn => dmaAckAxi.done,
-- [in] 204 dataOut => dmaAck.done
);
-- [out] 215 dataIn
(0) => dmaAckAxi.readError,
-- [in] 216 dataIn
(2 downto 1) => dmaAckAxi.errorValue,
-- [in] 217 dataOut
(0) => dmaAck.readError,
-- [out] 218 dataOut
(2 downto 1) => dmaAck.errorValue
);
-- [out] 244 comb :
process (axilAck,
axilRst, dmaAck, intStatusMaster, r)
is 245 variable v : RegType;
246 variable buf : slv(5 downto 0);
250 buf := intStatusMaster.tData(5 downto 0);
252 v.intStatusSlave.tReady := '0';
254 -- Automatically issue new read requests when a status message is ready 255 v.axilReq.rnw := '1';
256 if (axilAck.done = '0' and r.intStatusSlave.tReady = '0') then 264 if (r.axilReq.request = '1' and axilAck.done = '1') then 266 v.startAddr(31 downto 0) := axilAck.rdData;
267 v.state := START_HIGH_S;
273 if (r.axilReq.request = '1' and axilAck.done = '1') then 275 v.startAddr(63 downto 32) := axilAck.rdData;
276 v.state := END_LOW_S;
282 if (r.axilReq.request = '1' and axilAck.done = '1') then 284 v.endAddr(31 downto 0) := axilAck.rdData;
285 v.state := END_HIGH_S;
291 if (r.axilReq.request = '1' and axilAck.done = '1') then 293 v.endAddr(63 downto 32) := axilAck.rdData;
294 v.state := DMA_REQ_S;
301 v.dmaReq.address := r.startAddr;
302 -- Optimization. Start address will always be on a BURST_SIZE boundary 303 v.dmaReq.address(DMA_ADDR_LOW_C-1 downto 0) := (others => '0');
304 v.dmaReq.size := resize(r.endAddr-r.startAddr, 32);
305 v.dmaReq.dest := resize(buf, 8);
307 if (dmaAck.done = '1') then 315 v.axilReq.rnw := '1';
316 if (r.axilReq.request = '1' and axilAck.done = '1') then 319 v.state := CLEAR_HIGH_S;
323 -- Clear the buffer after reading it out 325 v.axilReq.wrData := r.mode;
328 v.axilReq.rnw := '0';
329 if (r.axilReq.request = '1' and axilAck.done = '1') then 331 v.state := CLEAR_LOW_S;
336 v.axilReq.wrData := r.mode;
339 v.axilReq.rnw := '0';
340 if (r.axilReq.request = '1' and axilAck.done = '1') then 342 v.intStatusSlave.tready := '1';
343 v.state := START_LOW_S;
349 ---------------------------------------------------------------------------------------------- 350 -- Reset and output assignment 351 ---------------------------------------------------------------------------------------------- 364 r <= rin after TPD_G;
368 end architecture rtl;
in statusMasterAxiStreamMasterType
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
AxiLiteMasterReqType :=(request => '0',rnw => '1',address =>( others => '0'),wrData =>( others => '0')) AXI_LITE_MASTER_REQ_INIT_C
in axilReadSlaveAxiLiteReadSlaveType
AXIS_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
BUFFERS_Gnatural range 2 to 64:= 64
AXI_CACHE_Gslv( 3 downto 0) := "1111"
AXI_STREAM_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 8)
out axilWriteMasterAxiLiteWriteMasterType
PIPE_STAGES_Gnatural range 0 to 16:= 1
slv( 7 downto 0) firstUser
out axilReadMasterAxiLiteReadMasterType
in rstsl :=not RST_POLARITY_G
BYPASS_SYNC_Gboolean := false
in axilWriteSlaveAxiLiteWriteSlaveType
AXI_READ_CONFIG_GAxiConfigType := axiConfig( 32, 8, 1, 8)
in reqAxiLiteMasterReqType
BYPASS_SYNC_Gboolean := false
in dmaReqAxiReadDmaReqType
out ackAxiLiteMasterAckType
in axilWriteSlaveAxiLiteWriteSlaveType
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
BURST_SIZE_BYTES_Gnatural range 4 to 2** 17:= 4096
out statusSlaveAxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C
SLAVE_READY_EN_Gboolean := true
FIFO_FIXED_THRESH_Gboolean := true
GEN_SYNC_FIFO_Gboolean := false
out axiReadMasterAxiReadMasterType
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 1,TDEST_BITS_C => 0,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_FIXED_C,TUSER_BITS_C => 1,TUSER_MODE_C => TUSER_NONE_C) DMA_RING_STATUS_CONFIG_C
AXI_CONFIG_GAxiConfigType := AXI_CONFIG_INIT_C
in axiReadSlaveAxiReadSlaveType
AXI_BURST_Gslv( 1 downto 0) := "01"
out dmaAckAxiReadDmaAckType
in axisCtrlAxiStreamCtrlType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
out axilWriteMasterAxiLiteWriteMasterType
AxiReadDmaReqType :=(request => '0',address =>( others => '0'),size =>( others => '0'),firstUser =>( others => '0'),lastUser =>( others => '0'),dest =>( others => '0'),id =>( others => '0')) AXI_READ_DMA_REQ_INIT_C
AXIS_READY_EN_Gboolean := false
integer := 0 START_AXIL_C
out axilReadMasterAxiLiteReadMasterType
in axiReadSlaveAxiReadSlaveType
slv( SSI_TDEST_BITS_C- 1 downto 0) dest
out sAxisSlaveAxiStreamSlaveType
in axilReadSlaveAxiLiteReadSlaveType
in dataCtrlAxiStreamCtrlType := AXI_STREAM_CTRL_UNUSED_C
in axisSlaveAxiStreamSlaveType
AxiStreamCtrlType :=(pause => '0',overflow => '0',idle => '1') AXI_STREAM_CTRL_UNUSED_C
slv( 31 downto 0) address
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
SSI_OUTPUT_Gboolean := false
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
in dataSlaveAxiStreamSlaveType
in mAxisSlaveAxiStreamSlaveType
USE_BUILT_IN_Gboolean := false
in rstsl :=not RST_POLARITY_G
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
out axiReadMasterAxiReadMasterType
out dataMasterAxiStreamMasterType
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out axisMasterAxiStreamMasterType
AXIL_BASE_ADDR_Gslv( 31 downto 0) :=( others => '0')
AXI_STREAM_READY_EN_Gboolean := true