Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_tsb_ttg.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_tsb_ttg | |
36 | ( | |
37 | // Control Signals | |
38 | clk, | |
39 | rst_l, | |
40 | ||
41 | // TIC-TTG INTERFACE | |
42 | // TIC-TTG Interface (Internal Input from TIC to TTG) | |
43 | tag_deq, | |
44 | ||
45 | // TTG-TIC Interface (Internal Output to TIC) | |
46 | no_tag_avail, | |
47 | tag_issue, | |
48 | ||
49 | // TEC-TTG INTERFACE | |
50 | // TEC-TTG Interface (Internal Input from TEC to TTG) | |
51 | tag_enq, | |
52 | tag_retire, | |
53 | ||
54 | // CSR interface | |
55 | tsb_sts_ext_select, | |
56 | tsb_sts_ext_done, | |
57 | tsb_sts_full_ext_read_data, | |
58 | tsb_sts_num_pnd_dma_ext_read_data, | |
59 | tsb_sts_empty_ext_read_data, | |
60 | ||
61 | // Debug ports | |
62 | ttg2dbg_dbg_a, | |
63 | ttg2dbg_dbg_b, | |
64 | dbg2ttg_dbg_sel_a, | |
65 | dbg2ttg_dbg_sel_b | |
66 | ); | |
67 | ||
68 | // synopsys sync_set_reset "rst_l" | |
69 | ||
70 | /////////////////////////////////////////////////////////////////////// | |
71 | // ************************* Parameters ************************* | |
72 | /////////////////////////////////////////////////////////////////////// | |
73 | parameter TAG_NUM = 32; // number of tags | |
74 | parameter TAG_WDTH = 5; // number of bits to encode tag | |
75 | ||
76 | ////////////////////////////////////////////////////////////////////// | |
77 | //************************* Port Declarations ******************* | |
78 | ////////////////////////////////////////////////////////////////////// | |
79 | ||
80 | // Control Signals | |
81 | input clk; | |
82 | input rst_l; | |
83 | ||
84 | // generator external interface inputs | |
85 | input tag_deq; // request from SRM for trtag | |
86 | input tag_enq; // request from RRM | |
87 | input [TAG_WDTH-1:0] tag_retire; // trtag from RRM | |
88 | ||
89 | // generator external interface outputs | |
90 | output no_tag_avail; // all trtags are in use | |
91 | output [TAG_WDTH-1:0] tag_issue; // trtag to be issued to SRM per request | |
92 | ||
93 | // Debug Wires | |
94 | output [`FIRE_DBG_DATA_BITS] ttg2dbg_dbg_a; | |
95 | output [`FIRE_DBG_DATA_BITS] ttg2dbg_dbg_b; | |
96 | ||
97 | input [2:0] dbg2ttg_dbg_sel_a; | |
98 | input [2:0] dbg2ttg_dbg_sel_b; | |
99 | ||
100 | // CSR interface | |
101 | input tsb_sts_ext_select; | |
102 | output tsb_sts_ext_done; | |
103 | output tsb_sts_full_ext_read_data; | |
104 | output [5:0] tsb_sts_num_pnd_dma_ext_read_data; | |
105 | output tsb_sts_empty_ext_read_data; | |
106 | ||
107 | ////////////////////////////////////////////////////////////////////// | |
108 | //*********************** Wires and Regs ************************ | |
109 | ////////////////////////////////////////////////////////////////////// | |
110 | ||
111 | wire tag_deq; | |
112 | reg [TAG_WDTH-1:0] next_tag_issue; | |
113 | wire n_no_tag_avail; | |
114 | ||
115 | wire tag_enq; | |
116 | wire [TAG_WDTH-1:0] tag_retire; | |
117 | ||
118 | ||
119 | wire [TAG_NUM-1:0] tag_issue_vctr; | |
120 | wire [TAG_NUM-1:0] next_tag; | |
121 | wire [TAG_NUM-1:0] higher_priority_tag; | |
122 | ||
123 | //non flops | |
124 | wire [TAG_NUM-1:0] nxt_tag_pool; | |
125 | reg [TAG_NUM-1:0] tag_dec_vctr; | |
126 | reg [TAG_NUM-1:0] dcd_vec; | |
127 | ||
128 | // flops | |
129 | reg [TAG_NUM-1:0] tag_pool; | |
130 | reg [TAG_WDTH-1:0] tag_issue; | |
131 | reg no_tag_avail; | |
132 | ||
133 | // Idle | |
134 | reg [5:0] count; | |
135 | reg ttg_idle; | |
136 | ||
137 | // debug | |
138 | reg [2:0] dbg_sel [0:1]; | |
139 | reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1]; | |
140 | reg [`FIRE_DBG_DATA_BITS] nxt_dbg_bus [0:1]; | |
141 | ||
142 | // debug ports | |
143 | wire [`FIRE_DBG_DATA_BITS] ttg2dbg_dbg_a; // TTG debug output a | |
144 | wire [`FIRE_DBG_DATA_BITS] ttg2dbg_dbg_b; // TTG debug output b | |
145 | wire [2:0] dbg2ttg_dbg_sel_a; // TTG debug select a | |
146 | wire [2:0] dbg2ttg_dbg_sel_b; // TTG debug select b | |
147 | ||
148 | reg tsb_empty ; | |
149 | ||
150 | integer i; | |
151 | ||
152 | ////////////////////////////////////////////////////////////////////// | |
153 | // ******** Zero-in checkers************************************ | |
154 | ////////////////////////////////////////////////////////////////////// | |
155 | ||
156 | // 0in bus_id -req tag_deq -req_id tag_issue -ret tag_enq -ret_id tag_retire -max_ids 32 | |
157 | // 0in encoder -in next_tag -out next_tag_issue -zero off | |
158 | // 0in decoder -in tag_retire -out dcd_vec | |
159 | ||
160 | ||
161 | ////////////////////////////////////////////////////////////////////// | |
162 | // ********************* Combinational Logic *********************** | |
163 | ////////////////////////////////////////////////////////////////////// | |
164 | ||
165 | // debug | |
166 | ||
167 | always @ (dbg2ttg_dbg_sel_a or dbg2ttg_dbg_sel_b) | |
168 | begin | |
169 | dbg_sel[0] = dbg2ttg_dbg_sel_a; | |
170 | dbg_sel[1] = dbg2ttg_dbg_sel_b; | |
171 | end | |
172 | ||
173 | always @ (dbg_sel[0] or dbg_sel[1] or tag_enq or tag_deq or tag_issue or tag_retire | |
174 | or no_tag_avail or ttg_idle) | |
175 | begin | |
176 | for (i = 0; i < 2; i = i + 1) | |
177 | begin | |
178 | case (dbg_sel[i]) // synopsys parallel_case infer_mux | |
179 | 3'b000: nxt_dbg_bus[i] = {2'b0, tag_enq, tag_retire}; | |
180 | 3'b001: nxt_dbg_bus[i] = {1'b0, no_tag_avail, tag_deq, tag_issue}; | |
181 | 3'b010: nxt_dbg_bus[i] = 8'b0; | |
182 | 3'b011: nxt_dbg_bus[i] = 8'b0; | |
183 | 3'b100: nxt_dbg_bus[i] = 8'b0; | |
184 | 3'b101: nxt_dbg_bus[i] = 8'b0; | |
185 | 3'b110: nxt_dbg_bus[i] = 8'b0; | |
186 | 3'b111: nxt_dbg_bus[i] = {7'b0, ttg_idle}; | |
187 | endcase | |
188 | end | |
189 | end | |
190 | ||
191 | assign ttg2dbg_dbg_a = dbg_bus[0]; | |
192 | assign ttg2dbg_dbg_b = dbg_bus[1]; | |
193 | ||
194 | // end debug | |
195 | ||
196 | ||
197 | //************************************ | |
198 | // CLEAR (RETIRE) TAG | |
199 | //************************************ | |
200 | // if tag pool is empty the retired tag becomes the next tag to issue | |
201 | always @ (tag_retire or tag_enq or no_tag_avail) | |
202 | begin | |
203 | if(no_tag_avail & tag_enq) | |
204 | begin | |
205 | dcd_vec = {TAG_NUM{1'b0}}; | |
206 | dcd_vec[tag_retire] = 1'b1; | |
207 | tag_dec_vctr = dcd_vec & {TAG_NUM{1'b0}}; | |
208 | end | |
209 | else | |
210 | begin | |
211 | dcd_vec = {TAG_NUM{1'b0}}; | |
212 | dcd_vec[tag_retire] = 1'b1; | |
213 | tag_dec_vctr = dcd_vec & {TAG_NUM{tag_enq}}; | |
214 | end | |
215 | end // always @ (tag_retire or tag_enq) | |
216 | ||
217 | ||
218 | //************************************ | |
219 | // ISSUE TAG | |
220 | //************************************ | |
221 | ||
222 | assign tag_issue_vctr = (next_tag & {TAG_NUM{tag_deq}}); | |
223 | ||
224 | ||
225 | // generate "next tag pool" storage vector | |
226 | assign nxt_tag_pool = (tag_dec_vctr | tag_pool) & ~tag_issue_vctr; | |
227 | ||
228 | // generate full signal | |
229 | assign n_no_tag_avail = ~(|tag_pool); | |
230 | ||
231 | always @(posedge clk) | |
232 | if (~rst_l) | |
233 | no_tag_avail <= 1'b0; | |
234 | else if (tag_deq) | |
235 | no_tag_avail <= n_no_tag_avail; | |
236 | else if (tag_enq) | |
237 | no_tag_avail <= 1'b0; | |
238 | ||
239 | // "tag pool" storage vector: 1 = avail, 0 = used | |
240 | always @(posedge clk) | |
241 | if (~rst_l) | |
242 | tag_pool <= 32'hffff_fffe; // all tags available on reset | |
243 | else | |
244 | tag_pool <= nxt_tag_pool; // retire/issue tags | |
245 | ||
246 | //*********************************** | |
247 | // priority select | |
248 | //*********************************** | |
249 | ||
250 | assign higher_priority_tag[TAG_NUM-1:1] = higher_priority_tag[TAG_NUM-2:0] | tag_pool[TAG_NUM-2:0]; | |
251 | assign higher_priority_tag[0] = 1'b0; | |
252 | assign next_tag[TAG_NUM-1:0] = tag_pool[TAG_NUM-1:0] & ~higher_priority_tag[TAG_NUM-1:0]; | |
253 | ||
254 | //*********************************** | |
255 | // encode tag | |
256 | //*********************************** | |
257 | ||
258 | always @(next_tag) | |
259 | begin | |
260 | ||
261 | next_tag_issue[0] = (next_tag[1] | next_tag[3] | next_tag[5] | | |
262 | next_tag[7] | next_tag[9] | next_tag[11] | | |
263 | next_tag[13] | next_tag[15] | | |
264 | next_tag[17] | next_tag[19] | next_tag[21] | | |
265 | next_tag[23] | next_tag[25] | next_tag[27] | | |
266 | next_tag[29] | next_tag[31]); | |
267 | ||
268 | next_tag_issue[1] = (next_tag[2] | next_tag[3] | next_tag[6] | | |
269 | next_tag[7] | next_tag[10] | next_tag[11] | | |
270 | next_tag[14] | next_tag[15] | | |
271 | next_tag[18] | next_tag[19] | next_tag[22] | | |
272 | next_tag[23] | next_tag[26] | next_tag[27] | | |
273 | next_tag[30] | next_tag[31]); | |
274 | ||
275 | next_tag_issue[2] = (next_tag[4] | next_tag[5] | next_tag[6] | | |
276 | next_tag[7] | next_tag[12] | next_tag[13] | | |
277 | next_tag[14] | next_tag[15] | | |
278 | next_tag[20] | next_tag[21] | next_tag[22] | | |
279 | next_tag[23] | next_tag[28] | next_tag[29] | | |
280 | next_tag[30] | next_tag[31]); | |
281 | ||
282 | next_tag_issue[3] = (next_tag[8] | next_tag[9] | next_tag[10] | | |
283 | next_tag[11] | next_tag[12] | next_tag[13] | | |
284 | next_tag[14] | next_tag[15] | | |
285 | next_tag[24] | next_tag[25] | next_tag[26] | | |
286 | next_tag[27] | next_tag[28] | next_tag[29] | | |
287 | next_tag[30] | next_tag[31]); | |
288 | ||
289 | next_tag_issue[4] = (next_tag[16] | next_tag[17] | next_tag[18] | | |
290 | next_tag[19] | next_tag[20] | next_tag[21] | | |
291 | next_tag[22] | next_tag[23] | | |
292 | next_tag[24] | next_tag[25] | next_tag[26] | | |
293 | next_tag[27] | next_tag[28] | next_tag[29] | | |
294 | next_tag[30] | next_tag[31]); | |
295 | end | |
296 | ||
297 | always @(posedge clk) | |
298 | if (~rst_l) | |
299 | tag_issue <= {TAG_WDTH{1'b0}}; | |
300 | else if (tag_enq & no_tag_avail) | |
301 | tag_issue <= tag_retire; | |
302 | else if (tag_deq) | |
303 | tag_issue <= next_tag_issue; | |
304 | ||
305 | // Idle counter | |
306 | ||
307 | always @(posedge clk) | |
308 | if (~rst_l) | |
309 | count <= 6'b00_0000; | |
310 | else if(tag_enq | tag_deq) | |
311 | begin | |
312 | if (tag_deq & tag_enq) | |
313 | count <= count; | |
314 | else if (tag_deq) | |
315 | count <= count + 1'b1; | |
316 | else | |
317 | count <= count - 1'b1; | |
318 | end | |
319 | ||
320 | always @(count) | |
321 | if (count == 6'b00_0000) | |
322 | ttg_idle = 1'b1; | |
323 | else | |
324 | ttg_idle = 1'b0; | |
325 | ||
326 | always @(posedge clk) | |
327 | begin | |
328 | tsb_empty <= ttg_idle; | |
329 | end | |
330 | ||
331 | ||
332 | // CSR interface | |
333 | assign tsb_sts_ext_done = tsb_sts_ext_select; | |
334 | assign tsb_sts_full_ext_read_data = no_tag_avail; | |
335 | assign tsb_sts_num_pnd_dma_ext_read_data = count; | |
336 | assign tsb_sts_empty_ext_read_data = tsb_empty; | |
337 | ||
338 | ||
339 | // Debug port outputs | |
340 | always @ (posedge clk) | |
341 | begin | |
342 | if(~rst_l) | |
343 | for (i = 0; i < 2; i = i + 1) | |
344 | dbg_bus[i] <= 8'h00; | |
345 | else | |
346 | for (i = 0; i < 2; i = i + 1) | |
347 | dbg_bus[i] <= nxt_dbg_bus[i]; | |
348 | end // always @ (posedge clk) | |
349 | ||
350 | endmodule // dmu_tsb_ttg |