1 ------------------------------------------------------------------------------- 2 -- File : SsiAxiLiteMaster.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2014-04-09 5 -- Last update: 2015-05-29 6 ------------------------------------------------------------------------------- 8 -- Block for Register protocol. 9 -- Packet is a minimum of 4 x 32-bits 12 -- Word 0 Data[31:0] = TID[31:0] (echoed) 14 -- Word 1 Data[29:0] = Address[31:2] (only 26-bits if EN_32BIT_G = false) 15 -- Word 1 Data[31:30] = Opcode, 0x0=Read, 0x1=Write, 0x2=Set, 0x3=Clear 16 -- (bit set and bit clear not supported) 17 -- Word 2 Data[31:0] = WriteData[31:0] or ReadCount[8:0] 19 -- Word N-1 Data[31:0] = WriteData[31:0] 21 -- Word N Data[31:2] = Don't Care 24 -- Word 0 Data[1:0] = VC (legacy, echoed) 25 -- Word 0 Data[7:2] = Dest_ID (legacy, echoed) 26 -- Word 0 Data[31:8] = TID[31:0] (legacy, echoed) 28 -- Word 1 Data[29:0] = Address[31:2] 29 -- Word 1 Data[31:30] = OpCode, 0x0=Read, 0x1=Write, 0x2=Set, 0x3=Clear 31 -- Word 2 Data[31:0] = ReadData[31:0]/WriteData[31:0] 33 -- Word N-1 Data[31:0] = ReadData[31:0]/WriteData[31:0] 35 -- Word N Data[31:18] = Don't Care 36 -- Word N Data[17] = Timeout Flag (response data) 37 -- Word N Data[16] = Fail Flag (response data) 38 -- Word N Data[15:00] = Don't Care 39 ------------------------------------------------------------------------------- 40 -- This file is part of 'SLAC Firmware Standard Library'. 41 -- It is subject to the license terms in the LICENSE.txt file found in the 42 -- top-level directory of this distribution and at: 43 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 44 -- No part of 'SLAC Firmware Standard Library', including this file, 45 -- may be copied, modified, propagated, or distributed except according to 46 -- the terms contained in the LICENSE.txt file. 47 ------------------------------------------------------------------------------- 50 use ieee.std_logic_1164.
all;
51 use ieee.std_logic_arith.
all;
52 use ieee.std_logic_unsigned.
all;
60 --! @ingroup protocols_ssi 72 USE_BUILT_IN_G : := false;
--if set to true, this module is only Xilinx compatible only!!! 79 -- AXI Stream IO Config 83 -- Streaming Slave (Rx) Interface (sAxisClk domain) 90 -- Streaming Master (Tx) Data Interface (mAxisClk domain) 96 -- AXI Lite Bus (axiLiteClk domain) 105 end SsiAxiLiteMaster;
109 constant SLAVE_FIFO_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_COMP_C);
110 constant MASTER_FIFO_SSI_CONFIG_C : AxiStreamConfigType := ssiAxiStreamConfig(4, TKEEP_COMP_C);
118 type StateType is (S_IDLE_C, S_ADDR_C, S_WRITE_C, S_WRITE_AXI_C, S_READ_SIZE_C, 119 S_READ_C, S_READ_AXI_C, S_STATUS_C, S_DUMP_C);
121 type RegType is record 122 echo : slv(31 downto 0);
123 address : slv(31 downto 0);
124 rdSize : slv(8 downto 0);
125 rdCount : slv(8 downto 0);
126 timer : slv(23 downto 0);
138 constant REG_INIT_C : RegType := ( 139 echo => (others => '0'), 140 address => (others => '0'), 141 rdSize => (others => '0'), 142 rdCount => (others => '0'), 143 timer => (others => '1'), 152 signal r : RegType := REG_INIT_C;
153 signal rin : RegType;
155 -- attribute dont_touch : string; 156 -- attribute dont_touch of r : signal is "TRUE"; 157 -- attribute dont_touch of sFifoAxisMaster : signal is "TRUE"; 158 -- attribute dont_touch of sFifoAxisSlave : signal is "TRUE"; 159 -- attribute dont_touch of mFifoAxisMaster : signal is "TRUE"; 160 -- attribute dont_touch of mFifoAxisSlave : signal is "TRUE"; 161 -- attribute dont_touch of mFifoAxisCtrl : signal is "TRUE"; 165 ---------------------------------- 167 ---------------------------------- 198 ------------------------------------- 199 -- Master State Machine 200 ------------------------------------- 203 variable v : RegType;
208 v.mFifoAxisMaster := sFifoAxisMaster;
209 v.mFifoAxisMaster.tUser := (others => '0');
210 v.mFifoAxisMaster.tKeep := (others => '1');
211 v.mFifoAxisMaster.tValid := '0';
212 v.mFifoAxisMaster.tLast := '0';
214 v.sFifoAxisSlave.tReady := '0';
224 v.address := (others => '0');
225 v.rdSize := (others => '0');
226 v.rdCount := (others => '0');
231 if sFifoAxisMaster.tValid = '1' and mFifoAxisCtrl.pause = '0' then 232 v.sFifoAxisSlave.tReady := '1';
235 if sFifoAxisMaster.tLast = '0' then 236 v.mFifoAxisMaster.tValid := '1';
-- Echo word 0 237 v.mFifoAxisMaster.tUser := sFifoAxisMaster.tUser;
238 v.mFifoAxisMaster.tData := sFifoAxisMaster.tData;
245 v.sFifoAxisSlave.tReady := '1';
247 if sFifoAxisMaster.tValid = '1' then 250 v.address(31 downto 26) := sFifoAxisMaster.tData(29 downto 24);
253 v.address(25 downto 2) := sFifoAxisMaster.tData(23 downto 0);
254 v.mFifoAxisMaster.tValid := '1';
-- Echo word 1 256 -- Short frame, return error 257 if sFifoAxisMaster.tLast = '1' then 259 v.state := S_STATUS_C;
262 elsif sFifoAxisMaster.tData(31 downto 30) = "00" then 263 v.state := S_READ_SIZE_C;
266 elsif sFifoAxisMaster.tData(31 downto 30) = "01" then 267 v.state := S_WRITE_C;
276 -- Prepare Write Transaction 282 v.sFifoAxisSlave.tReady := '1';
283 v.timer := (others => '1');
285 if sFifoAxisMaster.tValid = '1' then 286 if sFifoAxisMaster.tLast = '1' then 288 if (not axiStreamPacked(SLAVE_FIFO_SSI_CONFIG_C, sFifoAxisMaster)) then 291 v.state := S_STATUS_C;
293 v.mFifoAxisMaster.tValid := '1';
-- Echo write data 297 v.state := S_WRITE_AXI_C;
301 -- Write Transaction, AXI 302 when S_WRITE_AXI_C => 303 v.timer := r.timer - 1;
305 -- Clear control signals on ack 320 -- End transaction on timeout 328 -- Transaction is done 333 v.address := r.address + 4;
334 v.state := S_WRITE_C;
338 when S_READ_SIZE_C => 339 v.rdCount := (others => '0');
340 v.rdSize := sFifoAxisMaster.tData(8 downto 0);
342 -- Don't read if EOF (need for dump later) 343 if sFifoAxisMaster.tValid = '1' then 344 v.sFifoAxisSlave.tReady := not sFifoAxisMaster.tLast;
352 v.timer := (others => '1');
354 -- Start AXI transaction 357 v.state := S_READ_AXI_C;
361 v.timer := r.timer - 1;
363 -- Clear control signals on ack 376 -- End transaction on timeout 383 -- Transaction is done 385 v.mFifoAxisMaster.tValid := '1';
386 v.address := r.address + 4;
387 v.rdCount := r.rdCount + 1;
389 if r.rdCount = r.rdSize then 398 v.sFifoAxisSlave.tReady := '1';
400 if sFifoAxisMaster.tValid = '1' and sFifoAxisMaster.tLast = '1' then 402 if (not axiStreamPacked(SLAVE_FIFO_SSI_CONFIG_C, sFifoAxisMaster)) then 405 v.state := S_STATUS_C;
410 v.mFifoAxisMaster.tValid := '1';
411 v.mFifoAxisMaster.tLast := '1';
412 v.mFifoAxisMaster.tData(63 downto 0) := (others => '0');
413 v.mFifoAxisMaster.tData(17) := r.timeout;
414 v.mFifoAxisMaster.tData(16) := r.fail;
430 sFifoAxisSlave <= v.sFifoAxisSlave;
431 mFifoAxisMaster <= r.mFifoAxisMaster;
438 r <= rin after TPD_G;
443 ---------------------------------- 445 ----------------------------------
ALTERA_SYN_Gboolean := false
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
in mAxiLiteReadSlaveAxiLiteReadSlaveType
out sAxisCtrlAxiStreamCtrlType
ALTERA_RAM_Gstring := "M9K"
ALTERA_RAM_Gstring := "M9K"
PIPE_STAGES_Gnatural range 0 to 16:= 1
out mAxiLiteWriteMasterAxiLiteWriteMasterType
in mAxiLiteWriteSlaveAxiLiteWriteSlaveType
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
RESP_THOLD_Ginteger range 0 to ( 2** 24):= 1
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
SLAVE_READY_EN_Gboolean := true
FIFO_FIXED_THRESH_Gboolean := true
GEN_SYNC_FIFO_Gboolean := false
USE_BUILT_IN_Gboolean := false
in mAxisSlaveAxiStreamSlaveType
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 2** 8
XIL_DEVICE_Gstring := "7SERIES"
EN_32BIT_ADDR_Gboolean := false
XIL_DEVICE_Gstring := "7SERIES"
GEN_SYNC_FIFO_Gboolean := false
out sAxisSlaveAxiStreamSlaveType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
out mAxiLiteReadMasterAxiLiteReadMasterType
AXI_STREAM_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out sAxisSlaveAxiStreamSlaveType
ALTERA_SYN_Gboolean := false
in sAxisMasterAxiStreamMasterType
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
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
AxiLiteWriteMasterType :=(awaddr =>( others => '0'),awprot =>( others => '0'),awvalid => '0',wdata =>( others => '0'),wstrb =>( others => '1'),wvalid => '0',bready => '1') AXI_LITE_WRITE_MASTER_INIT_C
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
out mAxisMasterAxiStreamMasterType
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
out sAxisCtrlAxiStreamCtrlType
SLAVE_READY_EN_Gboolean := false