Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_rmu_lrm_itsb_fsm.v | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | module dmu_rmu_lrm_itsb_fsm ( | |
36 | ||
37 | clk, | |
38 | rst_l, | |
39 | ||
40 | // TSB Interface - Ingress Pipeline | |
41 | rm2ts_i_cmd_type, | |
42 | rm2ts_i_wr_data, | |
43 | rm2ts_i_req, | |
44 | ||
45 | ts2rm_i_gnt, | |
46 | ts2rm_i_n_trn, | |
47 | ||
48 | // Internal LRM Output Control Interface - lrm_octl - Outgoing LRM rcd | |
49 | lrm_rcd, | |
50 | lrm_rcd_enq, | |
51 | lrm_rcd_deq, | |
52 | ||
53 | // Internal LRM Input Control Interface - lrm_ictl - Incoming STD rcd | |
54 | std_rcd, | |
55 | std_rcd_enq, | |
56 | std_rcd_deq, | |
57 | ||
58 | // Outputs (local) for Debug Port Visibility | |
59 | trans_type, | |
60 | sr_std_empty, | |
61 | itsb_state, | |
62 | lrm_credit_ok, | |
63 | dma_rd_bcnt | |
64 | ||
65 | ); | |
66 | ||
67 | // synopsys sync_set_reset "rst_l" | |
68 | ||
69 | ||
70 | //############################################################################ | |
71 | // PORT DECLARATIONS | |
72 | //############################################################################ | |
73 | ||
74 | //------------------------------------------------------------------------ | |
75 | // Clock and Reset Signals | |
76 | //------------------------------------------------------------------------ | |
77 | input clk; | |
78 | input rst_l; | |
79 | ||
80 | ||
81 | //------------------------------------------------------------------------ | |
82 | // TSB Interface | |
83 | //------------------------------------------------------------------------ | |
84 | ||
85 | // TSB interface (Ingress Pipeline) | |
86 | output [`FIRE_DLC_TSR_CMD_TYPE_WDTH-1:0] rm2ts_i_cmd_type; // 4 bit TSB Command | |
87 | output [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] rm2ts_i_wr_data; // 48 bit Write Data | |
88 | output rm2ts_i_req; | |
89 | ||
90 | input ts2rm_i_gnt; | |
91 | input [`FIRE_DLC_TSR_TRN_WDTH-1:0] ts2rm_i_n_trn; // 5 bit TRN - Trans Scoreboard Tag | |
92 | ||
93 | ||
94 | //------------------------------------------------------------------------ | |
95 | // Internal LRM Interface to LRM Output Control Module | |
96 | //------------------------------------------------------------------------ | |
97 | ||
98 | output [`FIRE_DLC_RMU_LRM_WDTH-1:0] lrm_rcd; | |
99 | output lrm_rcd_enq; | |
100 | ||
101 | input lrm_rcd_deq; // LRM FIFO deq | |
102 | ||
103 | ||
104 | //------------------------------------------------------------------------ | |
105 | // Internal LRM Interface to LRM Input Control Module | |
106 | //------------------------------------------------------------------------ | |
107 | ||
108 | // Standard Records (other than rcd's destined to IMU or RRM) | |
109 | // Note: STD Record defined identically as the IIN record | |
110 | input [`FIRE_DLC_RMU_LRM_WDTH-1:0] std_rcd; // 131 bit Std Rcd | |
111 | input std_rcd_enq; // Std Rcd FIFO Enqueue | |
112 | ||
113 | output std_rcd_deq; // SR Std Rcd Dequeue | |
114 | ||
115 | ||
116 | //------------------------------------------------------------------------ | |
117 | // Outputs for Debug Port Visibility | |
118 | //------------------------------------------------------------------------ | |
119 | ||
120 | output [1:0] trans_type; // SR STD rcd trans type decoder | |
121 | output sr_std_empty; // STD SR fifo is empty | |
122 | output [4:0] itsb_state; // Ingress TSB 1-hot FSM | |
123 | output lrm_credit_ok; // OK to enqueue LRM rcd | |
124 | output [`FIRE_DLC_TSR_BYTECNT_WDTH:0] dma_rd_bcnt; // 13 bit bcnt calc [12:0] for dma_rd | |
125 | ||
126 | ||
127 | //############################################################################ | |
128 | // PARAMETERS | |
129 | //############################################################################ | |
130 | ||
131 | // Ingress Transaction Type Decoder Parameters | |
132 | ||
133 | parameter | |
134 | SEND2OCTL = 2'b00, // Send Record Up Pipeline | |
135 | NP_DMA_TSB = 2'b01, // DMA Rd transaction requiring TSB access | |
136 | NP_UR_TSB = 2'b10, // Unsupported Request requiring TSB access | |
137 | UNDEFINED = 2'b11; // undefined type | |
138 | ||
139 | parameter | |
140 | DMA_MRD32 = 7'b0000000, // NP_DMA_TSB class | |
141 | DMA_MRD64 = 7'b0100000, // NP_DMA_TSB class | |
142 | DMA_MRDLK32 = 7'b0000001, // NP_DMA_TSB class | |
143 | DMA_MRDLK64 = 7'b0100001, // NP_DMA_TSB class | |
144 | DMA_UR = 7'b0001001, // NP_DMA_TSB class | |
145 | DMA_MWR32 = 7'b1000000, // will send straight to MMU | |
146 | DMA_MWR64 = 7'b1100000, // will send straight to MMU | |
147 | // MSI_EQWR_32 = 7'b1011000, // should not be seen in this module | |
148 | // MSI_EQWR_64 = 7'b1111000, // should not be seen in this module | |
149 | // MSG_EQWR_32 = 7'b1010000, // should not be seen in this module | |
150 | // MSG_EQWR_64 = 7'b1110000, // should not be seen in this module | |
151 | // NULL = 7'b1111100, // should not be seen in this module | |
152 | // MONDO = 7'b1111010, // should not be seen in this module | |
153 | PIO_CPLD = 7'b1001010, // will send straight to MMU | |
154 | PIO_CPL = 7'b0001010; // will send straight to MMU | |
155 | ||
156 | ||
157 | // Ingress Transaction Scoreboard Parameters | |
158 | parameter | |
159 | TRN_REQ_WR = 4'b0101; // TSB command - Request TRN and Write Data to TRN addr | |
160 | ||
161 | ||
162 | // LRM Ingress TSB Finite State Machine Parameters | |
163 | ||
164 | parameter | |
165 | I_PROCESS = 0, // FSM ready to process STD records (PIO's, Posted DMA's -DMAWRs) | |
166 | I_LDPIPE = 1, // TSB Write Access in progress - Load Pipeline, DEQ next STD rcd | |
167 | I_ENQPIPE = 2, // Complete TSB access and ENQ LRM Rcd - check if another TSB access | |
168 | I_STALL1 = 3, // No lrm_credits while accessing TSB - finish TSB and chk credit | |
169 | I_STALL2 = 4; // Pipelined TSB access completed, but had no credits - ENQ when OK! | |
170 | ||
171 | parameter | |
172 | NUM_STATES = 5; | |
173 | ||
174 | ||
175 | // LRM Record FIFO Parameters Width = 123, Depth = 5 | |
176 | ||
177 | parameter | |
178 | STD_SR_WIDTH = `FIRE_DLC_RMU_LRM_WDTH, // 131 bits | |
179 | STD_SR_DEPTH = 4; // 4 deep | |
180 | ||
181 | ||
182 | //############################################################################ | |
183 | // SIGNAL DECLARATIONS | |
184 | //############################################################################ | |
185 | ||
186 | // Only (1) type of TSB command supported from Ingress Path - TRN Request w Write | |
187 | wire [`FIRE_DLC_TSR_CMD_TYPE_WDTH-1:0] rm2ts_i_cmd_type; // 4 bit TSB Command | |
188 | ||
189 | ||
190 | //************************************************** | |
191 | // Internal Sub-Block Wires | |
192 | //************************************************** | |
193 | ||
194 | // Incoming STD Record fields out of the SR fifo - 131 bit STD record | |
195 | ||
196 | wire [`FIRE_DLC_RMU_LRM_WDTH-1:0] sr_std_dout; // Entire STD-LRM Record | |
197 | ||
198 | wire [`FIRE_DLC_RMU_LRM_TYPE_WDTH-1:0] sr_std_type; // 7 bit Type Field | |
199 | wire [`FIRE_DLC_RMU_LRM_TC_WDTH-1:0] sr_std_tc; // 3 bit TC field | |
200 | wire [`FIRE_DLC_RMU_LRM_ATR_WDTH-1:0] sr_std_atr; // 2 bit Atr field | |
201 | wire [`FIRE_DLC_RMU_LRM_LEN_WDTH-1:0] sr_std_len; // 10 bit Length | |
202 | wire [`FIRE_DLC_RMU_LRM_REQID_WDTH-1:0] sr_std_reqid; // 16 bit Reqid | |
203 | wire [`FIRE_DLC_RMU_LRM_TAG_WDTH-1:0] sr_std_tag; // 8 bit tlptag | |
204 | wire [`FIRE_DLC_RMU_LRM_LDWBE_WDTH-1:0] sr_std_ldwbe; // 4 bit last DWBE | |
205 | wire [`FIRE_DLC_RMU_LRM_FDWBE_WDTH-1:0] sr_std_fdwbe; // 4 bit first DWBE | |
206 | wire [`FIRE_DLC_RMU_LRM_ADDR_WDTH-1:0] sr_std_addr; // 62 bit Addr | |
207 | wire [`FIRE_DLC_RMU_LRM_DPTR_WDTH-1:0] sr_std_dptr; // 7 bit Data Pointer | |
208 | wire [`FIRE_DLC_RMU_LRM_LRMTAG_WDTH-1:0] sr_std_lrmtag; // 8 bit sbdtag | |
209 | ||
210 | ||
211 | wire lrm_credit_ok; // OK to enqueue LRM rcd | |
212 | wire sr_std_empty; // STD SR fifo is empty | |
213 | ||
214 | ||
215 | wire [`FIRE_DLC_RMU_LRM_WDTH-1:0] std_lrm_rcd; // concatenation of entire std_dout rcd | |
216 | wire [`FIRE_DLC_RMU_LRM_WDTH-1:0] tsb_lrm_rcd; // concatenation of entire pipelined rcd | |
217 | ||
218 | ||
219 | // Fields Used for TSB byte count and lower addr calculations | |
220 | wire [`FIRE_DLC_TSR_BYTECNT_WDTH-1:0] tsb_bcnt; // 12 bit bcnt written to TSB | |
221 | wire [`FIRE_DLC_TSR_BYTECNT_WDTH:0] dma_rd_bcnt; // 13 bit bcnt calc [12:0] for dma_rd | |
222 | wire [`FIRE_DLC_TSR_BYTECNT_WDTH:0] dma_rd_bcnt_mult_dws; // 13 bit bcnt calc [12:0] for multi dw | |
223 | wire [`FIRE_DLC_TSR_BYTECNT_WDTH:0] dma_rd_len_total_bc; // 13 bit bcnt calc [12:0] from pkt LEN | |
224 | // before bytes subtracted from BE's | |
225 | ||
226 | wire [`FIRE_DLC_TSR_ADALIGN_WDTH-1:0] tsb_lower_addr; // 7 bit address | |
227 | wire [`FIRE_DLC_TSR_ADALIGN_WDTH-1:0] dma_rd_addr; // 7 bit address | |
228 | ||
229 | wire [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] next_tsb_write_data; // 48 bit tsb wr data | |
230 | ||
231 | wire [2:0] total_bytes_off; // 3 bit temporary adder for bcnt calc | |
232 | wire [1:0] dma_rd_lower_addr; // 2 bit byte aligned lower addr from DMA RD | |
233 | wire dma_rd_len_eq_dw; // DMA Rd LEN == 1 DW | |
234 | wire dma_rd_len_fourk; // DMA Rd LEN == 0's -> so 4K! | |
235 | ||
236 | // Miscellaneous Wires | |
237 | ||
238 | wire tsb_vld; // transaction type requiring TSB access | |
239 | wire tsb_lrm_rcd_sel; // Registered lrm rcd mux select | |
240 | wire ld_tsb_pipe_reg; // Load tsb_lrm_reg's from sr_std_dout | |
241 | wire ld_tsb_sbdtag_reg; // Load tsb trn tag into upbound LRM rcd | |
242 | wire [`FIRE_DLC_TSR_TRN_WDTH-1:0] tsb_lrm_sbdtag; // Muxed Output for the 5 bit TSB tag | |
243 | ||
244 | ||
245 | //************************************************** | |
246 | // Registers that Are Not Flops | |
247 | //************************************************** | |
248 | ||
249 | reg [1:0] trans_type; // SR STD rcd trans type decoder | |
250 | reg std_rcd_deq; // SR STD rcd dequeue signal | |
251 | reg lrm_rcd_enq; // LRM rcd enqueue signal | |
252 | reg ld_tsb_wr_data; // Load Enable for TSB WR data | |
253 | ||
254 | // Signals used to help calculate DMA RD byte count for TSB accesses | |
255 | reg [1:0] bytes_off_frst_dwbe; // Bytes to be subtracted from FDWBE | |
256 | reg [1:0] bytes_off_last_dwbe; // Bytes to be subtracted from LDWBE | |
257 | reg [2:0] dma_rd_bcnt_one_dw; // Value is 1,2,3 or 4 | |
258 | ||
259 | ||
260 | //************************************************** | |
261 | // Registers that Are Flops | |
262 | //************************************************** | |
263 | ||
264 | // LRM Ingress TSB FSM 1-hot state machine | |
265 | reg [NUM_STATES-1:0] itsb_state, next_itsb_state; // 1-hot FSM | |
266 | ||
267 | ||
268 | // Registered TSB Outputs | |
269 | reg [`FIRE_DLC_TSR_WR_DATA_WDTH-1:0] rm2ts_i_wr_data; // 48 bit Write Data | |
270 | reg rm2ts_i_req, next_rm2ts_i_req; // TSB Request Signal | |
271 | ||
272 | ||
273 | // LRM FIFO credit mechanism - STD rcd and LRM rcd FIFO's sized to depth of 4 | |
274 | reg [2:0] lrm_credit_count, next_lrm_credit_count; // 3 bit credit count | |
275 | ||
276 | ||
277 | // tsb_lrm_reg's - Pipelined registers fro STD rcd's that need TSB access - allows streaming | |
278 | reg [`FIRE_DLC_RMU_LRM_TYPE_WDTH-1:0] tsb_reg_type; // 7 bit Type Field | |
279 | reg [`FIRE_DLC_RMU_LRM_TC_WDTH-1:0] tsb_reg_tc; // 3 bit TC field | |
280 | reg [`FIRE_DLC_RMU_LRM_ATR_WDTH-1:0] tsb_reg_atr; // 2 bit Atr field | |
281 | reg [`FIRE_DLC_RMU_LRM_LEN_WDTH-1:0] tsb_reg_len; // 10 bit Length | |
282 | reg [`FIRE_DLC_RMU_LRM_REQID_WDTH-1:0] tsb_reg_reqid; // 16 bit Reqid | |
283 | reg [`FIRE_DLC_RMU_LRM_LDWBE_WDTH-1:0] tsb_reg_ldwbe; // 4 bit last DWBE | |
284 | reg [`FIRE_DLC_RMU_LRM_FDWBE_WDTH-1:0] tsb_reg_fdwbe; // 4 bit first DWBE | |
285 | reg [`FIRE_DLC_RMU_LRM_ADDR_WDTH-1:0] tsb_reg_addr; // 62 bit Addr | |
286 | reg [`FIRE_DLC_RMU_LRM_DPTR_WDTH-1:0] tsb_reg_dptr; // 7 bit Data Pointer | |
287 | reg [`FIRE_DLC_RMU_LRM_LRMTAG_WDTH-1:0] tsb_reg_lrmtag; // 8 bit sbdtag | |
288 | ||
289 | reg [`FIRE_DLC_TSR_TRN_WDTH-1:0] tsb_reg_sbdtag; // 5 bit TSB index tag | |
290 | // 123 registers total | |
291 | ||
292 | ||
293 | //############################################################################ | |
294 | // ZERO IN CHECKERS | |
295 | //############################################################################ | |
296 | ||
297 | /* 0in state -var itsb_state | |
298 | -val (5'b00001 << I_PROCESS) | |
299 | -next (5'b00001 << I_LDPIPE) | |
300 | */ | |
301 | ||
302 | /* 0in state -var itsb_state | |
303 | -val (5'b00001 << I_LDPIPE) | |
304 | -next (5'b00001 << I_ENQPIPE) | |
305 | (5'b00001 << I_STALL1) | |
306 | */ | |
307 | ||
308 | /* 0in state -var itsb_state | |
309 | -val (5'b00001 << I_ENQPIPE) | |
310 | -next (5'b00001 << I_LDPIPE) | |
311 | (5'b00001 << I_PROCESS) | |
312 | */ | |
313 | ||
314 | /* 0in state -var itsb_state | |
315 | -val (5'b00001 << I_STALL1) | |
316 | -next (5'b00001 << I_STALL2) | |
317 | (5'b00001 << I_LDPIPE) | |
318 | (5'b00001 << I_PROCESS) | |
319 | */ | |
320 | ||
321 | /* 0in state -var itsb_state | |
322 | -val (5'b00001 << I_STALL2) | |
323 | -next (5'b00001 << I_LDPIPE) | |
324 | (5'b00001 << I_PROCESS) | |
325 | */ | |
326 | ||
327 | // 0in one_hot -var itsb_state | |
328 | ||
329 | // 0in maximum -var lrm_credit_count -val 4 | |
330 | ||
331 | // 0in maximum -var trans_type -val 2 | |
332 | ||
333 | ||
334 | // Other POTENTIAL areas for Zero In | |
335 | // make sure rm2ts_wr_data doesnt change while rm2ts_req asserted | |
336 | ||
337 | ||
338 | /* 0in constant -var rm2ts_i_wr_data | |
339 | -active ts2rm_i_gnt | |
340 | */ | |
341 | ||
342 | ||
343 | ||
344 | ||
345 | //############################################################################ | |
346 | // COMBINATIONAL LOGIC | |
347 | //############################################################################ | |
348 | ||
349 | // Only (1) type of TSB command supported from Ingress Path - TRN Request w Write | |
350 | assign rm2ts_i_cmd_type = TRN_REQ_WR; // TSB Command - TRN request w write | |
351 | ||
352 | ||
353 | //--------------------------------------------------------------------------- | |
354 | // Outgoing LRM record to LRM Output Control Module | |
355 | //--------------------------------------------------------------------------- | |
356 | ||
357 | assign lrm_rcd = tsb_lrm_rcd_sel ? tsb_lrm_rcd : std_lrm_rcd; | |
358 | ||
359 | assign std_lrm_rcd = { | |
360 | sr_std_type, | |
361 | sr_std_tc, | |
362 | sr_std_atr, | |
363 | sr_std_len, | |
364 | sr_std_reqid, | |
365 | sr_std_tag, | |
366 | sr_std_ldwbe, | |
367 | sr_std_fdwbe, | |
368 | sr_std_addr, | |
369 | sr_std_dptr, | |
370 | sr_std_lrmtag | |
371 | }; | |
372 | ||
373 | assign tsb_lrm_rcd = { | |
374 | tsb_reg_type, | |
375 | tsb_reg_tc, | |
376 | tsb_reg_atr, | |
377 | tsb_reg_len, | |
378 | tsb_reg_reqid, | |
379 | {3'b000, tsb_lrm_sbdtag}, | |
380 | tsb_reg_ldwbe, | |
381 | tsb_reg_fdwbe, | |
382 | tsb_reg_addr, | |
383 | tsb_reg_dptr, | |
384 | tsb_reg_lrmtag | |
385 | }; | |
386 | ||
387 | ||
388 | // Transaction Scoreboard Tag - Only need to mux in the regsitered value if we have no upbound | |
389 | // LRM credits - but had already initiated a pipelined TSB Wr w trn request | |
390 | ||
391 | assign tsb_lrm_sbdtag = (itsb_state[I_STALL2]) ? tsb_reg_sbdtag : ts2rm_i_n_trn; | |
392 | ||
393 | ||
394 | //--------------------------------------------------------------------------- | |
395 | // STD Record Fields used to define outgoing LRM Record | |
396 | //--------------------------------------------------------------------------- | |
397 | ||
398 | assign sr_std_type = sr_std_dout[`FIRE_DLC_RMU_LRM_TYPE]; // 7 bit TYPE field | |
399 | assign sr_std_tc = sr_std_dout[`FIRE_DLC_RMU_LRM_TC]; // 3 bit TC field | |
400 | assign sr_std_atr = sr_std_dout[`FIRE_DLC_RMU_LRM_ATR]; // 2 bit TYPE field | |
401 | assign sr_std_len = sr_std_dout[`FIRE_DLC_RMU_LRM_LEN]; // 10 bit Length | |
402 | assign sr_std_reqid = sr_std_dout[`FIRE_DLC_RMU_LRM_REQID]; // 16 bit Reqid | |
403 | assign sr_std_tag = sr_std_dout[`FIRE_DLC_RMU_LRM_TAG]; // 8 bit tlptag | |
404 | assign sr_std_ldwbe = sr_std_dout[`FIRE_DLC_RMU_LRM_LDWBE]; // 4 bit last DWBE | |
405 | assign sr_std_fdwbe = sr_std_dout[`FIRE_DLC_RMU_LRM_FDWBE]; // 4 bit first DWBE | |
406 | assign sr_std_addr = sr_std_dout[`FIRE_DLC_RMU_LRM_ADDR]; // 62 bit Addr | |
407 | assign sr_std_dptr = sr_std_dout[`FIRE_DLC_RMU_LRM_DPTR]; // 7 bit Data Pointer | |
408 | assign sr_std_lrmtag = sr_std_dout[`FIRE_DLC_RMU_LRM_LRMTAG];// 8 bit lrmtag | |
409 | ||
410 | ||
411 | //--------------------------------------------------------------------------------- | |
412 | // Pipelined STD records that require TSB Access - Pipelined to Stream DMARds, UR's | |
413 | //--------------------------------------------------------------------------------- | |
414 | ||
415 | always @ (posedge clk) | |
416 | if(~rst_l) begin | |
417 | tsb_reg_type <= {`FIRE_DLC_RMU_LRM_TYPE_WDTH{1'b0}}; | |
418 | tsb_reg_tc <= {`FIRE_DLC_RMU_LRM_TC_WDTH{1'b0}}; | |
419 | tsb_reg_atr <= {`FIRE_DLC_RMU_LRM_ATR_WDTH{1'b0}}; | |
420 | tsb_reg_len <= {`FIRE_DLC_RMU_LRM_LEN_WDTH{1'b0}}; | |
421 | tsb_reg_reqid <= {`FIRE_DLC_RMU_LRM_REQID_WDTH{1'b0}}; | |
422 | tsb_reg_ldwbe <= {`FIRE_DLC_RMU_LRM_LDWBE_WDTH{1'b0}}; | |
423 | tsb_reg_fdwbe <= {`FIRE_DLC_RMU_LRM_FDWBE_WDTH{1'b0}}; | |
424 | tsb_reg_addr <= {`FIRE_DLC_RMU_LRM_ADDR_WDTH{1'b0}}; | |
425 | tsb_reg_dptr <= {`FIRE_DLC_RMU_LRM_DPTR_WDTH{1'b0}}; | |
426 | tsb_reg_lrmtag <= {`FIRE_DLC_RMU_LRM_LRMTAG_WDTH{1'b0}}; | |
427 | end | |
428 | else if (ld_tsb_pipe_reg) | |
429 | begin | |
430 | tsb_reg_type <= sr_std_type; | |
431 | tsb_reg_tc <= sr_std_tc; | |
432 | tsb_reg_atr <= sr_std_atr; | |
433 | tsb_reg_len <= sr_std_len; | |
434 | tsb_reg_reqid <= sr_std_reqid; | |
435 | tsb_reg_ldwbe <= sr_std_ldwbe; | |
436 | tsb_reg_fdwbe <= sr_std_fdwbe; | |
437 | tsb_reg_addr <= sr_std_addr; | |
438 | tsb_reg_dptr <= sr_std_dptr; | |
439 | tsb_reg_lrmtag <= sr_std_lrmtag; | |
440 | end | |
441 | ||
442 | else | |
443 | begin | |
444 | tsb_reg_type <= tsb_reg_type; | |
445 | tsb_reg_tc <= tsb_reg_tc; | |
446 | tsb_reg_atr <= tsb_reg_atr; | |
447 | tsb_reg_len <= tsb_reg_len; | |
448 | tsb_reg_reqid <= tsb_reg_reqid; | |
449 | tsb_reg_ldwbe <= tsb_reg_ldwbe; | |
450 | tsb_reg_fdwbe <= tsb_reg_fdwbe; | |
451 | tsb_reg_addr <= tsb_reg_addr; | |
452 | tsb_reg_dptr <= tsb_reg_dptr; | |
453 | tsb_reg_lrmtag <= tsb_reg_lrmtag; | |
454 | end | |
455 | ||
456 | // Register TSB index for LRM record - the TSB access may complete before having credits | |
457 | // to enqueue up to the LRM - safe bet is to register the value so next TSB trn is not | |
458 | // muxed into LRM record | |
459 | ||
460 | always @ (posedge clk) | |
461 | if(~rst_l) begin | |
462 | tsb_reg_sbdtag <= {`FIRE_DLC_TSR_TRN_WDTH{1'b0}}; | |
463 | end | |
464 | else if (ld_tsb_sbdtag_reg) | |
465 | tsb_reg_sbdtag <= ts2rm_i_n_trn; | |
466 | else | |
467 | tsb_reg_sbdtag <= tsb_reg_sbdtag; | |
468 | ||
469 | ||
470 | //-------------------------------------- | |
471 | // Ingress LRM Record Type Decoder Logic | |
472 | //-------------------------------------- | |
473 | ||
474 | // Note: Should NEVER see a MSG, MSI, Mondo or Null IN THIS MODULE - they should have been | |
475 | // forked off to the IMU... and then passed back up to the lrm_octl module where they | |
476 | // are merged back into the Ingress pipeline | |
477 | ||
478 | always @ (sr_std_type or sr_std_empty) | |
479 | begin | |
480 | if (sr_std_empty) | |
481 | trans_type = SEND2OCTL; | |
482 | ||
483 | else | |
484 | case (sr_std_type) // 0in < case -default | |
485 | ||
486 | DMA_MRD32 : trans_type = NP_DMA_TSB; | |
487 | DMA_MRD64 : trans_type = NP_DMA_TSB; | |
488 | DMA_MRDLK32 : trans_type = NP_DMA_TSB; | |
489 | DMA_MRDLK64 : trans_type = NP_DMA_TSB; | |
490 | DMA_UR : trans_type = NP_UR_TSB; | |
491 | DMA_MWR32 : trans_type = SEND2OCTL; | |
492 | DMA_MWR64 : trans_type = SEND2OCTL; | |
493 | PIO_CPLD : trans_type = SEND2OCTL; | |
494 | PIO_CPL : trans_type = SEND2OCTL; | |
495 | ||
496 | // Zero In Check for INVALID transaction type if FIFO is not empty | |
497 | default : trans_type = UNDEFINED; | |
498 | ||
499 | endcase // case | |
500 | end // always | |
501 | ||
502 | ||
503 | //---------------------------------------------------------------------- | |
504 | // Signal that indicates that there is room for LRM rcd - ok to Enqueue | |
505 | //---------------------------------------------------------------------- | |
506 | ||
507 | assign lrm_credit_ok = |lrm_credit_count; // If Credit is 1-4, then OK!! | |
508 | // If Credit is 0 - NOT ok! LRM SR full | |
509 | ||
510 | //############################################################################ | |
511 | // SEQUENTIAL LOGIC | |
512 | //############################################################################ | |
513 | ||
514 | //------------------------ | |
515 | // TSB request register | |
516 | //------------------------ | |
517 | ||
518 | always @ (posedge clk) | |
519 | if (~rst_l) | |
520 | rm2ts_i_req <= 1'b0; | |
521 | else | |
522 | rm2ts_i_req <= next_rm2ts_i_req; | |
523 | ||
524 | ||
525 | //------------------------ | |
526 | // TSB write data register | |
527 | //------------------------ | |
528 | ||
529 | always @ (posedge clk) | |
530 | if (~rst_l) | |
531 | rm2ts_i_wr_data <= {`FIRE_DLC_TSR_WR_DATA_WDTH{1'b0}}; | |
532 | ||
533 | else if (ld_tsb_wr_data) | |
534 | rm2ts_i_wr_data <= next_tsb_write_data; | |
535 | ||
536 | else | |
537 | rm2ts_i_wr_data <= rm2ts_i_wr_data; | |
538 | ||
539 | ||
540 | // Fields that make up the 48 bit TSB write data | |
541 | assign next_tsb_write_data = { | |
542 | sr_std_tc, | |
543 | sr_std_atr, | |
544 | tsb_bcnt, | |
545 | sr_std_reqid, | |
546 | sr_std_tag, | |
547 | tsb_lower_addr | |
548 | }; | |
549 | ||
550 | assign tsb_bcnt = (trans_type == NP_UR_TSB) ? 12'h4 : dma_rd_bcnt[`FIRE_DLC_TSR_BYTECNT_WDTH-1:0]; | |
551 | assign tsb_lower_addr = (trans_type == NP_UR_TSB) ? 7'h0 : dma_rd_addr; | |
552 | ||
553 | // Note: IF len = 4K and NO BE's are subtracted from bcnt, all 0's will be written to TSB, the MSB | |
554 | // or bit 13 of bcnt calculation does not get written to TSB, RRM must check for 4K length | |
555 | ||
556 | //------------------------------------------------ | |
557 | // DMA Rd Byte Count Calculations for TSB accesses | |
558 | //------------------------------------------------ | |
559 | ||
560 | // Note that ANY malformed packets WILL be trapped in the ILU - and that | |
561 | // no additioanl checks need to performed in the RMU! | |
562 | ||
563 | // Check to see if LEN = 1 DW... if so - then LDWBE's can be ignored - and BC = dma_rd_bcnt_one_dw | |
564 | assign dma_rd_len_eq_dw = ~|sr_std_len[`FIRE_DLC_RMU_LRM_LEN_WDTH-1:1] & sr_std_len[0]; | |
565 | ||
566 | // Check to see if LEN = 0 DW... if so - then BCNT = 4K, dma_rd_bcnt = 12'h0; | |
567 | assign dma_rd_len_fourk = ~|sr_std_len[`FIRE_DLC_RMU_LRM_LEN_WDTH-1:0]; | |
568 | ||
569 | ||
570 | // Calculate dma_rd_bcnt for the case when LEN IS exactly equal to 1 DW | |
571 | always @ (sr_std_fdwbe) | |
572 | begin | |
573 | casez (sr_std_fdwbe) // 0in < case -parallel -full -active ~sr_std_empty | |
574 | 4'b1zz1 : dma_rd_bcnt_one_dw = 3'h4; | |
575 | 4'b01z1 : dma_rd_bcnt_one_dw = 3'h3; | |
576 | 4'b1z10 : dma_rd_bcnt_one_dw = 3'h3; | |
577 | 4'b0011 : dma_rd_bcnt_one_dw = 3'h2; | |
578 | 4'b0110 : dma_rd_bcnt_one_dw = 3'h2; | |
579 | 4'b1100 : dma_rd_bcnt_one_dw = 3'h2; | |
580 | 4'b0001 : dma_rd_bcnt_one_dw = 3'h1; | |
581 | 4'b0010 : dma_rd_bcnt_one_dw = 3'h1; | |
582 | 4'b0100 : dma_rd_bcnt_one_dw = 3'h1; | |
583 | 4'b1000 : dma_rd_bcnt_one_dw = 3'h1; | |
584 | 4'b0000 : dma_rd_bcnt_one_dw = 3'h1; // If ZERO byte DMA Rd - byte count = 1! | |
585 | endcase | |
586 | end | |
587 | ||
588 | // Number of bytes off from 1st DWBE | |
589 | always @ (sr_std_fdwbe) | |
590 | begin | |
591 | if (sr_std_fdwbe[0]) bytes_off_frst_dwbe = 2'b00; | |
592 | else if (sr_std_fdwbe[1]) bytes_off_frst_dwbe = 2'b01; | |
593 | else if (sr_std_fdwbe[2]) bytes_off_frst_dwbe = 2'b10; | |
594 | else if (sr_std_fdwbe[3]) bytes_off_frst_dwbe = 2'b11; | |
595 | else bytes_off_frst_dwbe = 2'b00; | |
596 | end | |
597 | ||
598 | // Number of bytes off from last DWBE | |
599 | always @ (sr_std_ldwbe) | |
600 | begin | |
601 | if (sr_std_ldwbe[3]) bytes_off_last_dwbe = 2'b00; | |
602 | else if (sr_std_ldwbe[2]) bytes_off_last_dwbe = 2'b01; | |
603 | else if (sr_std_ldwbe[1]) bytes_off_last_dwbe = 2'b10; | |
604 | else if (sr_std_ldwbe[0]) bytes_off_last_dwbe = 2'b11; | |
605 | else bytes_off_last_dwbe = 2'b00; | |
606 | end | |
607 | ||
608 | assign total_bytes_off = {1'b0, bytes_off_frst_dwbe} + {1'b0, bytes_off_last_dwbe}; // 3-bit value (0-6) | |
609 | ||
610 | // Calculate DMA Rd BCNT len for cases where the 10 bit LEN field is not a single DW | |
611 | ||
612 | // NOTE: this calculation also holds for LEN==0, or 4K - all BE's will set, | |
613 | // total bytes off will = 0 - therefore a value of 12'h0 will be written | |
614 | // to TSB! Need to validate cases where LEN may == 0, but BE's not all set? | |
615 | ||
616 | assign dma_rd_len_total_bc = {dma_rd_len_fourk, sr_std_len, 2'b00}; // 13 bit value | |
617 | ||
618 | assign dma_rd_bcnt_mult_dws = dma_rd_len_total_bc - {10'h0, total_bytes_off}; // 13 bit value | |
619 | ||
620 | assign dma_rd_bcnt = dma_rd_len_eq_dw ? {10'h0, dma_rd_bcnt_one_dw} : dma_rd_bcnt_mult_dws; | |
621 | ||
622 | ||
623 | //---------------------------------------------------------- | |
624 | // DMA Lower Address Align Bit Calculations for TSB accesses | |
625 | //---------------------------------------------------------- | |
626 | ||
627 | assign dma_rd_lower_addr = bytes_off_frst_dwbe; // 2 bit LSB addr | |
628 | ||
629 | assign dma_rd_addr = {sr_std_addr[4:0], dma_rd_lower_addr}; // 7 bit field | |
630 | ||
631 | ||
632 | //------------------------------------------------- | |
633 | // LRM Ingress TSB State Machine Combinatorial Code | |
634 | //------------------------------------------------- | |
635 | ||
636 | // ttype of 0x01, 0x10 = NP_DMA, NP_UR respectively | |
637 | assign tsb_vld = trans_type[1]^trans_type[0]; | |
638 | ||
639 | // Registered lrm rcd mux select | |
640 | assign tsb_lrm_rcd_sel = (itsb_state[I_ENQPIPE] | itsb_state[I_STALL1] | itsb_state[I_STALL2]); | |
641 | ||
642 | // Load tsb_lrm_reg's from sr_std_dout | |
643 | assign ld_tsb_pipe_reg = itsb_state[I_LDPIPE]; | |
644 | ||
645 | // Load enable for TSB trn number for upbound LRM record | |
646 | assign ld_tsb_sbdtag_reg = (itsb_state[I_STALL1]) & ts2rm_i_gnt; | |
647 | ||
648 | ||
649 | ||
650 | ||
651 | //----------------------------------------------- | |
652 | // LRM Ingress TSB State Machine Sequential Logic | |
653 | //----------------------------------------------- | |
654 | ||
655 | always @ (posedge clk) | |
656 | if (~rst_l) | |
657 | begin | |
658 | itsb_state[NUM_STATES-1:0] <= {NUM_STATES{1'b0}}; | |
659 | itsb_state[I_PROCESS] <= 1'b1; | |
660 | end | |
661 | else | |
662 | begin | |
663 | itsb_state <= next_itsb_state; | |
664 | end | |
665 | ||
666 | ||
667 | // LRM Ingress TSB State Machine Combinatorial (Next State) Logic | |
668 | ||
669 | always @ ( itsb_state or sr_std_empty or lrm_credit_ok or trans_type or ts2rm_i_gnt or tsb_vld ) | |
670 | ||
671 | begin | |
672 | next_itsb_state = {NUM_STATES{1'b0}}; // Default FSM Output Values | |
673 | std_rcd_deq = 1'b0; | |
674 | lrm_rcd_enq = 1'b0; | |
675 | ld_tsb_wr_data = 1'b0; | |
676 | next_rm2ts_i_req = 1'b0; | |
677 | ||
678 | ||
679 | case(1'b1) // synopsys parallel_case | |
680 | // 0in < case -full | |
681 | ||
682 | // I_PROCESS - Initial State | |
683 | itsb_state[I_PROCESS] : | |
684 | ||
685 | if (~sr_std_empty & lrm_credit_ok) // STD rcd ready to be processed | |
686 | ||
687 | case(trans_type) | |
688 | ||
689 | (SEND2OCTL) : // Send STD rcd up pipeline | |
690 | begin | |
691 | std_rcd_deq = 1'b1; | |
692 | lrm_rcd_enq = 1'b1; | |
693 | next_itsb_state[I_PROCESS] = 1'b1; | |
694 | end | |
695 | ||
696 | (NP_DMA_TSB), // STD rcd needs to be tracked on TSB | |
697 | (NP_UR_TSB) : | |
698 | begin | |
699 | ld_tsb_wr_data = 1'b1; | |
700 | next_rm2ts_i_req = 1'b1; | |
701 | next_itsb_state[I_LDPIPE] = 1'b1; | |
702 | end | |
703 | ||
704 | endcase | |
705 | ||
706 | else // STD rcd fifo empty - Keep Default Values | |
707 | next_itsb_state[I_PROCESS] = 1'b1; | |
708 | ||
709 | ||
710 | // I_LDPIPE - TSB Write Access in progress - Load Pipeline, DEQ next STD rcd and chk credit | |
711 | itsb_state[I_LDPIPE] : // Pipline Load enable for NP record | |
712 | ||
713 | begin | |
714 | next_rm2ts_i_req = 1'b1; // Keep REQ asserted | |
715 | std_rcd_deq = 1'b1; // Pipeline TSB rcd | |
716 | ||
717 | if (lrm_credit_ok) | |
718 | next_itsb_state[I_ENQPIPE] = 1'b1; // Complete TSB access and ENQ LRM Rcd | |
719 | else | |
720 | next_itsb_state[I_STALL1] = 1'b1; // NO upbound credit - STALL pipeline | |
721 | end | |
722 | ||
723 | ||
724 | // I_ENQPIPE - Complete TSB access and ENQ LRM Rcd - check if another TSB access | |
725 | itsb_state[I_ENQPIPE] : // LRM output rcd mux select -> tsb_lrm_rcd | |
726 | ||
727 | case({ts2rm_i_gnt, tsb_vld}) // 0in < case -parallel -full | |
728 | ||
729 | (2'b00), // Wait for GNT to complete | |
730 | (2'b01) : // Keeping REQ asserted | |
731 | begin | |
732 | next_rm2ts_i_req = 1'b1; | |
733 | next_itsb_state[I_ENQPIPE] = 1'b1; | |
734 | end | |
735 | ||
736 | (2'b10) : // TSB access complete, ENQ LRM rcd | |
737 | begin // since no more TSB accesses required | |
738 | lrm_rcd_enq = 1'b1; // just return to PROCESS state | |
739 | next_itsb_state[I_PROCESS] = 1'b1; | |
740 | end | |
741 | ||
742 | (2'b11) : // TSB access completed, ENQ LRM rcd | |
743 | begin // and continue to stream NP DMA's | |
744 | lrm_rcd_enq = 1'b1; | |
745 | ld_tsb_wr_data = 1'b1; | |
746 | next_rm2ts_i_req = 1'b1; | |
747 | next_itsb_state[I_LDPIPE] = 1'b1; | |
748 | end | |
749 | endcase | |
750 | ||
751 | ||
752 | // I_STALL1 - No lrm_credits while accessing TSB - finish TSB and chk credit | |
753 | itsb_state[I_STALL1] : // LRM output rcd mux select -> tsb_lrm_rcd | |
754 | ||
755 | case({ts2rm_i_gnt, lrm_credit_ok}) // 0in < case -parallel -full | |
756 | ||
757 | (2'b00), | |
758 | (2'b01) : | |
759 | begin | |
760 | next_rm2ts_i_req = 1'b1; // credit freed up before GNT | |
761 | next_itsb_state[I_STALL1] = 1'b1; // need to wait for credit_ok | |
762 | end | |
763 | ||
764 | (2'b10) : | |
765 | begin | |
766 | next_itsb_state[I_STALL2] = 1'b1; // deassert REQ - but wait for credit | |
767 | end | |
768 | ||
769 | (2'b11) : | |
770 | begin // TSB completed and have credit! | |
771 | lrm_rcd_enq = 1'b1; // ENQ lrm rcd!, deassert req | |
772 | ||
773 | if (tsb_vld) // Another NP_DMA or NP_UR ready for TSB | |
774 | begin | |
775 | ld_tsb_wr_data = 1'b1; | |
776 | next_rm2ts_i_req = 1'b1; | |
777 | next_itsb_state[I_LDPIPE] = 1'b1; // Stream out Non Posted DMA's | |
778 | end | |
779 | else | |
780 | begin | |
781 | next_itsb_state[I_PROCESS] = 1'b1; // Either fifo empty or | |
782 | end | |
783 | end | |
784 | endcase | |
785 | ||
786 | ||
787 | // I_STALL2 - Pipelined TSB access completed, but had no credits - ENQ when OK! | |
788 | itsb_state[I_STALL2] : // LRM output rcd mux select -> tsb_lrm_rcd | |
789 | ||
790 | case({lrm_credit_ok, tsb_vld}) // 0in < case -parallel -full | |
791 | ||
792 | (2'b00), | |
793 | (2'b01) : | |
794 | begin | |
795 | next_itsb_state[I_STALL2] = 1'b1; // need to wait for credit_ok | |
796 | end | |
797 | ||
798 | (2'b10) : | |
799 | begin | |
800 | lrm_rcd_enq = 1'b1; // OK to ENQ LRM Rcd - no more TSB cycles | |
801 | next_itsb_state[I_PROCESS] = 1'b1; | |
802 | end | |
803 | ||
804 | (2'b11) : | |
805 | begin // Have credit!, and Another TSB access | |
806 | lrm_rcd_enq = 1'b1; // ENQ lrm rcd!, deassert req | |
807 | ld_tsb_wr_data = 1'b1; | |
808 | next_rm2ts_i_req = 1'b1; | |
809 | next_itsb_state[I_LDPIPE] = 1'b1; | |
810 | end | |
811 | ||
812 | endcase | |
813 | ||
814 | ||
815 | endcase // ends itsb_state case FSM | |
816 | ||
817 | end // ends combinatorial always block for i_fsm state machine | |
818 | ||
819 | ||
820 | //-------------------------------------------------------------------------------------------- | |
821 | // LRM rcd Credit Counter - Establishes whether there is credit to Enqueue LRM rcd to lrm_octl | |
822 | //-------------------------------------------------------------------------------------------- | |
823 | ||
824 | always @ (posedge clk) | |
825 | if (~rst_l) | |
826 | lrm_credit_count <= 3'b100; // Initially sized to LRM FIFO Depth - 5 | |
827 | else | |
828 | lrm_credit_count <= next_lrm_credit_count; | |
829 | ||
830 | ||
831 | always @ (lrm_rcd_enq or lrm_rcd_deq or lrm_credit_count) | |
832 | begin // Combinatorial next_lrm_credit_count logic | |
833 | next_lrm_credit_count = 3'b000; // Just for initialization | |
834 | ||
835 | case ({lrm_rcd_deq, lrm_rcd_enq}) // synopsys infer_mux | |
836 | ||
837 | (2'b01) : // Enqueueing LRM record | |
838 | next_lrm_credit_count = lrm_credit_count - 1'b1; // Decrement LRM credit | |
839 | (2'b10) : // Dequeueing Record from LRM SR | |
840 | next_lrm_credit_count = lrm_credit_count + 1'b1; // Increment LRM credit | |
841 | (2'b00), | |
842 | (2'b11) : | |
843 | next_lrm_credit_count = lrm_credit_count; // Credit Count Remains the Same | |
844 | ||
845 | endcase | |
846 | end | |
847 | ||
848 | ||
849 | //############################################################################ | |
850 | // MODULE INSTANTIATIONS | |
851 | //############################################################################ | |
852 | ||
853 | //---------------------------------------------------- | |
854 | // STD Standard Record FIFO = 131 * 5 = 655 registers | |
855 | // STD Standard Record FIFO = 131 * 4 = 524 registers | |
856 | //---------------------------------------------------- | |
857 | ||
858 | fire_dmc_common_srfifo #(STD_SR_WIDTH, STD_SR_DEPTH) sr_std_fifo ( | |
859 | .clk (clk), | |
860 | .rst_l (rst_l), | |
861 | .enq (std_rcd_enq), | |
862 | .data_in (std_rcd), | |
863 | .deq (std_rcd_deq), | |
864 | .data_out (sr_std_dout), | |
865 | .full (), | |
866 | .empty (sr_std_empty), | |
867 | .overflow (), | |
868 | .underflow () | |
869 | ); | |
870 | ||
871 | ||
872 | endmodule |