Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_crb.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: dmu_mmu_crb.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 ============================================
35module dmu_mmu_crb
36 (
37 clk, // clock
38 rst_l, // reset
39 csr2crb_ds_a, // csr debug select a
40 csr2crb_ds_b, // csr debug select b
41 csr2crb_ra, // csr read address
42 csr2crb_wa, // csr write address
43 csr2crb_wd, // csr write data
44 csr2crb_we, // csr write enable
45 tcb2crb_req, // tcb tag request
46 vtb2crb_hit, // vtb hit
47 vtb2crb_inv, // vtb tag invalidate
48 vtb2crb_tag, // vtb invalidate tag
49 vtb2crb_vld, // vtb valid
50 crb2csr_dbg_a, // csr debug bus a
51 crb2csr_dbg_b, // csr debug bus b
52 crb2csr_rd, // csr read data
53 crb2tcb_tag // tcb replacment tag
54 );
55
56// ----------------------------------------------------------------------------
57// Parameters
58// ----------------------------------------------------------------------------
59 parameter CNT_MAX = { `FIRE_DLC_MMU_VTC_WDTH {1'b1} };
60
61// ----------------------------------------------------------------------------
62// Ports
63// ----------------------------------------------------------------------------
64 input clk;
65 input rst_l;
66
67 input [`FIRE_DLC_MMU_TAG_PTR_BITS] csr2crb_ra;
68 input [`FIRE_DLC_MMU_TAG_PTR_BITS] csr2crb_wa;
69 input [`FIRE_DLC_MMU_VTC_BITS] csr2crb_wd;
70 input csr2crb_we;
71 input [`FIRE_DLC_MMU_CSR_DS_BITS] csr2crb_ds_a;
72 input [`FIRE_DLC_MMU_CSR_DS_BITS] csr2crb_ds_b;
73 input tcb2crb_req;
74 input [`FIRE_DLC_MMU_TAG_BITS] vtb2crb_hit;
75 input vtb2crb_inv;
76 input [`FIRE_DLC_MMU_TAG_PTR_BITS] vtb2crb_tag;
77 input [`FIRE_DLC_MMU_TAG_BITS] vtb2crb_vld;
78
79 output [`FIRE_DBG_DATA_BITS] crb2csr_dbg_a;
80 output [`FIRE_DBG_DATA_BITS] crb2csr_dbg_b;
81 output [`FIRE_DLC_MMU_VTC_BITS] crb2csr_rd;
82 output [`FIRE_DLC_MMU_TAG_PTR_BITS] crb2tcb_tag;
83
84// ----------------------------------------------------------------------------
85// Variables
86// ----------------------------------------------------------------------------
87 wire [`FIRE_DBG_DATA_BITS] crb2csr_dbg_a, crb2csr_dbg_b;
88 wire [`FIRE_DLC_MMU_TAG_PTR_BITS] crb2tcb_tag, nxt_ptr;
89 wire [`FIRE_DLC_MMU_VTC_BITS] crb2csr_rd;
90 wire [`FIRE_DLC_MMU_VTC_BITS] cnt_ptr, cnt_tag0, cnt_tag1;
91 wire [`FIRE_DLC_MMU_TAG_BITS] cnt_clr;
92 wire [1:0] tag_dn, tag_ld, tag_up, tag_tst;
93 wire [1:0] vld_tag, inv_not_req;
94
95 reg [`FIRE_DLC_MMU_VTC_BITS] cnt [`FIRE_DLC_MMU_TAG_MEM_BITS];
96 reg [`FIRE_DLC_MMU_TAG_BITS] cnt_inc, cnt_ld, cnt_rst;
97 reg [`FIRE_DLC_MMU_TAG_PTR_BITS] ptr, que_tag [0:1];
98 reg [1:0] tag_chk;
99 reg skp;
100
101 reg [`FIRE_DLC_MMU_CSR_DS_BITS] dbg_sel [0:1];
102 reg [`FIRE_DBG_DATA_BITS] dbg_bus [0:1];
103
104 integer i;
105
106// ----------------------------------------------------------------------------
107// Zero In Checkers
108// ----------------------------------------------------------------------------
109
110 // 0in decoder -in ptr -out cnt_inc -active inc_cnt
111 // 0in decoder -in csr2crb_wa -out cnt_ld -active csr2crb_we
112 // 0in decoder -in que_tag[0] -out cnt_rst -active req_not_inv
113
114// ----------------------------------------------------------------------------
115// Combinational
116// ----------------------------------------------------------------------------
117// pointer and tag counts and valids
118 assign cnt_ptr = cnt[ptr];
119 assign cnt_tag0 = cnt[que_tag[0]];
120 assign cnt_tag1 = cnt[que_tag[1]];
121
122 wire vld_ptr = vtb2crb_vld[ptr];
123 assign vld_tag[0] = vtb2crb_vld[que_tag[0]];
124 assign vld_tag[1] = vtb2crb_vld[que_tag[1]];
125
126// tag equals pointer and tags equal invalidate
127 wire tag_eqs_hit = vtb2crb_hit[que_tag[0]];
128 wire tag_eqs_inv = (que_tag[0] == vtb2crb_tag);
129 wire tag_eqs_ptr = (que_tag[0] == ptr);
130
131// tag request
132 wire tag_request = tcb2crb_req | tag_eqs_hit;
133 wire tag_invalid = vtb2crb_inv & ~tag_eqs_inv;
134 wire tag_freeze = vtb2crb_inv & tag_eqs_inv;
135
136// request and invalidate combinations
137 wire req_not_inv = tag_request & ~tag_invalid;
138 assign inv_not_req[0] = tag_invalid & ~tcb2crb_req;
139 assign inv_not_req[1] = tag_invalid & ~tag_request;
140
141// tag checks
142 wire tag_spc = ~tag_freeze & ~skp;
143 assign tag_tst[0] = ~tag_freeze & (cnt_tag0 < cnt_ptr);
144 assign tag_tst[1] = ~tag_eqs_ptr & (cnt_tag1 < cnt_ptr);
145
146 always @ (tag_eqs_ptr or tag_spc or tag_tst or vld_ptr or vld_tag) begin
147 case ({vld_tag, vld_ptr})
148 3'b000 : tag_chk = 0;
149 3'b001 : tag_chk = 0;
150 3'b010 : tag_chk = {1'b0, tag_spc};
151 3'b011 : tag_chk = {1'b0, tag_tst[0]};
152 3'b100 : tag_chk = {~tag_eqs_ptr, 1'b0};
153 3'b101 : tag_chk = {tag_tst[1], 1'b0};
154 3'b110 : tag_chk = {1'b0, tag_spc};
155 3'b111 : tag_chk = tag_tst;
156 endcase
157 end
158
159// pointer hold
160 wire ptr_hld = tag_request ^ tag_invalid;
161
162// next pointer
163 assign nxt_ptr = ptr_hld ? ptr : ptr + 1;
164
165// next skip
166 wire nxt_skp = req_not_inv & tag_eqs_ptr;
167
168// count update controls
169 wire inc_cnt = vld_ptr & ~(cnt_ptr == CNT_MAX) & ~ptr_hld;
170
171 always @ (ptr or inc_cnt) begin
172 cnt_inc = 0;
173 cnt_inc[ptr] = inc_cnt;
174 end
175
176 always @ (csr2crb_wa or csr2crb_we) begin
177 cnt_ld = 0;
178 cnt_ld[csr2crb_wa] = csr2crb_we;
179 end
180
181 always @ (req_not_inv or que_tag[0]) begin
182 cnt_rst = 0;
183 cnt_rst[que_tag[0]] = req_not_inv;
184 end
185
186 assign cnt_clr = cnt_rst | vtb2crb_hit | ~vtb2crb_vld;
187
188// tag update controls
189 assign tag_dn[0] = req_not_inv;
190 assign tag_dn[1] = req_not_inv;
191 assign tag_up[0] = inv_not_req[0];
192 assign tag_up[1] = inv_not_req[1] | tag_chk[0];
193 assign tag_ld[0] = tag_chk[0];
194 assign tag_ld[1] = tag_chk[1];
195
196// csr lru count
197 assign crb2csr_rd = cnt[csr2crb_ra];
198
199// tcb replacement tag
200 assign crb2tcb_tag = tag_invalid ? vtb2crb_tag : que_tag[0];
201
202// ----------------------------------------------------------------------------
203// Debug
204// ----------------------------------------------------------------------------
205 always @ (csr2crb_ds_a or csr2crb_ds_b) begin
206 dbg_sel[0] = csr2crb_ds_a;
207 dbg_sel[1] = csr2crb_ds_b;
208 end
209
210 assign crb2csr_dbg_a = dbg_bus[0];
211 assign crb2csr_dbg_b = dbg_bus[1];
212
213// ----------------------------------------------------------------------------
214// Sequential
215// ----------------------------------------------------------------------------
216 always @ (posedge clk) begin
217 if (!rst_l) begin
218 ptr <= 0;
219 skp <= 0;
220 end
221 else begin
222 ptr <= nxt_ptr;
223 skp <= nxt_skp;
224 end
225 end
226
227 always @ (posedge clk) begin
228 if (!rst_l) que_tag[0] <= 0;
229 else if (tag_dn[0]) que_tag[0] <= que_tag[1];
230 else if (tag_up[0]) que_tag[0] <= vtb2crb_tag;
231 else if (tag_ld[0]) que_tag[0] <= ptr;
232 end
233
234 always @ (posedge clk) begin
235 if (!rst_l) que_tag[1] <= 1;
236 else if (tag_dn[1]) que_tag[1] <= que_tag[1] + 1;
237 else if (tag_up[1]) que_tag[1] <= que_tag[0];
238 else if (tag_ld[1]) que_tag[1] <= ptr;
239 end
240
241 always @ (posedge clk)
242 if(~rst_l) begin : cnt_tag_rst
243 integer j;
244 for (j = 0; j < `FIRE_DLC_MMU_TAG_SIZE; j = j + 1) begin
245 cnt[j] <= {`FIRE_DLC_MMU_VTC_WDTH{1'b0}};
246 end
247 end
248 else begin
249 for (i = 0; i < `FIRE_DLC_MMU_TAG_SIZE; i = i + 1) begin
250 if (cnt_ld[i]) cnt[i] <= csr2crb_wd;
251 else if (cnt_clr[i]) cnt[i] <= 0;
252 else if (cnt_inc[i]) cnt[i] <= cnt_ptr + 1;
253 end
254 end
255
256 always @ (posedge clk)
257 if(~rst_l) begin : dbg_rst
258 integer j;
259 for (j = 0; j < 2; j = j + 1) begin
260 dbg_bus[j] <= {`FIRE_DEBUG_WDTH{1'b0}};
261 end
262 end
263 else begin
264 for (i = 0; i < 2; i = i + 1) begin
265 case (dbg_sel[i]) // synopsys infer_mux
266 3'b000: dbg_bus[i] <= { tcb2crb_req, vtb2crb_inv, vtb2crb_tag };
267 3'b001: dbg_bus[i] <= { tag_dn[0], tag_up[0], que_tag[0] };
268 3'b010: dbg_bus[i] <= { tag_dn[1], tag_up[1], que_tag[1] };
269 3'b011: dbg_bus[i] <= { tag_chk, tag_ld, tag_up, tag_dn };
270 3'b100: dbg_bus[i] <= { tag_chk, ptr };
271 3'b101: dbg_bus[i] <= 8'h00;
272 3'b110: dbg_bus[i] <= 8'h00;
273 3'b111: dbg_bus[i] <= 8'h00;
274 endcase
275 end
276 end
277
278endmodule // dmu_mmu_crb