SURF  1.0
AxiStreamPipeline.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamPipeline.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-05-01
5 -- Last update: 2016-09-06
6 -------------------------------------------------------------------------------
7 -- Description: This module is used to sync a AxiStream bus
8 -- either as a pass through or with pipeline register stages.
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 -------------------------------------------------------------------------------
18 
19 library ieee;
20 use ieee.std_logic_1164.all;
21 
22 use work.StdRtlPkg.all;
23 use work.AxiStreamPkg.all;
24 
25 --! @see entity
26  --! @ingroup axi
28  generic (
29  TPD_G : time := 1 ns;
30  PIPE_STAGES_G : natural range 0 to 16 := 0);
31  port (
32  -- Clock and Reset
33  axisClk : in sl;
34  axisRst : in sl;
35  -- Slave Port
38  -- Master Port
41 end AxiStreamPipeline;
42 
43 architecture rtl of AxiStreamPipeline is
44 
45  constant PIPE_STAGES_C : natural := PIPE_STAGES_G+1;
46 
47  type RegType is record
49  mAxisMaster : AxiStreamMasterArray(0 to PIPE_STAGES_C);
50  end record RegType;
51 
52  constant REG_INIT_C : RegType := (
54  (others => AXI_STREAM_MASTER_INIT_C));
55 
56  signal r : RegType := REG_INIT_C;
57  signal rin : RegType;
58 
59 begin
60 
61  ZERO_LATENCY : if (PIPE_STAGES_G = 0) generate
62 
65 
66  end generate;
67 
68  PIPE_REG : if (PIPE_STAGES_G > 0) generate
69 
70  comb : process (axisRst, mAxisSlave, r, sAxisMaster) is
71  variable v : RegType;
72  variable i : natural;
73  begin
74  -- Latch the current value
75  v := r;
76 
77  -- Check if we need to shift register
78  if (r.mAxisMaster(PIPE_STAGES_C).tValid = '0') or (mAxisSlave.tReady = '1') then
79  -- Shift the data up the pipeline
80  for i in PIPE_STAGES_C downto 2 loop
81  v.mAxisMaster(i) := r.mAxisMaster(i-1);
82  end loop;
83  -- Check if the lowest cell is empty
84  if r.mAxisMaster(0).tValid = '0' then
85  -- Set the ready bit
86  v.sAxisSlave.tReady := '1';
87  -- Check if we were pulling the FIFO last clock cycle
88  if r.sAxisSlave.tReady = '1' then
89  -- Shift the FIFO data
90  v.mAxisMaster(1) := sAxisMaster;
91  else
92  -- Clear valid in stage 1
93  v.mAxisMaster(1).tValid := '0';
94  end if;
95  else
96  -- Shift the lowest cell
97  v.mAxisMaster(1) := r.mAxisMaster(0);
98  -- Check if we were pulling the FIFO last clock cycle
99  if r.sAxisSlave.tReady = '1' then
100  -- Reset the ready bit
101  v.sAxisSlave.tReady := '0';
102  -- Fill the lowest cell
103  v.mAxisMaster(0) := sAxisMaster;
104  else
105  -- Set the ready bit
106  v.sAxisSlave.tReady := '1';
107  -- Reset the lowest cell tValid
108  v.mAxisMaster(0).tValid := '0';
109  end if;
110  end if;
111  else
112  -- Reset the ready bit
113  v.sAxisSlave.tReady := '0';
114  -- Check if we were pulling the FIFO last clock cycle
115  if r.sAxisSlave.tReady = '1' then
116  -- Fill the lowest cell
117  v.mAxisMaster(0) := sAxisMaster;
118  elsif r.mAxisMaster(0).tValid = '0' then
119  -- Set the ready bit
120  v.sAxisSlave.tReady := '1';
121  end if;
122  -- Check if we need to internally shift the data to remove gaps
123  for i in PIPE_STAGES_C-1 downto 1 loop
124  -- Check for empty cell ahead of a filled cell
125  if (r.mAxisMaster(i).tValid = '0') and (r.mAxisMaster(i-1).tValid = '1') then
126  -- Shift the lowest cell
127  v.mAxisMaster(i) := r.mAxisMaster(i-1);
128  -- Reset the flag
129  v.mAxisMaster(i-1).tValid := '0';
130  end if;
131  end loop;
132  end if;
133 
134  -- Synchronous Reset
135  if axisRst = '1' then
136  v := REG_INIT_C;
137  end if;
138 
139  -- Register the variable for next clock cycle
140  rin <= v;
141 
142  -- Outputs
143  sAxisSlave <= r.sAxisSlave;
144  mAxisMaster <= r.mAxisMaster(PIPE_STAGES_C);
145 
146  end process comb;
147 
148  seq : process (axisClk) is
149  begin
150  if rising_edge(axisClk) then
151  r <= rin after TPD_G;
152  end if;
153  end process seq;
154 
155  end generate;
156 
157 end rtl;
PIPE_STAGES_Gnatural range 0 to 16:= 0
std_logic sl
Definition: StdRtlPkg.vhd:28
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
out sAxisSlaveAxiStreamSlaveType
in mAxisSlaveAxiStreamSlaveType
in sAxisMasterAxiStreamMasterType
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
out mAxisMasterAxiStreamMasterType