OpenCores
URL https://opencores.org/ocsvn/mpmc8/mpmc8/trunk

Subversion Repositories mpmc8

[/] [mpmc8/] [trunk/] [rtl/] [mpmc10/] [mpcm10_cache_wb.sv] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4 11 robfinch
//   \\__/ o\    (C) 2015-2023  Robert Finch, Waterloo
5 5 robfinch
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@finitron.ca
7
//       ||
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35
// ============================================================================
36
//
37
import const_pkg::*;
38
import wishbone_pkg::*;
39
import mpmc10_pkg::*;
40
 
41
module mpmc10_cache_wb (input rst, wclk, inv,
42 11 robfinch
        input wb_cmd_request128_t wchi,
43 5 robfinch
        output wb_write_response_t wcho,
44 11 robfinch
        input wb_cmd_request128_t ld,
45 5 robfinch
        input ch0clk,
46
        input ch1clk,
47
        input ch2clk,
48
        input ch3clk,
49
        input ch4clk,
50
        input ch5clk,
51
        input ch6clk,
52
        input ch7clk,
53 11 robfinch
        input wb_cmd_request128_t ch0i,
54
        input wb_cmd_request128_t ch1i,
55
        input wb_cmd_request128_t ch2i,
56
        input wb_cmd_request128_t ch3i,
57
        input wb_cmd_request128_t ch4i,
58
        input wb_cmd_request128_t ch5i,
59
        input wb_cmd_request128_t ch6i,
60
        input wb_cmd_request128_t ch7i,
61 5 robfinch
        input ch0wack,
62
        input ch1wack,
63
        input ch2wack,
64
        input ch3wack,
65
        input ch4wack,
66
        input ch5wack,
67
        input ch6wack,
68
        input ch7wack,
69 11 robfinch
        output wb_cmd_response128_t ch0o,
70
        output wb_cmd_response128_t ch1o,
71
        output wb_cmd_response128_t ch2o,
72
        output wb_cmd_response128_t ch3o,
73
        output wb_cmd_response128_t ch4o,
74
        output wb_cmd_response128_t ch5o,
75
        output wb_cmd_response128_t ch6o,
76
        output wb_cmd_response128_t ch7o,
77
        output reg ch0hit,
78
        output reg ch1hit,
79
        output reg ch2hit,
80
        output reg ch3hit,
81
        output reg ch4hit,
82
        output reg ch5hit,
83
        output reg ch6hit,
84
        output reg ch7hit
85 5 robfinch
);
86
parameter DEP=1024;
87
parameter LOBIT=4;
88
parameter HIBIT=13;
89
 
90
integer n,n2,n3,n4,n5;
91
 
92
(* ram_style="distributed" *)
93
reg [1023:0] vbit [0:CACHE_ASSOC-1];
94
initial begin
95
        for (n5 = 0; n5 < CACHE_ASSOC; n5 = n5 + 1)
96
                vbit[n5] <= 'd0;
97
end
98
 
99
reg [31:0] radrr [0:8];
100
reg wchi_stb, wchi_stb_r;
101 8 robfinch
reg [15:0] wchi_sel;
102 7 robfinch
reg [31:0] wchi_adr, wchi_adr1;
103 5 robfinch
reg [127:0] wchi_dat;
104
 
105
mpmc10_quad_cache_line_t doutb [0:8];
106
mpmc10_quad_cache_line_t wrdata, wdata;
107
 
108
reg [31:0] wadr;
109 7 robfinch
reg [127:0] lddat1, lddat2;
110
reg [31:0] wadr2;
111 5 robfinch
reg wstrb;
112
reg [$clog2(CACHE_ASSOC)-1:0] wway;
113
 
114
reg [CACHE_ASSOC-1:0] vbito0a;
115
reg [CACHE_ASSOC-1:0] vbito1a;
116
reg [CACHE_ASSOC-1:0] vbito2a;
117
reg [CACHE_ASSOC-1:0] vbito3a;
118
reg [CACHE_ASSOC-1:0] vbito4a;
119
reg [CACHE_ASSOC-1:0] vbito5a;
120
reg [CACHE_ASSOC-1:0] vbito6a;
121
reg [CACHE_ASSOC-1:0] vbito7a;
122
reg [CACHE_ASSOC-1:0] vbito8a;
123
 
124
reg [CACHE_ASSOC-1:0] hit0a;
125
reg [CACHE_ASSOC-1:0] hit1a;
126
reg [CACHE_ASSOC-1:0] hit2a;
127
reg [CACHE_ASSOC-1:0] hit3a;
128
reg [CACHE_ASSOC-1:0] hit4a;
129
reg [CACHE_ASSOC-1:0] hit5a;
130
reg [CACHE_ASSOC-1:0] hit6a;
131
reg [CACHE_ASSOC-1:0] hit7a;
132
reg [CACHE_ASSOC-1:0] hit8a;
133
 
134
reg stb0;
135
reg stb1;
136
reg stb2;
137
reg stb3;
138
reg stb4;
139
reg stb5;
140
reg stb6;
141
reg stb7;
142
reg [8:0] rstb;
143
 
144 11 robfinch
always_ff @(posedge ch0clk) radrr[0] <= ch0i.padr;
145
always_ff @(posedge ch1clk) radrr[1] <= ch1i.padr;
146
always_ff @(posedge ch2clk) radrr[2] <= ch2i.padr;
147
always_ff @(posedge ch3clk) radrr[3] <= ch3i.padr;
148
always_ff @(posedge ch4clk) radrr[4] <= ch4i.padr;
149
always_ff @(posedge ch5clk) radrr[5] <= ch5i.padr;
150
always_ff @(posedge ch6clk) radrr[6] <= ch6i.padr;
151
always_ff @(posedge ch7clk) radrr[7] <= ch7i.padr;
152
always_ff @(posedge wclk) radrr[8] <= ld.cyc ? ld.padr : wchi.padr;
153
always_ff @(posedge wclk) wchi_adr1 <= wchi.padr;
154 7 robfinch
always_ff @(posedge wclk) wchi_adr <= wchi_adr1;
155 5 robfinch
 
156
always_ff @(posedge ch0clk) stb0 <= ch0i.stb;
157
always_ff @(posedge ch1clk) stb1 <= ch1i.stb;
158
always_ff @(posedge ch2clk) stb2 <= ch2i.stb;
159
always_ff @(posedge ch3clk) stb3 <= ch3i.stb;
160
always_ff @(posedge ch4clk) stb4 <= ch4i.stb;
161
always_ff @(posedge ch5clk) stb5 <= ch5i.stb;
162
always_ff @(posedge ch6clk) stb6 <= ch6i.stb;
163
always_ff @(posedge ch7clk) stb7 <= ch7i.stb;
164
 
165
always_comb rstb[0] <= ch0i.stb & ~ch0i.we;
166
always_comb rstb[1] <= ch1i.stb & ~ch1i.we;
167
always_comb rstb[2] <= ch2i.stb & ~ch2i.we;
168
always_comb rstb[3] <= ch3i.stb & ~ch3i.we;
169
always_comb rstb[4] <= ch4i.stb & ~ch4i.we;
170
always_comb rstb[5] <= ch5i.stb & ~ch5i.we;
171
always_comb rstb[6] <= ch6i.stb & ~ch6i.we;
172
always_comb rstb[7] <= ch7i.stb & ~ch7i.we;
173 7 robfinch
always_comb rstb[8] <= ld.cyc ? ld.stb : wchi.stb;
174 5 robfinch
 
175
always_ff @(posedge wclk) wchi_stb_r <= wchi.stb;
176
always_ff @(posedge wclk) wchi_stb <= wchi_stb_r;
177 8 robfinch
always_ff @(posedge wclk) wchi_sel <= wchi.sel;
178 11 robfinch
always_ff @(posedge wclk) wchi_dat <= wchi.data1;
179 5 robfinch
 
180
reg [8:0] rclkp;
181
always_comb
182
begin
183
        rclkp[0] = ch0clk;
184
        rclkp[1] = ch1clk;
185
        rclkp[2] = ch2clk;
186
        rclkp[3] = ch3clk;
187
        rclkp[4] = ch4clk;
188
        rclkp[5] = ch5clk;
189
        rclkp[6] = ch6clk;
190
        rclkp[7] = ch7clk;
191
        rclkp[8] = wclk;
192
end
193
 
194
reg [HIBIT-LOBIT:0] radr [0:8];
195
always_comb
196
begin
197 11 robfinch
        radr[0] = ch0i.padr[HIBIT:LOBIT];
198
        radr[1] = ch1i.padr[HIBIT:LOBIT];
199
        radr[2] = ch2i.padr[HIBIT:LOBIT];
200
        radr[3] = ch3i.padr[HIBIT:LOBIT];
201
        radr[4] = ch4i.padr[HIBIT:LOBIT];
202
        radr[5] = ch5i.padr[HIBIT:LOBIT];
203
        radr[6] = ch6i.padr[HIBIT:LOBIT];
204
        radr[7] = ch7i.padr[HIBIT:LOBIT];
205
        radr[8] = ld.cyc ? ld.padr[HIBIT:LOBIT] : wchi.padr[HIBIT:LOBIT];
206 5 robfinch
end
207
 
208
   // xpm_memory_sdpram: Simple Dual Port RAM
209
   // Xilinx Parameterized Macro, version 2020.2
210
 
211
genvar gway,gport;
212
 
213
generate begin : gCacheRAM
214
        for (gport = 0; gport < 9; gport = gport + 1) begin
215
        xpm_memory_sdpram #(
216
                .ADDR_WIDTH_A($clog2(DEP)),
217
                .ADDR_WIDTH_B($clog2(DEP)),
218
                .AUTO_SLEEP_TIME(0),
219
                .BYTE_WRITE_WIDTH_A($bits(mpmc10_quad_cache_line_t)),
220
                .CASCADE_HEIGHT(0),
221
                .CLOCKING_MODE("independent_clock"), // String
222
                .ECC_MODE("no_ecc"),            // String
223
                .MEMORY_INIT_FILE("none"),      // String
224
                .MEMORY_INIT_PARAM("0"),        // String
225
                .MEMORY_OPTIMIZATION("true"),   // String
226
                .MEMORY_PRIMITIVE("block"),      // String
227
                .MEMORY_SIZE($bits(mpmc10_quad_cache_line_t)*DEP),         // DECIMAL
228
                .MESSAGE_CONTROL(0),            // DECIMAL
229
                .READ_DATA_WIDTH_B($bits(mpmc10_quad_cache_line_t)),         // DECIMAL
230
                .READ_LATENCY_B(1),
231
                .READ_RESET_VALUE_B("0"),       // String
232
                .RST_MODE_A("SYNC"),            // String
233
                .RST_MODE_B("SYNC"),            // String
234
                .SIM_ASSERT_CHK(0),             // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
235
                .USE_EMBEDDED_CONSTRAINT(0),
236
                .USE_MEM_INIT(1),
237
                .WAKEUP_TIME("disable_sleep"),  // String
238
                .WRITE_DATA_WIDTH_A($bits(mpmc10_quad_cache_line_t)),        // DECIMAL
239
                .WRITE_MODE_B("no_change")      // String
240
        )
241
                xpm_memory_sdpram_inst1 (
242
                .dbiterrb(),             // 1-bit output: Status signal to indicate double bit error occurrence
243
                                                 // on the data output of port B.
244
 
245
                .doutb(doutb[gport]),                   // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
246
                .sbiterrb(),             // 1-bit output: Status signal to indicate single bit error occurrence
247
                                                 // on the data output of port B.
248
 
249
                .addra(wadr2[HIBIT:LOBIT]),                                     // ADDR_WIDTH_A-bit input: Address for port A write operations.
250
                .addrb(radr[gport]),             // ADDR_WIDTH_B-bit input: Address for port B read operations.
251
                .clka(wclk),                 // 1-bit input: Clock signal for port A. Also clocks port B when
252
                                                 // parameter CLOCKING_MODE is "common_clock".
253
 
254
                .clkb(rclkp[gport]),                     // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
255
                                                 // "independent_clock". Unused when parameter CLOCKING_MODE is
256
                                                 // "common_clock".
257
 
258
                .dina(wdata),                // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
259
                .ena(wstrb),                            // 1-bit input: Memory enable signal for port A. Must be high on clock
260
                                                 // cycles when write operations are initiated. Pipelined internally.
261
 
262
                .enb(rstb[gport]),                // 1-bit input: Memory enable signal for port B. Must be high on clock
263
                                                 // cycles when read operations are initiated. Pipelined internally.
264
 
265
                .injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
266
                                                 // ECC enabled (Error injection capability is not available in
267
                                                 // "decode_only" mode).
268
 
269
                .injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
270
                                                 // ECC enabled (Error injection capability is not available in
271
                                                 // "decode_only" mode).
272
 
273
                .regceb(1'b1),                 // 1-bit input: Clock Enable for the last register stage on the output
274
                                                 // data path.
275
 
276
                .rstb(rst),                     // 1-bit input: Reset signal for the final port B output register stage.
277
                                                 // Synchronously resets output port doutb to the value specified by
278
                                                 // parameter READ_RESET_VALUE_B.
279
 
280
                .sleep(1'b0),                   // 1-bit input: sleep signal to enable the dynamic power saving feature.
281
                .wea(wstrb)                     // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
282
                                                 // for port A input data port dina. 1 bit wide when word-wide writes are
283
                                                 // used. In byte-wide write configurations, each bit controls the
284
                                                 // writing one byte of dina to address addra. For example, to
285
                                                 // synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
286
                                                 // is 32, wea would be 4'b0010.
287
 
288
        );
289
        end
290
end
291
endgenerate
292
 
293
genvar g;
294
generate begin : gReaddat
295
        for (g = 0; g < CACHE_ASSOC; g = g + 1) begin
296
                always_comb vbito0a[g] <= vbit[g][radrr[0][HIBIT:LOBIT]];
297
                always_comb vbito1a[g] <= vbit[g][radrr[1][HIBIT:LOBIT]];
298
                always_comb vbito2a[g] <= vbit[g][radrr[2][HIBIT:LOBIT]];
299
                always_comb vbito3a[g] <= vbit[g][radrr[3][HIBIT:LOBIT]];
300
                always_comb vbito4a[g] <= vbit[g][radrr[4][HIBIT:LOBIT]];
301
                always_comb vbito5a[g] <= vbit[g][radrr[5][HIBIT:LOBIT]];
302
                always_comb vbito6a[g] <= vbit[g][radrr[6][HIBIT:LOBIT]];
303
                always_comb vbito7a[g] <= vbit[g][radrr[7][HIBIT:LOBIT]];
304
                always_comb vbito8a[g] <= vbit[g][radrr[8][HIBIT:LOBIT]];
305
 
306 9 robfinch
                always_ff @(posedge ch0clk)     hit0a[g] = (doutb[0].lines[g].tag==radrr[0][31:LOBIT]) && (vbito0a[g]==1'b1);
307
                always_ff @(posedge ch1clk)     hit1a[g] = (doutb[1].lines[g].tag==radrr[1][31:LOBIT]) && (vbito1a[g]==1'b1);
308
                always_ff @(posedge ch2clk)     hit2a[g] = (doutb[2].lines[g].tag==radrr[2][31:LOBIT]) && (vbito2a[g]==1'b1);
309
                always_ff @(posedge ch3clk)     hit3a[g] = (doutb[3].lines[g].tag==radrr[3][31:LOBIT]) && (vbito3a[g]==1'b1);
310
                always_ff @(posedge ch4clk)     hit4a[g] = (doutb[4].lines[g].tag==radrr[4][31:LOBIT]) && (vbito4a[g]==1'b1);
311
                always_ff @(posedge ch5clk)     hit5a[g] = (doutb[5].lines[g].tag==radrr[5][31:LOBIT]) && (vbito5a[g]==1'b1);
312
                always_ff @(posedge ch6clk)     hit6a[g] = (doutb[6].lines[g].tag==radrr[6][31:LOBIT]) && (vbito6a[g]==1'b1);
313
                always_ff @(posedge ch7clk)     hit7a[g] = (doutb[7].lines[g].tag==radrr[7][31:LOBIT]) && (vbito7a[g]==1'b1);
314
                always_ff @(posedge wclk)       hit8a[g] = (doutb[8].lines[g].tag==radrr[8][31:LOBIT]) && (vbito8a[g]==1'b1);
315 5 robfinch
        end
316 11 robfinch
        always_comb ch0hit = |hit0a & stb0;
317
        always_comb ch1hit = |hit1a & stb1;
318
        always_comb ch2hit = |hit2a & stb2;
319
        always_comb ch3hit = |hit3a & stb3;
320
        always_comb ch4hit = |hit4a & stb4;
321
        always_comb ch5hit = |hit5a & stb5;
322
        always_comb ch6hit = |hit6a & stb6;
323
        always_comb ch7hit = |hit7a & stb7;
324
        always_comb ch0o.ack = (|hit0a && stb0 && (ch0i.cmd==CMD_LOAD||ch0i.cmd==CMD_LOADZ)) | (ch0wack & stb0);
325
        always_comb ch1o.ack = (|hit1a && stb1 && (ch1i.cmd==CMD_LOAD||ch1i.cmd==CMD_LOADZ)) | (ch1wack & stb1);
326
        always_comb ch2o.ack = (|hit2a && stb2 && (ch2i.cmd==CMD_LOAD||ch2i.cmd==CMD_LOADZ)) | (ch2wack & stb2);
327
        always_comb ch3o.ack = (|hit3a && stb3 && (ch3i.cmd==CMD_LOAD||ch3i.cmd==CMD_LOADZ)) | (ch3wack & stb3);
328
        always_comb ch4o.ack = (|hit4a && stb4 && (ch4i.cmd==CMD_LOAD||ch4i.cmd==CMD_LOADZ)) | (ch4wack & stb4);
329
        always_comb ch5o.ack = (|hit5a && stb5 && (ch5i.cmd==CMD_LOAD||ch5i.cmd==CMD_LOADZ)) | (ch5wack & stb5);
330
        always_comb ch6o.ack = (|hit6a && stb6 && (ch6i.cmd==CMD_LOAD||ch6i.cmd==CMD_LOADZ)) | (ch6wack & stb6);
331
        always_comb ch7o.ack = (|hit7a && stb7 && (ch7i.cmd==CMD_LOAD||ch7i.cmd==CMD_LOADZ)) | (ch7wack & stb7);
332 5 robfinch
        always_comb ch0o.err = 1'b0;
333
        always_comb ch1o.err = 1'b0;
334
        always_comb ch2o.err = 1'b0;
335
        always_comb ch3o.err = 1'b0;
336
        always_comb ch4o.err = 1'b0;
337
        always_comb ch5o.err = 1'b0;
338
        always_comb ch6o.err = 1'b0;
339
        always_comb ch7o.err = 1'b0;
340
        always_comb ch0o.rty = 1'b0;
341
        always_comb ch1o.rty = 1'b0;
342
        always_comb ch2o.rty = 1'b0;
343
        always_comb ch3o.rty = 1'b0;
344
        always_comb ch4o.rty = 1'b0;
345
        always_comb ch5o.rty = 1'b0;
346
        always_comb ch6o.rty = 1'b0;
347
        always_comb ch7o.rty = 1'b0;
348
        always_comb ch0o.cid = ch0i.cid;
349
        always_comb ch1o.cid = ch1i.cid;
350
        always_comb ch2o.cid = ch2i.cid;
351
        always_comb ch3o.cid = ch3i.cid;
352
        always_comb ch4o.cid = ch4i.cid;
353
        always_comb ch5o.cid = ch5i.cid;
354
        always_comb ch6o.cid = ch6i.cid;
355
        always_comb ch7o.cid = ch7i.cid;
356 11 robfinch
        always_comb ch0o.tid = ch0i.tid;
357
        always_comb ch1o.tid = ch1i.tid;
358
        always_comb ch2o.tid = ch2i.tid;
359
        always_comb ch3o.tid = ch3i.tid;
360
        always_comb ch4o.tid = ch4i.tid;
361
        always_comb ch5o.tid = ch5i.tid;
362
        always_comb ch6o.tid = ch6i.tid;
363
        always_comb ch7o.tid = ch7i.tid;
364 5 robfinch
end
365
endgenerate
366
 
367
always_comb wway = hit8a[0] ? 2'd0 : hit8a[1] ? 2'd1 : hit8a[2] ? 2'd2 : hit8a[3] ? 2'd3 : 2'd0;
368
 
369
always_comb
370
begin
371
        ch0o.dat <= 'd0;
372
        ch1o.dat <= 'd0;
373
        ch2o.dat <= 'd0;
374
        ch3o.dat <= 'd0;
375
        ch4o.dat <= 'd0;
376
        ch5o.dat <= 'd0;
377
        ch6o.dat <= 'd0;
378
        ch7o.dat <= 'd0;
379
        wrdata <= 'd0;
380
        for (n2 = 0; n2 < CACHE_ASSOC; n2 = n2 + 1) begin
381
                if (hit0a[n2]) ch0o.dat <= doutb[0].lines[n2];
382
                if (hit1a[n2]) ch1o.dat <= doutb[1].lines[n2];
383
                if (hit2a[n2]) ch2o.dat <= doutb[2].lines[n2];
384
                if (hit3a[n2]) ch3o.dat <= doutb[3].lines[n2];
385
                if (hit4a[n2]) ch4o.dat <= doutb[4].lines[n2];
386
                if (hit5a[n2]) ch5o.dat <= doutb[5].lines[n2];
387
                if (hit6a[n2]) ch6o.dat <= doutb[6].lines[n2];
388
                if (hit7a[n2]) ch7o.dat <= doutb[7].lines[n2];
389
        end
390
//      if (|hit8a)
391
                wrdata <= doutb[8];
392
end
393
 
394
reg b0,b1,b2;
395
reg ldcycd1,ldcycd2;
396
always_ff @(posedge wclk)
397
        ldcycd1 <= ld.cyc;
398
always_ff @(posedge wclk)
399
        ldcycd2 <= ldcycd1;
400 10 robfinch
 
401 5 robfinch
always_ff @(posedge wclk)
402
if (rst) begin
403
        for (n = 0; n < 4; n = n + 1)
404
                vbit[n] <= 'b0;
405
end
406
else begin
407
        if (ldcycd2) begin
408
                vbit[0][wadr2[HIBIT:LOBIT]] <= 1'b1;
409
                vbit[1][wadr2[HIBIT:LOBIT]] <= b0;
410
                vbit[2][wadr2[HIBIT:LOBIT]] <= b1;
411
                vbit[3][wadr2[HIBIT:LOBIT]] <= b2;
412
        end
413
        if (ldcycd1) begin
414
                b0 <= vbit[0][wadr[HIBIT:LOBIT]];
415
                b1 <= vbit[1][wadr[HIBIT:LOBIT]];
416
                b2 <= vbit[2][wadr[HIBIT:LOBIT]];
417
        end
418 7 robfinch
        if (|hit8a & |wchi_sel & wchi_stb & wchi.we & ~(ld.cyc|ldcycd1|ldcycd2))
419 5 robfinch
                vbit[wway][wadr[HIBIT:LOBIT]] <= 1'b1;
420
        else if (inv)
421
                vbit[wway][wadr[HIBIT:LOBIT]] <= 1'b0;
422
end
423
 
424
// Update the cache only if there was a write hit or if loading the cache line
425
// due to a read miss. For a read miss the entire line is updated, otherwise
426
// just the part of the line relevant to the write is updated.
427
always_ff @(posedge wclk)
428
begin
429
        if (ld.cyc)
430 11 robfinch
                wadr <= ld.padr;
431 8 robfinch
        else if (wchi.stb)
432 11 robfinch
                wadr <= wchi.padr;
433 5 robfinch
end
434
always_ff @(posedge wclk)
435
        wadr2 <= wadr;
436
always_ff @(posedge wclk)
437 11 robfinch
        lddat1 <= ld.data1;
438 5 robfinch
always_ff @(posedge wclk)
439
        lddat2 <= lddat1;
440 8 robfinch
always_ff @(posedge wclk)
441
        wstrb <= ldcycd2 | (wchi_stb & |hit8a & wchi.we);
442 5 robfinch
 
443
// Merge write data into cache line.
444
// For a load due to a read miss the entire line is updated.
445
// For a write hit, just the portion of the line corresponding to the hit is
446
// updated.
447
reg [18:0] t0,t1,t2;
448
reg m0,m1,m2;
449
generate begin : gWrData
450
        // LRU update
451
        always_ff @(posedge wclk)
452
        begin
453
                if (ldcycd2) begin
454 9 robfinch
                        wdata.lines[0].tag <= wadr2[31:LOBIT];                  // set tag
455 5 robfinch
                        wdata.lines[1].tag <= t0;
456
                        wdata.lines[2].tag <= t1;
457
                        wdata.lines[3].tag <= t2;
458 9 robfinch
                        wdata.lines[0].modified <= 1'b0;                                                // clear modified flags
459 5 robfinch
                        wdata.lines[1].modified <= m0;
460
                        wdata.lines[2].modified <= m1;
461
                        wdata.lines[3].modified <= m2;
462
                end
463
                if (ldcycd1) begin
464
                        t0 <= wrdata.lines[0].tag;
465
                        t1 <= wrdata.lines[1].tag;
466
                        t2 <= wrdata.lines[2].tag;
467
                        m0 <= wrdata.lines[0].modified;
468
                        m1 <= wrdata.lines[1].modified;
469
                        m2 <= wrdata.lines[2].modified;
470
                end
471
                if (!(ld.cyc|ldcycd1|ldcycd2)) begin
472 7 robfinch
                        if (wchi_stb & hit8a[0] & wchi.we)
473 5 robfinch
                                wdata.lines[0].modified <= 1'b1;
474
                        else
475
                                wdata.lines[0].modified <= wrdata.lines[0].modified;
476 7 robfinch
                        if (wchi_stb & hit8a[1] & wchi.we)
477 5 robfinch
                                wdata.lines[1].modified <= 1'b1;
478
                        else
479 7 robfinch
                                wdata.lines[1].modified <= wrdata.lines[1].modified;
480
                        if (wchi_stb & hit8a[2] & wchi.we)
481 5 robfinch
                                wdata.lines[2].modified <= 1'b1;
482
                        else
483 7 robfinch
                                wdata.lines[2].modified <= wrdata.lines[2].modified;
484
                        if (wchi_stb & hit8a[3] & wchi.we)
485 5 robfinch
                                wdata.lines[3].modified <= 1'b1;
486
                        else
487 7 robfinch
                                wdata.lines[3].modified <= wrdata.lines[3].modified;
488 5 robfinch
                        // Tag stays the same, it was hit
489
                        wdata.lines[0].tag <= wrdata.lines[0].tag;
490
                        wdata.lines[1].tag <= wrdata.lines[1].tag;
491
                        wdata.lines[2].tag <= wrdata.lines[2].tag;
492
                        wdata.lines[3].tag <= wrdata.lines[3].tag;
493
                end
494
        end
495
        for (g = 0; g < 16; g = g + 1)
496
        always_ff @(posedge wclk)
497
                begin
498
                        if (ldcycd2) begin
499
        //                      wdata <= wrdata << $bits(mpmc10_cache_line_t);
500
                                wdata.lines[0].data[g*8+7:g*8] <= lddat2[g*8+7:g*8];            // set data
501
                                wdata.lines[1].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
502
                                wdata.lines[2].data[g*8+7:g*8] <= wrdata.lines[1].data[g*8+7:g*8];
503
                                wdata.lines[3].data[g*8+7:g*8] <= wrdata.lines[2].data[g*8+7:g*8];
504
                        end
505
                        if (!(ld.cyc|ldcycd1|ldcycd2)) begin
506 7 robfinch
                                if (wchi_stb & hit8a[0] & wchi.we)
507 5 robfinch
                                        wdata.lines[0].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[0].data[g*8+7:g*8];
508
                                else
509
                                        wdata.lines[0].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
510 7 robfinch
                                if (wchi_stb & hit8a[1] & wchi.we)
511 5 robfinch
                                        wdata.lines[1].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[1].data[g*8+7:g*8];
512
                                else
513 7 robfinch
                                        wdata.lines[1].data[g*8+7:g*8] <= wrdata.lines[1].data[g*8+7:g*8];
514
                                if (wchi_stb & hit8a[2] & wchi.we)
515 5 robfinch
                                        wdata.lines[2].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[2].data[g*8+7:g*8];
516
                                else
517 7 robfinch
                                        wdata.lines[2].data[g*8+7:g*8] <= wrdata.lines[2].data[g*8+7:g*8];
518
                                if (wchi_stb & hit8a[3] & wchi.we)
519 5 robfinch
                                        wdata.lines[3].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[3].data[g*8+7:g*8];
520
                                else
521 7 robfinch
                                        wdata.lines[3].data[g*8+7:g*8] <= wrdata.lines[3].data[g*8+7:g*8];
522 5 robfinch
                        end
523
                end
524
end
525
endgenerate
526
 
527
// Writes take two clock cycles, 1 to read the RAM and find out if it is a
528
// write hit and a second clock to write the data. The write cycle may be
529
// delayed by a cycle due to a load.
530
reg wack;
531
always_ff @(posedge wclk)
532
if (rst)
533
        wack <= 1'b0;
534
else begin
535
        wack <= 1'b0;
536 9 robfinch
        if (wchi_stb & ~ld.stb & wchi.we)
537 5 robfinch
                wack <= 1'b1;
538
end
539
assign wcho.ack = wack & wchi.stb;
540
 
541
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.