SURF  1.0
AxiWritePathMux.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiWritePathMux.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-25
5 -- Last update: 2014-04-29
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Block to connect multiple incoming AXI write path interfaces.
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 use ieee.std_logic_arith.all;
22 use ieee.std_logic_unsigned.all;
23 
24 use work.StdRtlPkg.all;
25 use work.ArbiterPkg.all;
26 use work.AxiPkg.all;
27 
28 --! @see entity
29  --! @ingroup axi
30 entity AxiWritePathMux is
31  generic (
32  TPD_G : time := 1 ns;
33  NUM_SLAVES_G : integer range 1 to 32 := 4
34  );
35  port (
36 
37  -- Clock and reset
38  axiClk : in sl;
39  axiRst : in sl;
40 
41  -- Slaves
44 
45  -- Master
48  );
49 end AxiWritePathMux;
50 
51 architecture structure of AxiWritePathMux is
52 
53  constant DEST_SIZE_C : integer := bitSize(NUM_SLAVES_G-1);
54  constant ARB_BITS_C : integer := 2**DEST_SIZE_C;
55 
56  --------------------------
57  -- Address Path
58  --------------------------
59 
60  type StateType is (S_IDLE_C, S_MOVE_C, S_LAST_C, S_WAIT_C);
61 
62  type RegType is record
64  addrAcks : slv(ARB_BITS_C-1 downto 0);
65  addrAckNum : slv(DEST_SIZE_C-1 downto 0);
70  dataAckNum : slv(DEST_SIZE_C-1 downto 0);
73  end record RegType;
74 
75  constant REG_INIT_C : RegType := (
76  addrState => S_IDLE_C,
77  addrAcks => (others => '0'),
78  addrAckNum => (others => '0'),
79  addrValid => '0',
80  dataReq => '0',
81  dataAck => '0',
82  dataState => S_IDLE_C,
83  dataAckNum => (others => '0'),
84  slaves => (others => AXI_WRITE_SLAVE_INIT_C),
86  );
87 
88  signal r : RegType := REG_INIT_C;
89  signal rin : RegType;
90 
91 begin
92 
93  comb : process (axiRst, r, sAxiWriteMasters, mAxiWriteSlave) is
94  variable v : RegType;
95  variable addrRequests : slv(ARB_BITS_C-1 downto 0);
96  variable selAddr : AxiWriteMasterType;
97  variable selData : AxiWriteMasterType;
98  begin
99  v := r;
100 
101  ----------------------------
102  -- Address Path
103  ----------------------------
104 
105  -- Init Slave Ready
106  for i in 0 to (NUM_SLAVES_G-1) loop
107  v.slaves(i).awready := '0';
108  end loop;
109 
110  -- Select address source
111  selAddr := sAxiWriteMasters(conv_integer(r.addrAckNum));
112  selAddr.awid := (others => '0');
113 
114  selAddr.awid(DEST_SIZE_C-1 downto 0) := r.addrAckNum;
115 
116  -- Format requests
117  addrRequests := (others=>'0');
118  for i in 0 to (NUM_SLAVES_G-1) loop
119  addrRequests(i) := sAxiWriteMasters(i).awvalid;
120  end loop;
121 
122  -- Addr State machine
123  case r.addrState is
124 
125  -- IDLE
126  when S_IDLE_C =>
127  v.master.awvalid := '0';
128  v.dataReq := '0';
129 
130  -- Aribrate between requesters
131  if r.addrValid = '0' then
132  arbitrate(addrRequests, r.addrAckNum, v.addrAckNum, v.addrValid, v.addrAcks);
133  end if;
134 
135  -- Valid request
136  if r.addrValid = '1' then
137  v.addrState := S_MOVE_C;
138  end if;
139 
140  -- Move one entry
141  when S_MOVE_C =>
142  v.addrValid := '0';
143 
144  -- Assert ready
145  v.slaves(conv_integer(r.addrAckNum)).awready := '1';
146 
147  -- Advance pipeline
148  v.master.awvalid := '1';
149  v.master.awaddr := selAddr.awaddr;
150  v.master.awid := selAddr.awid;
151  v.master.awlen := selAddr.awlen;
152  v.master.awsize := selAddr.awsize;
153  v.master.awburst := selAddr.awburst;
154  v.master.awlock := selAddr.awlock;
155  v.master.awprot := selAddr.awprot;
156  v.master.awcache := selAddr.awcache;
157  v.addrState := S_LAST_C;
158 
159  -- Last transfer
160  when S_LAST_C =>
161  if mAxiWriteSlave.awready = '1' then
162  v.master.awvalid := '0';
163  v.addrState := S_WAIT_C;
164  v.dataReq := '1';
165  end if;
166 
167  -- Wait for data
168  when S_WAIT_C =>
169  if r.dataAck = '1' then
170  v.dataReq := '0';
171  v.addrState := S_IDLE_C;
172  end if;
173  end case;
174 
175  ----------------------------
176  -- Data Path
177  ----------------------------
178 
179  -- Init Slave Ready
180  for i in 0 to (NUM_SLAVES_G-1) loop
181  v.slaves(i).wready := '0';
182  end loop;
183 
184  -- Select data source
185  selData := sAxiWriteMasters(conv_integer(r.dataAckNum));
186  selData.wid := (others => '0');
187 
188  selData.wid(DEST_SIZE_C-1 downto 0) := r.dataAckNum;
189 
190  -- Data State machine
191  case r.dataState is
192 
193  -- IDLE
194  when S_IDLE_C =>
195  v.master.wvalid := '0';
196  v.dataAck := '0';
197 
198  if v.dataReq = '1' then
199  v.dataAck := '1';
200  v.dataAckNum := r.addrAckNum;
201  v.dataState := S_MOVE_C;
202  end if;
203 
204  -- Move a frame until tLast
205  when S_MOVE_C =>
206  v.dataAck := '0';
207 
208  -- Advance pipeline
209  if r.master.wvalid = '0' or mAxiWriteSlave.wready = '1' then
210  v.master.wdata := selData.wdata;
211  v.master.wlast := selData.wlast;
212  v.master.wvalid := selData.wvalid;
213  v.master.wstrb := selData.wstrb;
214  v.master.wid := selData.wid;
215 
216  -- Ready
217  v.slaves(conv_integer(r.dataAckNum)).wready := '1';
218 
219  -- wlast to be presented
220  if selData.wlast = '1' and selData.wvalid = '1' then
221  v.dataState := S_LAST_C;
222  end if;
223  end if;
224 
225  -- Laster transfer
226  when S_LAST_C =>
227  if mAxiWriteSlave.wready = '1' then
228  v.master.wvalid := '0';
229  v.dataState := S_IDLE_C;
230  end if;
231 
232  -- Not valid
233  when S_WAIT_C =>
234  v.dataState := S_IDLE_C;
235 
236  end case;
237 
238  ----------------------------
239  -- Response Path
240  ----------------------------
241 
242  -- Clear existing valids
243  for i in 0 to (NUM_SLAVES_G-1) loop
244  if sAxiWriteMasters(i).bready = '1' then
245  v.slaves(i).bvalid := '0';
246  end if;
247  end loop;
248 
249  -- Pass response to destination
250  if r.slaves(conv_integer(mAxiWriteSlave.bid(DEST_SIZE_C-1 downto 0))).bvalid = '0' or
251  sAxiWriteMasters(conv_integer(mAxiWriteSlave.bid(DEST_SIZE_C-1 downto 0))).bready = '1' then
252 
253  v.slaves(conv_integer(mAxiWriteSlave.bid(DEST_SIZE_C-1 downto 0))).bresp := mAxiWriteSlave.bresp;
254  v.slaves(conv_integer(mAxiWriteSlave.bid(DEST_SIZE_C-1 downto 0))).bvalid := mAxiWriteSlave.bvalid;
255  v.slaves(conv_integer(mAxiWriteSlave.bid(DEST_SIZE_C-1 downto 0))).bid := mAxiWriteSlave.bid;
256  v.master.bready := '1';
257  else
258  v.master.bready := '0';
259  end if;
260 
261  if (axiRst = '1') or (NUM_SLAVES_G = 1) then
262  v := REG_INIT_C;
263  end if;
264 
265  rin <= v;
266 
267  -- Bypass if single slave
268  if NUM_SLAVES_G = 1 then
270  mAxiWriteMaster <= sAxiWritemasters(0);
271  else
272 
273  -- Output data
276 
277  -- Readies are direct
278  for i in 0 to (NUM_SLAVES_G-1) loop
280  sAxiWriteSlaves(i).wready <= v.slaves(i).wready;
281  end loop;
283  end if;
284 
285  end process comb;
286 
287  seq : process (axiClk) is
288  begin
289  if (rising_edge(axiClk)) then
290  r <= rin after TPD_G;
291  end if;
292  end process seq;
293 
294 end structure;
AxiWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0',bid =>( others => '0')) AXI_WRITE_SLAVE_INIT_C
Definition: AxiPkg.vhd:182
integer := 2** DEST_SIZE_C ARB_BITS_C
out sAxiWriteSlavesAxiWriteSlaveArray( NUM_SLAVES_G- 1 downto 0)
slv( 2 downto 0) awprot
Definition: AxiPkg.vhd:117
sl wvalid
Definition: AxiPkg.vhd:124
slv( 1 downto 0) awlock
Definition: AxiPkg.vhd:116
sl bvalid
Definition: AxiPkg.vhd:178
RegType :=(addrState => S_IDLE_C,addrAcks =>( others => '0'),addrAckNum =>( others => '0'),addrValid => '0',dataReq => '0',dataAck => '0',dataState => S_IDLE_C,dataAckNum =>( others => '0'),slaves =>( others => AXI_WRITE_SLAVE_INIT_C),master => AXI_WRITE_MASTER_INIT_C) REG_INIT_C
std_logic sl
Definition: StdRtlPkg.vhd:28
sl wlast
Definition: AxiPkg.vhd:123
slv( 1023 downto 0) wdata
Definition: AxiPkg.vhd:122
slv( 7 downto 0) awlen
Definition: AxiPkg.vhd:113
RegType := REG_INIT_C r
_library_ ieeeieee
AxiWriteMasterType master
slv( 2 downto 0) awsize
Definition: AxiPkg.vhd:114
sl awready
Definition: AxiPkg.vhd:173
sl bready
Definition: AxiPkg.vhd:128
slv( 127 downto 0) wstrb
Definition: AxiPkg.vhd:126
in mAxiWriteSlaveAxiWriteSlaveType
slv( 31 downto 0) bid
Definition: AxiPkg.vhd:179
in sAxiWriteMastersAxiWriteMasterArray( NUM_SLAVES_G- 1 downto 0)
AxiWriteMasterType
Definition: AxiPkg.vhd:108
slv( ARB_BITS_C- 1 downto 0) addrAcks
(S_IDLE_C,S_MOVE_C,S_LAST_C,S_WAIT_C) StateType
sl wready
Definition: AxiPkg.vhd:175
sl awvalid
Definition: AxiPkg.vhd:110
slv( DEST_SIZE_C- 1 downto 0) dataAckNum
NUM_SLAVES_Ginteger range 1 to 32:= 4
integer := bitSize( NUM_SLAVES_G- 1) DEST_SIZE_C
AxiWriteSlaveType
Definition: AxiPkg.vhd:171
AxiWriteSlaveArray( NUM_SLAVES_G- 1 downto 0) slaves
slv( 31 downto 0) wid
Definition: AxiPkg.vhd:125
slv( 1 downto 0) awburst
Definition: AxiPkg.vhd:115
slv( 3 downto 0) awcache
Definition: AxiPkg.vhd:118
array(natural range <> ) of AxiWriteMasterType AxiWriteMasterArray
Definition: AxiPkg.vhd:130
slv( 63 downto 0) awaddr
Definition: AxiPkg.vhd:111
out mAxiWriteMasterAxiWriteMasterType
slv( 31 downto 0) awid
Definition: AxiPkg.vhd:112
slv( DEST_SIZE_C- 1 downto 0) addrAckNum
array(natural range <> ) of AxiWriteSlaveType AxiWriteSlaveArray
Definition: AxiPkg.vhd:181
slv( 1 downto 0) bresp
Definition: AxiPkg.vhd:177
TPD_Gtime := 1 ns
AxiWriteMasterType :=(awvalid => '0',awaddr =>( others => '0'),awid =>( others => '0'),awlen =>( others => '0'),awsize =>( others => '0'),awburst =>( others => '0'),awlock =>( others => '0'),awprot =>( others => '0'),awcache =>( others => '0'),awqos =>( others => '0'),awregion =>( others => '0'),wdata =>( others => '0'),wlast => '0',wvalid => '0',wid =>( others => '0'),wstrb =>( others => '0'),bready => '0') AXI_WRITE_MASTER_INIT_C
Definition: AxiPkg.vhd:131
std_logic_vector slv
Definition: StdRtlPkg.vhd:29