Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: pcie_common_dcc.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 pcie_common_dcc | |
36 | ( | |
37 | csr_ring_out, // ring output | |
38 | csrbus_wr_data, // csr write data | |
39 | csrbus_addr, // csr address | |
40 | csrbus_wr, // csr write | |
41 | csrbus_valid, // csr valid | |
42 | csrbus_src_bus, // csr source bus | |
43 | clk, // clock | |
44 | rst_l, // reset | |
45 | csr_ring_in, // ring input | |
46 | csrbus_read_data, // csr read data | |
47 | csrbus_done, // csr done | |
48 | csrbus_mapped, // csr mapped | |
49 | csrbus_acc_vio // csr access violation | |
50 | ); | |
51 | ||
52 | // ---------------------------------------------------------------------------- | |
53 | // Parameters | |
54 | // ---------------------------------------------------------------------------- | |
55 | parameter IDLE = 3'b000, // state machine states | |
56 | REQ0 = 3'b001, | |
57 | REQ1 = 3'b010, | |
58 | WAIT = 3'b011, | |
59 | MAPD = 3'b100, | |
60 | DONE = 3'b101, | |
61 | RSP0 = 3'b110, | |
62 | RSP1 = 3'b111; | |
63 | ||
64 | // ---------------------------------------------------------------------------- | |
65 | // Ports | |
66 | // ---------------------------------------------------------------------------- | |
67 | output [`FIRE_CSR_RING_BITS] csr_ring_out; | |
68 | output [`FIRE_CSR_DATA_BITS] csrbus_wr_data; | |
69 | output [`FIRE_CSR_ADDR_BITS] csrbus_addr; | |
70 | output csrbus_wr; | |
71 | output csrbus_valid; | |
72 | output [`FIRE_CSR_SRCB_BITS] csrbus_src_bus; | |
73 | ||
74 | input clk; | |
75 | input rst_l; | |
76 | input [`FIRE_CSR_RING_BITS] csr_ring_in; | |
77 | input [`FIRE_CSR_DATA_BITS] csrbus_read_data; | |
78 | input csrbus_done; | |
79 | input csrbus_mapped; | |
80 | input csrbus_acc_vio; | |
81 | ||
82 | // ---------------------------------------------------------------------------- | |
83 | // Variables | |
84 | // ---------------------------------------------------------------------------- | |
85 | wire [`FIRE_CSR_ADDR_BITS] csrbus_addr; | |
86 | wire [`FIRE_CSR_DATA_BITS] csrbus_wr_data; | |
87 | wire [`FIRE_CSR_SRCB_BITS] csrbus_src_bus; | |
88 | wire [`FIRE_CSR_CMND_BITS] rng_cmnd, new_cmnd; | |
89 | ||
90 | reg [`FIRE_CSR_RING_BITS] rsp_addr, csr_ring_out, nxt_ring_out; | |
91 | reg [`FIRE_CSR_DATA_BITS] data, rsp_data; | |
92 | reg [`FIRE_CSR_ADDR_BITS] addr; | |
93 | reg [`FIRE_CSR_SRCB_BITS] srcb; | |
94 | reg [`FIRE_CSR_CMND_BITS] rsp_cmnd; | |
95 | reg [2:0] state, nxt_state; | |
96 | reg [2:0] req_vld; | |
97 | reg [1:0] sel_out; | |
98 | reg rsp_vld; | |
99 | reg sel, nxt_sel; | |
100 | reg vld, nxt_vld; | |
101 | reg wrt; | |
102 | ||
103 | // ---------------------------------------------------------------------------- | |
104 | // Zero In Checkers | |
105 | // ---------------------------------------------------------------------------- | |
106 | ||
107 | // 0in known_driven -var csrbus_wr_data -active csrbus_valid | |
108 | // 0in change_window -start csrbus_valid -stop ~csrbus_valid -not_in csrbus_wr_data -exclude_stop | |
109 | // 0in known_driven -var csrbus_addr -active csrbus_valid | |
110 | // 0in change_window -start csrbus_valid -stop ~csrbus_valid -not_in csrbus_addr -exclude_stop | |
111 | // 0in known_driven -var csrbus_wr -active csrbus_valid | |
112 | // 0in change_window -start csrbus_valid -stop ~csrbus_valid -not_in csrbus_wr -exclude_stop | |
113 | // 0in known_driven -var csrbus_src_bus -active csrbus_valid | |
114 | // 0in change_window -start csrbus_valid -stop ~csrbus_valid -not_in csrbus_src_bus -exclude_stop | |
115 | ||
116 | // 0in assert_timer -var (csrbus_valid && csrbus_mapped) -min 1 -active csrbus_valid | |
117 | // 0in assert_timer -var (csrbus_valid && csrbus_done) -min 1 -active csrbus_valid | |
118 | ||
119 | // 0in state_transition -var state -val IDLE -next REQ0 RSP0 | |
120 | // 0in state_transition -var state -val REQ0 -next REQ1 | |
121 | // 0in state_transition -var state -val REQ1 -next WAIT | |
122 | // 0in state_transition -var state -val WAIT -next IDLE REQ0 RSP0 MAPD DONE | |
123 | // 0in state_transition -var state -val MAPD -next IDLE REQ0 RSP0 DONE | |
124 | // 0in state_transition -var state -val DONE -next RSP0 | |
125 | // 0in state_transition -var state -val RSP0 -next RSP1 | |
126 | // 0in state_transition -var state -val RSP1 -next IDLE | |
127 | ||
128 | // ---------------------------------------------------------------------------- | |
129 | // Combinational | |
130 | // ---------------------------------------------------------------------------- | |
131 | ||
132 | // valid and command | |
133 | assign rng_cmnd = csr_ring_in[`FIRE_CSR_RING_CMND_BITS]; | |
134 | ||
135 | // next state | |
136 | always @ (state or rng_cmnd or csrbus_mapped or csrbus_done or csrbus_acc_vio) begin | |
137 | case (state) // synopsys parallel_case | |
138 | IDLE : begin | |
139 | case (rng_cmnd) // synopsys parallel_case | |
140 | `FIRE_CSR_CMND_RREQ : nxt_state = REQ0; | |
141 | `FIRE_CSR_CMND_WREQ : nxt_state = REQ0; | |
142 | `FIRE_CSR_CMND_RRSP : nxt_state = RSP0; | |
143 | `FIRE_CSR_CMND_WRSP : nxt_state = RSP0; | |
144 | `FIRE_CSR_CMND_RERR : nxt_state = RSP0; | |
145 | `FIRE_CSR_CMND_WERR : nxt_state = RSP0; | |
146 | default : nxt_state = IDLE; | |
147 | endcase | |
148 | end | |
149 | REQ0 : nxt_state = REQ1; | |
150 | REQ1 : nxt_state = WAIT; | |
151 | WAIT : begin | |
152 | case (rng_cmnd) // synopsys parallel_case | |
153 | `FIRE_CSR_CMND_RSET : nxt_state = IDLE; | |
154 | `FIRE_CSR_CMND_RREQ : nxt_state = REQ0; | |
155 | `FIRE_CSR_CMND_WREQ : nxt_state = REQ0; | |
156 | `FIRE_CSR_CMND_RRSP : nxt_state = RSP0; | |
157 | `FIRE_CSR_CMND_WRSP : nxt_state = RSP0; | |
158 | `FIRE_CSR_CMND_RERR : nxt_state = RSP0; | |
159 | `FIRE_CSR_CMND_WERR : nxt_state = RSP0; | |
160 | default : begin | |
161 | case ({csrbus_mapped, csrbus_done, csrbus_acc_vio}) // synopsys parallel_case | |
162 | 3'b000 : nxt_state = WAIT; | |
163 | 3'b001 : nxt_state = DONE; | |
164 | 3'b010 : nxt_state = DONE; | |
165 | 3'b011 : nxt_state = DONE; | |
166 | 3'b100 : nxt_state = MAPD; | |
167 | 3'b101 : nxt_state = DONE; | |
168 | 3'b110 : nxt_state = DONE; | |
169 | 3'b111 : nxt_state = DONE; | |
170 | endcase | |
171 | end | |
172 | endcase | |
173 | end | |
174 | MAPD : begin | |
175 | case (rng_cmnd) // synopsys parallel_case | |
176 | `FIRE_CSR_CMND_RSET : nxt_state = IDLE; | |
177 | `FIRE_CSR_CMND_RREQ : nxt_state = REQ0; | |
178 | `FIRE_CSR_CMND_WREQ : nxt_state = REQ0; | |
179 | `FIRE_CSR_CMND_RRSP : nxt_state = RSP0; | |
180 | `FIRE_CSR_CMND_WRSP : nxt_state = RSP0; | |
181 | `FIRE_CSR_CMND_RERR : nxt_state = RSP0; | |
182 | `FIRE_CSR_CMND_WERR : nxt_state = RSP0; | |
183 | default : begin | |
184 | case ({csrbus_done, csrbus_acc_vio}) // synopsys parallel_case | |
185 | 2'b00 : nxt_state = MAPD; | |
186 | 2'b01 : nxt_state = DONE; | |
187 | 2'b10 : nxt_state = DONE; | |
188 | 2'b11 : nxt_state = DONE; | |
189 | endcase | |
190 | end | |
191 | endcase | |
192 | end | |
193 | DONE : nxt_state = RSP0; | |
194 | RSP0 : nxt_state = RSP1; | |
195 | RSP1 : nxt_state = IDLE; | |
196 | endcase | |
197 | end | |
198 | ||
199 | // state outputs | |
200 | always @ (state or nxt_state or sel or wrt) begin | |
201 | nxt_sel = 0; | |
202 | nxt_vld = 0; | |
203 | req_vld = 0; | |
204 | rsp_vld = 0; | |
205 | sel_out = 0; | |
206 | case (state) // synopsys parallel_case | |
207 | IDLE : begin | |
208 | req_vld = 3'b100; | |
209 | end | |
210 | REQ0 : begin | |
211 | req_vld = 3'b010; | |
212 | end | |
213 | REQ1 : begin | |
214 | nxt_vld = 1'b1; | |
215 | req_vld = 3'b001; | |
216 | end | |
217 | WAIT : begin | |
218 | case (nxt_state) // synopsys parallel_case | |
219 | REQ0 : begin | |
220 | req_vld = 3'b100; | |
221 | end | |
222 | WAIT : begin | |
223 | nxt_vld = 1'b1; | |
224 | end | |
225 | MAPD : begin | |
226 | nxt_vld = 1'b1; | |
227 | end | |
228 | DONE : begin | |
229 | rsp_vld = 1'b1; | |
230 | end | |
231 | default : begin | |
232 | nxt_vld = 0; | |
233 | end | |
234 | endcase | |
235 | end | |
236 | MAPD : begin | |
237 | case (nxt_state) // synopsys parallel_case | |
238 | REQ0 : begin | |
239 | req_vld = 3'b100; | |
240 | end | |
241 | MAPD : begin | |
242 | nxt_vld = 1'b1; | |
243 | end | |
244 | DONE : begin | |
245 | rsp_vld = 1'b1; | |
246 | end | |
247 | default : begin | |
248 | nxt_vld = 0; | |
249 | end | |
250 | endcase | |
251 | end | |
252 | DONE : begin | |
253 | nxt_sel = ~wrt; | |
254 | sel_out = 2'b01; | |
255 | end | |
256 | RSP0 : begin | |
257 | nxt_sel = sel; | |
258 | sel_out = {sel, 1'b0}; | |
259 | end | |
260 | RSP1 : begin | |
261 | sel_out = {sel, sel}; | |
262 | end | |
263 | endcase | |
264 | end | |
265 | ||
266 | // response command | |
267 | assign new_cmnd[2] = csrbus_done | csrbus_acc_vio; | |
268 | assign new_cmnd[1] = csrbus_acc_vio; | |
269 | assign new_cmnd[0] = wrt; | |
270 | ||
271 | // response address | |
272 | always @ (rsp_cmnd or srcb or addr) begin | |
273 | rsp_addr = 0; | |
274 | rsp_addr[`FIRE_CSR_RING_CMND_BITS] = rsp_cmnd; | |
275 | rsp_addr[`FIRE_CSR_RING_SRCB_BITS] = srcb; | |
276 | rsp_addr[`FIRE_CSR_RING_ADDR_BITS] = addr; | |
277 | end | |
278 | ||
279 | // next csr ring out | |
280 | always @ (sel_out or csr_ring_in or rsp_addr or rsp_data) begin | |
281 | case (sel_out) // synopsys infer_mux | |
282 | 2'b00 : nxt_ring_out = csr_ring_in; | |
283 | 2'b01 : nxt_ring_out = rsp_addr; | |
284 | 2'b10 : nxt_ring_out = rsp_data[`FIRE_CSR_RDMS_BITS]; | |
285 | 2'b11 : nxt_ring_out = rsp_data[`FIRE_CSR_RDLS_BITS]; | |
286 | endcase | |
287 | end | |
288 | ||
289 | // csrbus outputs | |
290 | assign csrbus_addr = addr; | |
291 | assign csrbus_wr_data = data; | |
292 | assign csrbus_src_bus = srcb; | |
293 | wire csrbus_valid = vld; | |
294 | wire csrbus_wr = wrt; | |
295 | ||
296 | // ---------------------------------------------------------------------------- | |
297 | // Sequential | |
298 | // ---------------------------------------------------------------------------- | |
299 | always @ (posedge clk) begin | |
300 | if (!rst_l) begin | |
301 | state <= IDLE; | |
302 | sel <= 0; | |
303 | vld <= 0; | |
304 | end | |
305 | else begin | |
306 | state <= nxt_state; | |
307 | sel <= nxt_sel; | |
308 | vld <= nxt_vld; | |
309 | end | |
310 | end | |
311 | ||
312 | always @ (posedge clk) | |
313 | if (!rst_l) begin | |
314 | rsp_cmnd <= {3{1'b0}}; | |
315 | rsp_data <= {64{1'b0}}; | |
316 | end | |
317 | else begin | |
318 | if (rsp_vld) begin | |
319 | rsp_cmnd <= new_cmnd; | |
320 | rsp_data <= csrbus_read_data; | |
321 | end | |
322 | end | |
323 | ||
324 | always @ (posedge clk) | |
325 | if (!rst_l) begin | |
326 | addr <= {27{1'b0}}; | |
327 | wrt <= {{1'b0}}; | |
328 | srcb <= {2{1'b0}}; | |
329 | end | |
330 | else begin | |
331 | if (req_vld[2]) begin | |
332 | addr <= csr_ring_in[`FIRE_CSR_RING_ADDR_BITS]; | |
333 | wrt <= csr_ring_in[`FIRE_CSR_RING_WRIT_BITS]; | |
334 | srcb <= csr_ring_in[`FIRE_CSR_RING_SRCB_BITS]; | |
335 | end | |
336 | end | |
337 | ||
338 | always @ (posedge clk) | |
339 | if (!rst_l) begin | |
340 | data[`FIRE_CSR_RDMS_BITS] <= {32{1'b0}}; | |
341 | end | |
342 | else begin | |
343 | if (req_vld[1]) data[`FIRE_CSR_RDMS_BITS] <= csr_ring_in; | |
344 | end | |
345 | ||
346 | always @ (posedge clk) | |
347 | if (!rst_l) begin | |
348 | data[`FIRE_CSR_RDLS_BITS] <= {32{1'b0}}; | |
349 | end | |
350 | else begin | |
351 | if (req_vld[0]) data[`FIRE_CSR_RDLS_BITS] <= csr_ring_in; | |
352 | end | |
353 | ||
354 | always @ (posedge clk) | |
355 | if (!rst_l) begin | |
356 | csr_ring_out <= {32{1'b0}}; | |
357 | end | |
358 | else begin | |
359 | csr_ring_out <= nxt_ring_out; | |
360 | end | |
361 | ||
362 | endmodule // pcie_common_dcc |