1 ------------------------------------------------------------------------------- 2 -- File : AxiStreamScatterGather.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2013-03-01 5 -- Last update: 2015-04-08 6 ------------------------------------------------------------------------------- 7 -- Description: Takes 6 APV bursts with 128 channels of data each and 8 -- transforms them into 128 "MultiSamples" with 6 samples each. 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_unsigned.
all;
22 use ieee.std_logic_arith.
all;
38 -- Master system clock, 125Mhz 42 -- (optional) Axi Bus for status and debug 53 -- longWordCount : out slv(7 downto 0); 54 -- badWordCount : out slv(7 downto 0); 55 -- longWords : out slv(15 downto 0); 56 -- badWords : out slv(15 downto 0); 63 end entity AxiStreamScatterGather;
72 constant RAM_ADDR_LENGTH_C : := bitSize(RAM_DEPTH_RAW_C);
73 constant RAM_DEPTH_C : := 2**RAM_ADDR_LENGTH_C;
75 ------------------------------------------------------------------------------------------------- 77 ------------------------------------------------------------------------------------------------- 78 type RamType is array (0 to RAM_DEPTH_C-1) of slv(SLAVE_DATA_LENGTH_C-1 downto 0);
80 signal txRamRdData : slv(SLAVE_DATA_LENGTH_C-1 downto 0);
82 signal txFifoRdData : sl;
83 signal txFifoValid : sl;
85 -------------------------------------------------------------------------------------------------- 86 type RegType is record 88 rxRamWrData : slv(SLAVE_DATA_LENGTH_C-1 downto 0);
89 rxRamWrAddr : slv(RAM_ADDR_LENGTH_C-1 downto 0);
90 rxSofAddr : slv(RAM_ADDR_LENGTH_C-1 downto 0);
93 rxFrameNumber : slv(bitSize(SEQUENCE_LENGTH_C-1)-1 downto 0);
97 txRamRdAddr : slv(RAM_ADDR_LENGTH_C-1 downto 0);
101 txFrameNumber : slv(bitSize(SEQUENCE_LENGTH_C-1)-1 downto 0);
107 longWordCount : slv(7 downto 0);
108 longWords : slv(15 downto 0);
109 badWordCount : slv(7 downto 0);
110 badWords : slv(15 downto 0);
113 constant REG_INIT_C : RegType := ( 115 rxRamWrData => (others => '0'), 116 rxRamWrAddr => (others => '0'), 117 rxSofAddr => (others => '0'), 119 rxWordCount => (others => '0'), 120 rxFrameNumber => (others => '0'), 124 txRamRdAddr => (others => '0'), 127 txWordCount => (others => '0'), 128 txFrameNumber => (others => '0'), 134 longWordCount => (others => '0'), 135 badWordCount => (others => '0'), 136 longWords => (others => '0'), 137 badWords => (others => '0'));
139 signal r : RegType := REG_INIT_C;
140 signal rin : RegType;
146 ------------------------------------------------------------------------------------------------- 148 ------------------------------------------------------------------------------------------------- 149 ramProc :
process (
axiClk)
is 151 if (rising_edge(axiClk)) then 152 txRamRdData <= ram(conv_integer(r.txRamRdAddr)) after TPD_G;
153 if (r.rxRamWrEn = '1') then 154 ram(conv_integer(r.rxRamWrAddr)) <= r.rxRamWrData after TPD_G;
159 ------------------------------------------------------------------------------------------------- 160 -- Use fifo to indicate to TX side that a new frame is ready 161 ------------------------------------------------------------------------------------------------- 162 StatusFifo :
entity work.
Fifo 174 wr_en => r.rxFifoWrEn,
178 rd_en => r.txFifoRdEn,
179 dout
(0) => txFifoRdData,
180 valid => txFifoValid
);
187 txFifoValid, txRamRdData)
is 188 variable v : RegType;
189 variable mDataLow : ;
190 variable mDataHigh : ;
195 ---------------------------------------------------------------------------------------------- 197 ---------------------------------------------------------------------------------------------- 199 v.rxRamWrData := sSsiMaster.data(SLAVE_DATA_LENGTH_C-1 downto 0);
202 if (sSsiMaster.valid = '1') then 203 -- Default - Write to RAM and increment wr addr by sequence length 204 v.rxWordCount := r.rxWordCount + 1;
205 v.rxRamWrAddr := r.rxRamWrAddr + SEQUENCE_LENGTH_C;
208 -- Protect against long frames by freezing wr addr 210 v.rxRamWrAddr := r.rxRamWrAddr;
212 v.longWordCount := r.longWordCount + 1;
213 v.longWords(r.rxWordCount'range) := r.rxWordCount;
216 -- Log start address on each sof to easily come back to it + 1 on next frame 217 if (sSsiMaster.sof = '1') then 218 v.rxRamWrAddr := r.rxSofAddr;
221 if (sSsiMaster.eof = '1' or sSsiMaster.eofe = '1') then 222 v.rxFrameNumber := r.rxFrameNumber + 1;
223 v.rxWordCount := (others => '0');
224 v.rxError := r.rxError or sSsiMaster.eofe;
226 v.rxSofAddr := r.rxSofAddr + 1;
228 -- Check for proper number of words 231 v.badWordCount := r.badWordCount + 1;
232 v.badWords(r.rxWordCount'range) := r.rxWordCount;
235 -- Check for end of frame sequence 236 if (r.rxFrameNumber = SEQUENCE_LENGTH_C-1) then 237 v.rxFrameNumber := (others => '0');
241 -- v.rxFifoWrData(0) := v.rxError; -- Use v because it could be set this cycle 246 if (r.rxFifoWrEn = '1') then 247 -- Reset rx error after each write. 248 -- Need to check timing on this. 252 ---------------------------------------------------------------------------------------------- 254 ---------------------------------------------------------------------------------------------- 255 v.mSsiMaster.valid := '0';
256 v.mSsiMaster.sof := '0';
257 v.mSsiMaster.eof := '0';
258 v.mSsiMaster.eofe := '0';
262 if (txFifoValid = '1' and r.txFifoRdEn = '0') then 265 v.txRamRdAddr := r.txRamRdAddr + 1;
267 if (r.txRamRdEn = '1') then 268 v.txFrameNumber := r.txFrameNumber + 1;
270 mDataHigh := ((conv_integer(r.txFrameNumber) + 1) * SLAVE_DATA_LENGTH_C) - 1;
271 mDataLow := (conv_integer(r.txFrameNumber) * SLAVE_DATA_LENGTH_C);
272 for i in 0 to SLAVE_DATA_LENGTH_C-1 loop 273 v.mSsiMaster.data(i+mDataLow) := txRamRdData(i);
276 if (r.txFrameNumber = SEQUENCE_LENGTH_C-1) then 277 v.mSsiMaster.valid := '1';
278 v.mSsiMaster.sof := r.txSof;
279 v.mSsiMaster.eofe := r.txSof and txFifoRdData;
-- Assert eofe without eof to indicate sofe 281 v.txFrameNumber := (others => '0');
282 v.txWordCount := r.txWordCount + 1;
284 v.txWordCount := (others => '0');
286 v.mSsiMaster.eof := '1';
287 v.mSsiMaster.eofe := txFifoRdData;
288 v.txRamRdAddr := r.txRamRdAddr;
298 ---------------------------------------------------------------------------------------------- 299 -- Do reset here so that AXI logic can't be reset 300 ---------------------------------------------------------------------------------------------- 307 ---------------------------------------------------------------------------------------------- 309 ---------------------------------------------------------------------------------------------- 317 -- Decode address and assign read data 350 ---------------------------------------------------------------------------------------------- 352 ---------------------------------------------------------------------------------------------- 353 -- if (axiRst = '1') then 357 ---------------------------------------------------------------------------------------------- 359 ---------------------------------------------------------------------------------------------- 367 -- longWordCount <= r.longWordCount; 368 -- badWordCount <= r.badWordCount; 369 -- longWords <= r.longWords; 370 -- badWords <= r.badWords; 375 sync :
process (
axiClk)
is 377 if (rising_edge(axiClk)) then 378 r <= rin after TPD_G;
383 end architecture rtl;
out sAxisCtrlAxiStreamCtrlType
FWFT_EN_Gboolean := false
out mAxisMasterAxiStreamMasterType
in axilReadMasterAxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C
natural range 1 to 16 TDATA_BYTES_C
SLAVE_AXIS_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 2)
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
AXIS_SLAVE_FRAME_SIZE_Ginteger := 129
in mAxisSlaveAxiStreamSlaveType
out axilWriteSlaveAxiLiteWriteSlaveType
in axilWriteMasterAxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
GEN_SYNC_FIFO_Gboolean := false
out axilReadSlaveAxiLiteReadSlaveType
MASTER_AXIS_CONFIG_GAxiStreamConfigType := ssiAxiStreamConfig( 12)
AxiLiteReadMasterType :=(araddr =>( others => '0'),arprot =>( others => '0'),arvalid => '0',rready => '1') AXI_LITE_READ_MASTER_INIT_C
AxiStreamCtrlType :=(pause => '0',overflow => '0',idle => '1') AXI_STREAM_CTRL_UNUSED_C
in rstsl :=not RST_POLARITY_G
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
ADDR_WIDTH_Ginteger range 4 to 48:= 4
USE_BUILT_IN_Gboolean := false
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
out sAxisSlaveAxiStreamSlaveType
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
in mAxisCtrlAxiStreamCtrlType
in sAxisMasterAxiStreamMasterType