1 |
2 |
dmitryr |
// ========== Copyright Header Begin ==========================================
|
2 |
|
|
//
|
3 |
|
|
// OpenSPARC T1 Processor File: bw_r_dcd.v
|
4 |
|
|
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
|
5 |
|
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
|
6 |
|
|
//
|
7 |
|
|
// The above named program is free software; you can redistribute it and/or
|
8 |
|
|
// modify it under the terms of the GNU General Public
|
9 |
|
|
// License version 2 as published by the Free Software Foundation.
|
10 |
|
|
//
|
11 |
|
|
// The above named program is distributed in the hope that it will be
|
12 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
|
|
// General Public License for more details.
|
15 |
|
|
//
|
16 |
|
|
// You should have received a copy of the GNU General Public
|
17 |
|
|
// License along with this work; if not, write to the Free Software
|
18 |
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
19 |
|
|
//
|
20 |
|
|
// ========== Copyright Header End ============================================
|
21 |
|
|
////////////////////////////////////////////////////////////////////////
|
22 |
|
|
/*
|
23 |
|
|
// Module Name:
|
24 |
|
|
// Description: LSU Data Cache.
|
25 |
|
|
// - Physically-Indexed Physically Tagged (PIPT)
|
26 |
|
|
// - 8KB
|
27 |
|
|
// - 4 way set-associative.
|
28 |
|
|
// - 16B lines
|
29 |
|
|
// - 2:1 column select by choosing either lower
|
30 |
|
|
// or upper half of 16B line.
|
31 |
|
|
// - Parity protected on a byte basis.
|
32 |
|
|
// - Byte enables for byte-wide stores.
|
33 |
|
|
//
|
34 |
|
|
*/
|
35 |
|
|
////////////////////////////////////////////////////////////////////////
|
36 |
|
|
// Global header file includes
|
37 |
|
|
////////////////////////////////////////////////////////////////////////
|
38 |
|
|
//`include "sys.h" // system level definition file which contains the
|
39 |
|
|
// time scale definition
|
40 |
|
|
|
41 |
|
|
//`include "iop.h"
|
42 |
|
|
//`include "fabric.h"
|
43 |
|
|
|
44 |
|
|
//FPGA_SYN enables all FPGA related modifications
|
45 |
|
|
`ifdef FPGA_SYN
|
46 |
|
|
`define FPGA_SYN_DCD
|
47 |
|
|
`endif
|
48 |
|
|
|
49 |
|
|
////////////////////////////////////////////////////////////////////////
|
50 |
|
|
// Local header file includes / local defines
|
51 |
|
|
////////////////////////////////////////////////////////////////////////
|
52 |
|
|
|
53 |
|
|
module bw_r_dcd ( /*AUTOARG*/
|
54 |
|
|
// Outputs
|
55 |
|
|
so, dcache_rdata_wb, dcache_rparity_wb, dcache_rparity_err_wb,
|
56 |
|
|
dcache_rdata_msb_w0_m, dcache_rdata_msb_w1_m,
|
57 |
|
|
dcache_rdata_msb_w2_m, dcache_rdata_msb_w3_m,
|
58 |
|
|
dcd_fuse_repair_value, dcd_fuse_repair_en,
|
59 |
|
|
// Inputs
|
60 |
|
|
dcache_rd_addr_e, dcache_alt_addr_e, dcache_rvld_e, dcache_wvld_e,
|
61 |
|
|
dcache_wdata_e, dcache_wr_rway_e, dcache_byte_wr_en_e,
|
62 |
|
|
dcache_alt_rsel_way_e, dcache_rsel_way_wb, dcache_alt_mx_sel_e,
|
63 |
|
|
si, se, sehold, rst_tri_en, arst_l, rclk, dcache_alt_data_w0_m,
|
64 |
|
|
dcache_arry_data_sel_m, efc_spc_fuse_clk1, fuse_dcd_wren,
|
65 |
|
|
fuse_dcd_rid, fuse_dcd_repair_value, fuse_dcd_repair_en
|
66 |
|
|
) ;
|
67 |
|
|
|
68 |
|
|
input [10:3] dcache_rd_addr_e; // read cache index [10:4] + bit [3] offset
|
69 |
|
|
input [10:3] dcache_alt_addr_e; // write/bist/diagnostic read cache index + offset
|
70 |
|
|
|
71 |
|
|
input dcache_rvld_e; // read accesses d$.
|
72 |
|
|
input dcache_wvld_e; // valid write setup to m-stage.
|
73 |
|
|
|
74 |
|
|
input [143:0] dcache_wdata_e; // write data - 16Bx8 + 8b parity.
|
75 |
|
|
input [3:0] dcache_wr_rway_e; // replacement way for load miss/store.
|
76 |
|
|
input [15:0] dcache_byte_wr_en_e; // 16b byte wr enable for stores.
|
77 |
|
|
|
78 |
|
|
input [3:0] dcache_alt_rsel_way_e ; // bist/diagnostic read way select
|
79 |
|
|
input [3:0] dcache_rsel_way_wb; // load way select, connect to cache_way_hit
|
80 |
|
|
input dcache_alt_mx_sel_e;
|
81 |
|
|
|
82 |
|
|
input si;
|
83 |
|
|
input se;
|
84 |
|
|
input sehold;
|
85 |
|
|
|
86 |
|
|
output so;
|
87 |
|
|
|
88 |
|
|
input rst_tri_en ;
|
89 |
|
|
|
90 |
|
|
input arst_l; // used for redundancy flops - do not reset on wrm reset.
|
91 |
|
|
|
92 |
|
|
input rclk;
|
93 |
|
|
|
94 |
|
|
output [63:0] dcache_rdata_wb;
|
95 |
|
|
output [7:0] dcache_rparity_wb;
|
96 |
|
|
output dcache_rparity_err_wb;
|
97 |
|
|
|
98 |
|
|
//=================================
|
99 |
|
|
// dc_fill critical path
|
100 |
|
|
//=================================
|
101 |
|
|
input [63:0] dcache_alt_data_w0_m; //from qdp1
|
102 |
|
|
input dcache_arry_data_sel_m; //from dctl
|
103 |
|
|
|
104 |
|
|
output [7:0] dcache_rdata_msb_w0_m; //to dcdp
|
105 |
|
|
output [7:0] dcache_rdata_msb_w1_m; //to dcdp
|
106 |
|
|
output [7:0] dcache_rdata_msb_w2_m; //to dcdp
|
107 |
|
|
output [7:0] dcache_rdata_msb_w3_m; //to dcdp
|
108 |
|
|
|
109 |
|
|
//-----------------------------------------------------------------------------
|
110 |
|
|
// 32KB block fuse inputs
|
111 |
|
|
//-----------------------------------------------------------------------------
|
112 |
|
|
// efuse non ovl clks
|
113 |
|
|
input efc_spc_fuse_clk1;
|
114 |
|
|
|
115 |
|
|
input fuse_dcd_wren; //redundancy register write enable, qualified
|
116 |
|
|
input [2:0] fuse_dcd_rid; //redundancy register id
|
117 |
|
|
input [7:0] fuse_dcd_repair_value; //data in for redundancy register
|
118 |
|
|
input [1:0] fuse_dcd_repair_en; //enable bits to turn on redundancy
|
119 |
|
|
output [7:0] dcd_fuse_repair_value; //data out for redundancy register
|
120 |
|
|
output [1:0] dcd_fuse_repair_en; //enable bits out
|
121 |
|
|
|
122 |
|
|
// Memory declaration.
|
123 |
|
|
|
124 |
|
|
`ifdef DEFINE_0IN
|
125 |
|
|
wire [143:0] temp_w0a;
|
126 |
|
|
wire [143:0] temp_w1a;
|
127 |
|
|
wire [143:0] temp_w2a;
|
128 |
|
|
wire [143:0] temp_w3a;
|
129 |
|
|
`else
|
130 |
|
|
reg [143:0] w0 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity.
|
131 |
|
|
reg [143:0] w1 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity.
|
132 |
|
|
reg [143:0] w2 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity.
|
133 |
|
|
reg [143:0] w3 [127:0]/* synthesis syn_ramstyle = block_ram syn_ramstyle = no_rw_check */ ; // way0, byte0. Data+Parity.
|
134 |
|
|
|
135 |
|
|
reg [143:0] temp_w0a_reg;
|
136 |
|
|
reg [143:0] temp_w1a_reg;
|
137 |
|
|
reg [143:0] temp_w2a_reg;
|
138 |
|
|
reg [143:0] temp_w3a_reg;
|
139 |
|
|
|
140 |
|
|
wire [143:0] temp_w0a;
|
141 |
|
|
wire [143:0] temp_w1a;
|
142 |
|
|
wire [143:0] temp_w2a;
|
143 |
|
|
wire [143:0] temp_w3a;
|
144 |
|
|
|
145 |
|
|
reg [143:0] temp_w0;
|
146 |
|
|
reg [143:0] temp_w1;
|
147 |
|
|
reg [143:0] temp_w2;
|
148 |
|
|
reg [143:0] temp_w3;
|
149 |
|
|
`endif
|
150 |
|
|
reg [10:3] dcache_rwaddr_m ;
|
151 |
|
|
reg [10:3] dcache_raddr_m ;
|
152 |
|
|
reg dcache_rvld_m ;
|
153 |
|
|
reg wvld_m ;
|
154 |
|
|
reg [143:0] dcache_wdata_m ;
|
155 |
|
|
reg [127:0] rw_wdline ;
|
156 |
|
|
reg [3:0] dcache_wr_rway_m ;
|
157 |
|
|
|
158 |
|
|
reg [63:0] dcache_rdata_w0_wb; // way0 64b data.
|
159 |
|
|
reg [63:0] dcache_rdata_w1_wb; // way1 64b data.
|
160 |
|
|
reg [63:0] dcache_rdata_w2_wb; // way2 64b data.
|
161 |
|
|
reg [63:0] dcache_rdata_w3_wb; // way3 64b data.
|
162 |
|
|
reg [15:0] byte_wr_enable ;
|
163 |
|
|
reg [7:0] ctr;
|
164 |
|
|
|
165 |
|
|
reg dcache_alt_mx_sel_m, dcache_alt_mx_sel_wb;
|
166 |
|
|
reg [3:0] dcache_alt_rsel_way_m, dcache_alt_rsel_way_wb;
|
167 |
|
|
|
168 |
|
|
integer i,j;
|
169 |
|
|
|
170 |
|
|
wire dcache_wvld_m ;
|
171 |
|
|
wire [63:0] dcache_rdata_w0_m; // way0 64b data.
|
172 |
|
|
wire [63:0] dcache_rdata_w1_m; // way1 64b data.
|
173 |
|
|
wire [63:0] dcache_rdata_w2_m; // way2 64b data.
|
174 |
|
|
wire [63:0] dcache_rdata_w3_m; // way3 64b data.
|
175 |
|
|
wire [7:0] dcache_rparity_w0_m; // way0 8b parity.
|
176 |
|
|
wire [7:0] dcache_rparity_w1_m; // way1 8b parity.
|
177 |
|
|
wire [7:0] dcache_rparity_w2_m; // way2 8b parity.
|
178 |
|
|
wire [7:0] dcache_rparity_w3_m; // way3 8b parity.
|
179 |
|
|
|
180 |
|
|
wire [7:0] rd_parity_err_w0_m;
|
181 |
|
|
wire [7:0] rd_parity_err_w1_m;
|
182 |
|
|
wire [7:0] rd_parity_err_w2_m;
|
183 |
|
|
wire [7:0] rd_parity_err_w3_m;
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
wire [143:0] way_mask ;
|
187 |
|
|
wire [143:0] way_mask_inv ;
|
188 |
|
|
|
189 |
|
|
wire [10:3] dcache_rwaddr_e ;
|
190 |
|
|
wire [10:3] dcache_raddr_e ;
|
191 |
|
|
|
192 |
|
|
//calculated parity based on read-out data
|
193 |
|
|
wire [7:0] gen_dcache_parity_w0_m;
|
194 |
|
|
wire [7:0] gen_dcache_parity_w1_m;
|
195 |
|
|
wire [7:0] gen_dcache_parity_w2_m;
|
196 |
|
|
wire [7:0] gen_dcache_parity_w3_m;
|
197 |
|
|
|
198 |
|
|
wire clk;
|
199 |
|
|
assign clk = rclk;
|
200 |
|
|
|
201 |
|
|
//=========================================================================================
|
202 |
|
|
// Staging
|
203 |
|
|
//=========================================================================================
|
204 |
|
|
|
205 |
|
|
// BIST Rd used fill address port.
|
206 |
|
|
assign dcache_rwaddr_e[10:3] =
|
207 |
|
|
(dcache_alt_mx_sel_e) ? dcache_alt_addr_e[10:3] : dcache_rd_addr_e[10:3] ;
|
208 |
|
|
|
209 |
|
|
assign dcache_raddr_e[10:3] =
|
210 |
|
|
(dcache_alt_mx_sel_e) ? dcache_alt_addr_e[10:3] : dcache_rd_addr_e[10:3] ;
|
211 |
|
|
|
212 |
|
|
always @(posedge clk)
|
213 |
|
|
begin
|
214 |
|
|
dcache_alt_mx_sel_m <= sehold ? dcache_alt_mx_sel_m : dcache_alt_mx_sel_e;
|
215 |
|
|
|
216 |
|
|
dcache_alt_rsel_way_m <= sehold ? dcache_alt_rsel_way_m : dcache_alt_rsel_way_e;
|
217 |
|
|
|
218 |
|
|
dcache_rwaddr_m[10:3] <= sehold ? dcache_rwaddr_m[10:3] : dcache_rwaddr_e[10:3] ;
|
219 |
|
|
|
220 |
|
|
dcache_raddr_m[10:3] <= sehold ? dcache_raddr_m[10:3] : dcache_raddr_e[10:3] ;
|
221 |
|
|
|
222 |
|
|
dcache_rvld_m <= sehold ? dcache_rvld_m : dcache_rvld_e ;
|
223 |
|
|
|
224 |
|
|
wvld_m <= sehold ? wvld_m : dcache_wvld_e ;
|
225 |
|
|
|
226 |
|
|
dcache_wdata_m[143:0] <= sehold ? dcache_wdata_m[143:0] : dcache_wdata_e[143:0] ;
|
227 |
|
|
|
228 |
|
|
dcache_wr_rway_m[3:0] <= sehold ? dcache_wr_rway_m[3:0] : dcache_wr_rway_e[3:0] ;
|
229 |
|
|
|
230 |
|
|
byte_wr_enable[15:0] <= sehold ? byte_wr_enable[15:0] : dcache_byte_wr_en_e[15:0] ;
|
231 |
|
|
|
232 |
|
|
end
|
233 |
|
|
|
234 |
|
|
always @ (posedge clk)
|
235 |
|
|
begin
|
236 |
|
|
// JC modified begin
|
237 |
|
|
// dcache_alt_mx_sel_wb <= dcache_alt_mx_sel_m;
|
238 |
|
|
// dcache_alt_rsel_way_wb <= dcache_alt_rsel_way_m;
|
239 |
|
|
dcache_alt_mx_sel_wb <= sehold ? dcache_alt_mx_sel_wb :dcache_alt_mx_sel_m;
|
240 |
|
|
dcache_alt_rsel_way_wb <= sehold ? dcache_alt_rsel_way_wb :dcache_alt_rsel_way_m;
|
241 |
|
|
// JC modified end
|
242 |
|
|
end
|
243 |
|
|
|
244 |
|
|
assign dcache_wvld_m = wvld_m & ~rst_tri_en ;
|
245 |
|
|
|
246 |
|
|
|
247 |
|
|
`ifdef DEFINE_0IN
|
248 |
|
|
wire [3:0] dc_we = dcache_wvld_m ? dcache_wr_rway_m : 4'b0;
|
249 |
|
|
|
250 |
|
|
dc_data dc_data0 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]),
|
251 |
|
|
.we(dc_we [0] ), .wm(way_mask [143:0]),
|
252 |
|
|
.din(dcache_wdata_m[143:0]), .dout(temp_w0a[143:0]) );
|
253 |
|
|
dc_data dc_data1 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]),
|
254 |
|
|
.we(dc_we [1] ), .wm(way_mask [143:0]),
|
255 |
|
|
.din(dcache_wdata_m[143:0]), .dout(temp_w1a[143:0]) );
|
256 |
|
|
dc_data dc_data2 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]),
|
257 |
|
|
.we(dc_we [2] ), .wm(way_mask [143:0]),
|
258 |
|
|
.din(dcache_wdata_m[143:0]), .dout(temp_w2a[143:0]) );
|
259 |
|
|
dc_data dc_data3 ( .nclk(~clk), .adr(dcache_rwaddr_m[10:4]),
|
260 |
|
|
.we(dc_we [3] ), .wm(way_mask [143:0]),
|
261 |
|
|
.din(dcache_wdata_m[143:0]), .dout(temp_w3a[143:0]) );
|
262 |
|
|
`else
|
263 |
|
|
//=========================================================================================
|
264 |
|
|
// generate wordlines
|
265 |
|
|
//=========================================================================================
|
266 |
|
|
|
267 |
|
|
// Generate at posedge of clk.
|
268 |
|
|
// JC modified begin
|
269 |
|
|
/*
|
270 |
|
|
always @ (posedge clk)
|
271 |
|
|
begin
|
272 |
|
|
for (ctr=8'h00;ctr<128;ctr=ctr+1)
|
273 |
|
|
begin
|
274 |
|
|
if (clk & ({1'b0,dcache_rwaddr_e[10:4]} == ctr) &
|
275 |
|
|
(dcache_rvld_e | dcache_wvld_e))
|
276 |
|
|
rw_wdline[ctr] = 1'b1;
|
277 |
|
|
else
|
278 |
|
|
rw_wdline[ctr] = 1'b0;
|
279 |
|
|
end
|
280 |
|
|
end
|
281 |
|
|
*/
|
282 |
|
|
|
283 |
|
|
`ifdef FPGA_SYN_DCD
|
284 |
|
|
`else
|
285 |
|
|
always @ (clk or dcache_rwaddr_m or dcache_wvld_m or dcache_rvld_m)
|
286 |
|
|
begin
|
287 |
|
|
if (clk) begin
|
288 |
|
|
for (ctr=8'h00;ctr<128;ctr=ctr+1)
|
289 |
|
|
begin
|
290 |
|
|
if (({1'b0,dcache_rwaddr_m[10:4]} == ctr) &
|
291 |
|
|
(dcache_rvld_m | dcache_wvld_m))
|
292 |
|
|
rw_wdline[ctr] = 1'b1;
|
293 |
|
|
else
|
294 |
|
|
rw_wdline[ctr] = 1'b0;
|
295 |
|
|
end
|
296 |
|
|
end
|
297 |
|
|
end
|
298 |
|
|
// JC modified end
|
299 |
|
|
`endif
|
300 |
|
|
|
301 |
|
|
|
302 |
|
|
//=========================================================================================
|
303 |
|
|
// Read from Memory.
|
304 |
|
|
//=========================================================================================
|
305 |
|
|
|
306 |
|
|
`ifdef FPGA_SYN_DCD
|
307 |
|
|
always @(posedge clk) begin
|
308 |
|
|
temp_w0a_reg[143:0] = w0[dcache_raddr_e[10:4]];
|
309 |
|
|
temp_w1a_reg[143:0] = w1[dcache_raddr_e[10:4]];
|
310 |
|
|
temp_w2a_reg[143:0] = w2[dcache_raddr_e[10:4]];
|
311 |
|
|
temp_w3a_reg[143:0] = w3[dcache_raddr_e[10:4]];
|
312 |
|
|
end
|
313 |
|
|
`else
|
314 |
|
|
// Read
|
315 |
|
|
always @ (negedge clk)
|
316 |
|
|
begin
|
317 |
|
|
for (i=0;i<128;i=i+1)
|
318 |
|
|
begin
|
319 |
|
|
if (rw_wdline[i] & dcache_rvld_m)
|
320 |
|
|
begin
|
321 |
|
|
temp_w0a_reg[143:0] <= w0[i];
|
322 |
|
|
temp_w1a_reg[143:0] <= w1[i];
|
323 |
|
|
temp_w2a_reg[143:0] <= w2[i];
|
324 |
|
|
temp_w3a_reg[143:0] <= w3[i];
|
325 |
|
|
end
|
326 |
|
|
end
|
327 |
|
|
end
|
328 |
|
|
`endif
|
329 |
|
|
|
330 |
|
|
//removed stablizer, zero out without read
|
331 |
|
|
assign temp_w0a[143:0] = dcache_rvld_m? temp_w0a_reg[143:0]: 144'b0;
|
332 |
|
|
assign temp_w1a[143:0] = dcache_rvld_m? temp_w1a_reg[143:0]: 144'b0;
|
333 |
|
|
assign temp_w2a[143:0] = dcache_rvld_m? temp_w2a_reg[143:0]: 144'b0;
|
334 |
|
|
assign temp_w3a[143:0] = dcache_rvld_m? temp_w3a_reg[143:0]: 144'b0;
|
335 |
|
|
|
336 |
|
|
`endif
|
337 |
|
|
|
338 |
|
|
// Prior to SA, column mux (64(D)+8(P))x4 bits. Assume parity is
|
339 |
|
|
// at the end of the 144b line. Entry is wX||Parity
|
340 |
|
|
|
341 |
|
|
// Select either upper or lower 64b from each of the 4 ways.
|
342 |
|
|
assign dcache_rdata_w0_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w0a[143:80] : temp_w0a[79:16] ;
|
343 |
|
|
assign dcache_rdata_w1_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w1a[143:80] : temp_w1a[79:16] ;
|
344 |
|
|
assign dcache_rdata_w2_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w2a[143:80] : temp_w2a[79:16] ;
|
345 |
|
|
assign dcache_rdata_w3_m[63:0] = ~dcache_rwaddr_m[3] ? temp_w3a[143:80] : temp_w3a[79:16] ;
|
346 |
|
|
|
347 |
|
|
wire [7:0] dcache_msb_w0_m;
|
348 |
|
|
wire [7:0] dcache_alt_data_w0_msb_m;
|
349 |
|
|
|
350 |
|
|
//MSB sent out to dcdp in M stage
|
351 |
|
|
assign dcache_msb_w0_m[7:0]=
|
352 |
|
|
{dcache_rdata_w0_m[63],
|
353 |
|
|
dcache_rdata_w0_m[55],
|
354 |
|
|
dcache_rdata_w0_m[47],
|
355 |
|
|
dcache_rdata_w0_m[39],
|
356 |
|
|
dcache_rdata_w0_m[31],
|
357 |
|
|
dcache_rdata_w0_m[23],
|
358 |
|
|
dcache_rdata_w0_m[15],
|
359 |
|
|
dcache_rdata_w0_m[07]} ;
|
360 |
|
|
|
361 |
|
|
assign dcache_alt_data_w0_msb_m [7:0]=
|
362 |
|
|
{dcache_alt_data_w0_m[63],
|
363 |
|
|
dcache_alt_data_w0_m[55],
|
364 |
|
|
dcache_alt_data_w0_m[47],
|
365 |
|
|
dcache_alt_data_w0_m[39],
|
366 |
|
|
dcache_alt_data_w0_m[31],
|
367 |
|
|
dcache_alt_data_w0_m[23],
|
368 |
|
|
dcache_alt_data_w0_m[15],
|
369 |
|
|
dcache_alt_data_w0_m[07]} ;
|
370 |
|
|
|
371 |
|
|
//2-to-1 mux
|
372 |
|
|
assign dcache_rdata_msb_w0_m[7:0] = dcache_arry_data_sel_m ?
|
373 |
|
|
dcache_msb_w0_m[7:0] :
|
374 |
|
|
dcache_alt_data_w0_msb_m[7:0];
|
375 |
|
|
|
376 |
|
|
assign dcache_rdata_msb_w1_m[7:0]=
|
377 |
|
|
{dcache_rdata_w1_m[63],
|
378 |
|
|
dcache_rdata_w1_m[55],
|
379 |
|
|
dcache_rdata_w1_m[47],
|
380 |
|
|
dcache_rdata_w1_m[39],
|
381 |
|
|
dcache_rdata_w1_m[31],
|
382 |
|
|
dcache_rdata_w1_m[23],
|
383 |
|
|
dcache_rdata_w1_m[15],
|
384 |
|
|
dcache_rdata_w1_m[07]} ;
|
385 |
|
|
|
386 |
|
|
assign dcache_rdata_msb_w2_m[7:0]=
|
387 |
|
|
{dcache_rdata_w2_m[63],
|
388 |
|
|
dcache_rdata_w2_m[55],
|
389 |
|
|
dcache_rdata_w2_m[47],
|
390 |
|
|
dcache_rdata_w2_m[39],
|
391 |
|
|
dcache_rdata_w2_m[31],
|
392 |
|
|
dcache_rdata_w2_m[23],
|
393 |
|
|
dcache_rdata_w2_m[15],
|
394 |
|
|
dcache_rdata_w2_m[07]} ;
|
395 |
|
|
|
396 |
|
|
assign dcache_rdata_msb_w3_m[7:0]=
|
397 |
|
|
{dcache_rdata_w3_m[63],
|
398 |
|
|
dcache_rdata_w3_m[55],
|
399 |
|
|
dcache_rdata_w3_m[47],
|
400 |
|
|
dcache_rdata_w3_m[39],
|
401 |
|
|
dcache_rdata_w3_m[31],
|
402 |
|
|
dcache_rdata_w3_m[23],
|
403 |
|
|
dcache_rdata_w3_m[15],
|
404 |
|
|
dcache_rdata_w3_m[07]} ;
|
405 |
|
|
|
406 |
|
|
wire [63:0] rdata_w0_m;
|
407 |
|
|
wire [63:0] rdata_w1_m;
|
408 |
|
|
wire [63:0] rdata_w2_m;
|
409 |
|
|
wire [63:0] rdata_w3_m;
|
410 |
|
|
|
411 |
|
|
//2-to-1 mux
|
412 |
|
|
//dcache_alt_mx_sel default 0001 (way 0) when not in MBIST mode (logic in qdp2)
|
413 |
|
|
assign rdata_w0_m[63:0] = dcache_arry_data_sel_m ?
|
414 |
|
|
dcache_rdata_w0_m[63:0] : dcache_alt_data_w0_m[63:0];
|
415 |
|
|
|
416 |
|
|
//assign rdata_w0_m[63:0] = dcache_rdata_w0_m[63:0];
|
417 |
|
|
assign rdata_w1_m[63:0] = dcache_rdata_w1_m[63:0];
|
418 |
|
|
assign rdata_w2_m[63:0] = dcache_rdata_w2_m[63:0];
|
419 |
|
|
assign rdata_w3_m[63:0] = dcache_rdata_w3_m[63:0];
|
420 |
|
|
|
421 |
|
|
// Select upper half or lower half of parity.
|
422 |
|
|
assign dcache_rparity_w0_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w0a[15:8] : temp_w0a[7:0] ;
|
423 |
|
|
assign dcache_rparity_w1_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w1a[15:8] : temp_w1a[7:0] ;
|
424 |
|
|
assign dcache_rparity_w2_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w2a[15:8] : temp_w2a[7:0] ;
|
425 |
|
|
assign dcache_rparity_w3_m[7:0] = ~dcache_rwaddr_m[3] ? temp_w3a[15:8] : temp_w3a[7:0] ;
|
426 |
|
|
|
427 |
|
|
reg [7:0] dcache_rparity_w0_wb;
|
428 |
|
|
reg [7:0] dcache_rparity_w1_wb;
|
429 |
|
|
reg [7:0] dcache_rparity_w2_wb;
|
430 |
|
|
reg [7:0] dcache_rparity_w3_wb;
|
431 |
|
|
|
432 |
|
|
reg [7:0] rd_parity_err_w0_wb;
|
433 |
|
|
reg [7:0] rd_parity_err_w1_wb;
|
434 |
|
|
reg [7:0] rd_parity_err_w2_wb;
|
435 |
|
|
reg [7:0] rd_parity_err_w3_wb;
|
436 |
|
|
|
437 |
|
|
|
438 |
|
|
// Stage to WB
|
439 |
|
|
always @(posedge clk)
|
440 |
|
|
begin
|
441 |
|
|
dcache_rdata_w0_wb[63:0] <= rdata_w0_m[63:0] ;
|
442 |
|
|
dcache_rdata_w1_wb[63:0] <= rdata_w1_m[63:0] ;
|
443 |
|
|
dcache_rdata_w2_wb[63:0] <= rdata_w2_m[63:0] ;
|
444 |
|
|
dcache_rdata_w3_wb[63:0] <= rdata_w3_m[63:0] ;
|
445 |
|
|
|
446 |
|
|
dcache_rparity_w0_wb[7:0] <= dcache_rparity_w0_m[7:0];
|
447 |
|
|
dcache_rparity_w1_wb[7:0] <= dcache_rparity_w1_m[7:0];
|
448 |
|
|
dcache_rparity_w2_wb[7:0] <= dcache_rparity_w2_m[7:0];
|
449 |
|
|
dcache_rparity_w3_wb[7:0] <= dcache_rparity_w3_m[7:0];
|
450 |
|
|
|
451 |
|
|
rd_parity_err_w0_wb [7:0] <= rd_parity_err_w0_m[7:0];
|
452 |
|
|
rd_parity_err_w1_wb [7:0] <= rd_parity_err_w1_m[7:0];
|
453 |
|
|
rd_parity_err_w2_wb [7:0] <= rd_parity_err_w2_m[7:0];
|
454 |
|
|
rd_parity_err_w3_wb [7:0] <= rd_parity_err_w3_m[7:0];
|
455 |
|
|
|
456 |
|
|
end
|
457 |
|
|
|
458 |
|
|
//parity calculation and check are done in M stage for 4 way data
|
459 |
|
|
wire rd_parity_err_w0;
|
460 |
|
|
wire rd_parity_err_w1;
|
461 |
|
|
wire rd_parity_err_w2;
|
462 |
|
|
wire rd_parity_err_w3;
|
463 |
|
|
|
464 |
|
|
lsu_dc_parity_gen #(8,8) parity_gen_w0 (
|
465 |
|
|
.data_in (dcache_rdata_w0_m[63:0]),
|
466 |
|
|
.parity_out (gen_dcache_parity_w0_m[7:0])
|
467 |
|
|
);
|
468 |
|
|
|
469 |
|
|
assign rd_parity_err_w0_m[7:0] = dcache_rvld_m ? (dcache_rparity_w0_m[7:0] ^ gen_dcache_parity_w0_m[7:0]) :
|
470 |
|
|
8'hff;
|
471 |
|
|
|
472 |
|
|
|
473 |
|
|
lsu_dc_parity_gen #(8,8) parity_gen_w1 (
|
474 |
|
|
.data_in (dcache_rdata_w1_m[63:0]),
|
475 |
|
|
.parity_out (gen_dcache_parity_w1_m[7:0])
|
476 |
|
|
);
|
477 |
|
|
|
478 |
|
|
assign rd_parity_err_w1_m[7:0] = dcache_rvld_m ? (dcache_rparity_w1_m[7:0] ^ gen_dcache_parity_w1_m[7:0]) :
|
479 |
|
|
8'hff;
|
480 |
|
|
|
481 |
|
|
lsu_dc_parity_gen #(8,8) parity_gen_w2 (
|
482 |
|
|
.data_in (dcache_rdata_w2_m[63:0]),
|
483 |
|
|
.parity_out (gen_dcache_parity_w2_m[7:0])
|
484 |
|
|
);
|
485 |
|
|
assign rd_parity_err_w2_m[7:0] = dcache_rvld_m ? (dcache_rparity_w2_m[7:0] ^ gen_dcache_parity_w2_m[7:0]) :
|
486 |
|
|
8'hff;
|
487 |
|
|
|
488 |
|
|
lsu_dc_parity_gen #(8,8) parity_gen_w3 (
|
489 |
|
|
.data_in (dcache_rdata_w3_m[63:0]),
|
490 |
|
|
.parity_out (gen_dcache_parity_w3_m[7:0])
|
491 |
|
|
);
|
492 |
|
|
assign rd_parity_err_w3_m[7:0] = dcache_rvld_m ? (dcache_rparity_w3_m[7:0] ^ gen_dcache_parity_w3_m[7:0]) :
|
493 |
|
|
8'hff;
|
494 |
|
|
|
495 |
|
|
|
496 |
|
|
// way select mux on READ
|
497 |
|
|
// Select one of four ways from indexed cache set.
|
498 |
|
|
|
499 |
|
|
wire [3:0] dcache_rd_sel_way_wb;
|
500 |
|
|
assign dcache_rd_sel_way_wb[3:0] = dcache_alt_mx_sel_wb ? dcache_alt_rsel_way_wb[3:0] :
|
501 |
|
|
dcache_rsel_way_wb[3:0];
|
502 |
|
|
|
503 |
|
|
assign dcache_rdata_wb[63:0] =
|
504 |
|
|
(dcache_rd_sel_way_wb[0] ? dcache_rdata_w0_wb[63:0] : 64'b0) |
|
505 |
|
|
(dcache_rd_sel_way_wb[1] ? dcache_rdata_w1_wb[63:0] : 64'b0) |
|
506 |
|
|
(dcache_rd_sel_way_wb[2] ? dcache_rdata_w2_wb[63:0] : 64'b0) |
|
507 |
|
|
(dcache_rd_sel_way_wb[3] ? dcache_rdata_w3_wb[63:0] : 64'b0);
|
508 |
|
|
|
509 |
|
|
//parity err in W-stage, cache_way_hit may not be one-hot
|
510 |
|
|
assign rd_parity_err_w0 = |(rd_parity_err_w0_wb[7:0]);
|
511 |
|
|
assign rd_parity_err_w1 = |(rd_parity_err_w1_wb[7:0]);
|
512 |
|
|
assign rd_parity_err_w2 = |(rd_parity_err_w2_wb[7:0]);
|
513 |
|
|
assign rd_parity_err_w3 = |(rd_parity_err_w3_wb[7:0]);
|
514 |
|
|
|
515 |
|
|
assign dcache_rparity_err_wb = rd_parity_err_w3 & dcache_rd_sel_way_wb[3] |
|
516 |
|
|
rd_parity_err_w2 & dcache_rd_sel_way_wb[2] |
|
517 |
|
|
rd_parity_err_w1 & dcache_rd_sel_way_wb[1] |
|
518 |
|
|
rd_parity_err_w0 & dcache_rd_sel_way_wb[0] ;
|
519 |
|
|
|
520 |
|
|
//mux4ds #(64) dcache_rdata_wb_mx (
|
521 |
|
|
// .in0 (dcache_rdata_w0_wb[63:0]),
|
522 |
|
|
// .in1 (dcache_rdata_w1_wb[63:0]),
|
523 |
|
|
// .in2 (dcache_rdata_w2_wb[63:0]),
|
524 |
|
|
// .in3 (dcache_rdata_w3_wb[63:0]),
|
525 |
|
|
// .sel0 (dcache_rd_sel_way_wb[0]),
|
526 |
|
|
// .sel1 (dcache_rd_sel_way_wb[1]),
|
527 |
|
|
// .sel2 (dcache_rd_sel_way_wb[2]),
|
528 |
|
|
// .sel3 (dcache_rd_sel_way_wb[3]),
|
529 |
|
|
// .dout (dcache_rdata_wb[63:0])
|
530 |
|
|
//);
|
531 |
|
|
|
532 |
|
|
// dcache_rparity_wb only used by MBIST
|
533 |
|
|
//mux4ds #(8) dcache_rparity_wb_mx (
|
534 |
|
|
// .in0 (dcache_rparity_w0_wb[7:0]),
|
535 |
|
|
// .in1 (dcache_rparity_w1_wb[7:0]),
|
536 |
|
|
// .in2 (dcache_rparity_w2_wb[7:0]),
|
537 |
|
|
// .in3 (dcache_rparity_w3_wb[7:0]),
|
538 |
|
|
// .sel0(dcache_alt_rsel_way_wb[0]),
|
539 |
|
|
// .sel1(dcache_alt_rsel_way_wb[1]),
|
540 |
|
|
// .sel2(dcache_alt_rsel_way_wb[2]),
|
541 |
|
|
// .sel3(dcache_alt_rsel_way_wb[3]),
|
542 |
|
|
// .dout(dcache_rparity_wb[7:0])
|
543 |
|
|
//);
|
544 |
|
|
|
545 |
|
|
assign dcache_rparity_wb[7:0] =
|
546 |
|
|
( dcache_rd_sel_way_wb[0] ? dcache_rparity_w0_wb[7:0] : 8'b0 ) |
|
547 |
|
|
( dcache_rd_sel_way_wb[1] ? dcache_rparity_w1_wb[7:0] : 8'b0 ) |
|
548 |
|
|
( dcache_rd_sel_way_wb[2] ? dcache_rparity_w2_wb[7:0] : 8'b0 ) |
|
549 |
|
|
( dcache_rd_sel_way_wb[3] ? dcache_rparity_w3_wb[7:0] : 8'b0 ) ;
|
550 |
|
|
|
551 |
|
|
|
552 |
|
|
//=========================================================================================
|
553 |
|
|
// Write to Memory
|
554 |
|
|
//=========================================================================================
|
555 |
|
|
|
556 |
|
|
// Reads and writes are mutex as array is single-ported.
|
557 |
|
|
|
558 |
|
|
|
559 |
|
|
// Includes data(128b)+parity(16b).
|
560 |
|
|
assign way_mask[143:0] =
|
561 |
|
|
{{8{byte_wr_enable[15]}},{8{byte_wr_enable[14]}},{8{byte_wr_enable[13]}},
|
562 |
|
|
{8{byte_wr_enable[12]}},{8{byte_wr_enable[11]}},{8{byte_wr_enable[10]}},
|
563 |
|
|
{8{byte_wr_enable[9]}}, {8{byte_wr_enable[8]}}, {8{byte_wr_enable[7]}},
|
564 |
|
|
{8{byte_wr_enable[6]}}, {8{byte_wr_enable[5]}}, {8{byte_wr_enable[4]}},
|
565 |
|
|
{8{byte_wr_enable[3]}}, {8{byte_wr_enable[2]}}, {8{byte_wr_enable[1]}},
|
566 |
|
|
{8{byte_wr_enable[0]}}, byte_wr_enable[15:0]} ;
|
567 |
|
|
|
568 |
|
|
assign way_mask_inv[143:0] = ~way_mask[143:0];
|
569 |
|
|
|
570 |
|
|
|
571 |
|
|
always @ (negedge clk)
|
572 |
|
|
begin
|
573 |
|
|
|
574 |
|
|
`ifdef FPGA_SYN_DCD
|
575 |
|
|
|
576 |
|
|
if(dcache_wvld_m & dcache_wr_rway_m[0]) begin
|
577 |
|
|
w0[dcache_rwaddr_m[10:4]] = (temp_w0a_reg[143:0] & way_mask_inv[143:0]) |
|
578 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
579 |
|
|
end
|
580 |
|
|
if(dcache_wvld_m & dcache_wr_rway_m[1]) begin
|
581 |
|
|
w1[dcache_rwaddr_m[10:4]] = (temp_w1a_reg[143:0] & way_mask_inv[143:0]) |
|
582 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
583 |
|
|
end
|
584 |
|
|
if(dcache_wvld_m & dcache_wr_rway_m[2]) begin
|
585 |
|
|
w2[dcache_rwaddr_m[10:4]] = (temp_w2a_reg[143:0] & way_mask_inv[143:0]) |
|
586 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
587 |
|
|
end
|
588 |
|
|
if(dcache_wvld_m & dcache_wr_rway_m[3]) begin
|
589 |
|
|
w3[dcache_rwaddr_m[10:4]] = (temp_w3a_reg[143:0] & way_mask_inv[143:0]) |
|
590 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
591 |
|
|
end
|
592 |
|
|
|
593 |
|
|
`else // !`ifdef FPGA_SYN_DCD
|
594 |
|
|
|
595 |
|
|
for (j=0;j<128;j=j+1)
|
596 |
|
|
begin
|
597 |
|
|
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[0])
|
598 |
|
|
begin
|
599 |
|
|
// read
|
600 |
|
|
temp_w0[143:0] = w0[j];
|
601 |
|
|
// modify & write
|
602 |
|
|
w0[j] = (temp_w0[143:0] & way_mask_inv[143:0]) |
|
603 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
604 |
|
|
end
|
605 |
|
|
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[1])
|
606 |
|
|
begin
|
607 |
|
|
// read
|
608 |
|
|
temp_w1[143:0] = w1[j];
|
609 |
|
|
// modify & write
|
610 |
|
|
w1[j] = (temp_w1[143:0] & way_mask_inv[143:0]) |
|
611 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
612 |
|
|
end
|
613 |
|
|
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[2])
|
614 |
|
|
begin
|
615 |
|
|
// read
|
616 |
|
|
temp_w2[143:0] = w2[j];
|
617 |
|
|
// modify & write
|
618 |
|
|
w2[j] = (temp_w2[143:0] & way_mask_inv[143:0]) |
|
619 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
620 |
|
|
end
|
621 |
|
|
if (rw_wdline[j] & dcache_wvld_m & dcache_wr_rway_m[3])
|
622 |
|
|
begin
|
623 |
|
|
// read
|
624 |
|
|
temp_w3[143:0] = w3[j];
|
625 |
|
|
// modify & write.
|
626 |
|
|
w3[j] = (temp_w3[143:0] & way_mask_inv[143:0]) |
|
627 |
|
|
(dcache_wdata_m[143:0] & way_mask[143:0]) ;
|
628 |
|
|
end
|
629 |
|
|
end
|
630 |
|
|
`endif // !`ifdef FPGA_SYN_DCD
|
631 |
|
|
|
632 |
|
|
end // always @ (negedge clk)
|
633 |
|
|
|
634 |
|
|
endmodule
|
635 |
|
|
|
636 |
|
|
|