forked from TILOS-AI-Institute/MacroPlacement
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserpent_cache_pkg.sv
More file actions
364 lines (323 loc) · 16.5 KB
/
Copy pathserpent_cache_pkg.sv
File metadata and controls
364 lines (323 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
// Date: 15.08.2018
// Description: Package for OpenPiton compatible L1 cache subsystem
// this is needed to propagate the
// configuration in case Ariane is
// instantiated in OpenPiton
`ifdef PITON_ARIANE
`ifndef AXI64_CACHE_PORTS
`include "l15.tmp.h"
`include "define.tmp.h"
`endif
`endif
package serpent_cache_pkg;
// these parames need to coincide with the
// L1.5 parameterization, do not change
`ifdef PITON_ARIANE
`ifndef CONFIG_L15_ASSOCIATIVITY
`define CONFIG_L15_ASSOCIATIVITY 4
`endif
`ifndef L15_THREADID_WIDTH
`define L15_THREADID_WIDTH 1
`endif
`ifndef TLB_CSM_WIDTH
`define TLB_CSM_WIDTH 33
`endif
localparam L15_SET_ASSOC = `CONFIG_L15_ASSOCIATIVITY;
localparam L15_TID_WIDTH = `L15_THREADID_WIDTH;
localparam L15_TLB_CSM_WIDTH = `TLB_CSM_WIDTH;
`else
localparam L15_SET_ASSOC = ariane_pkg::DCACHE_SET_ASSOC;// align with dcache for compatibility with the standard Ariane setup
localparam L15_TID_WIDTH = 2;
localparam L15_TLB_CSM_WIDTH = 33;
`endif
localparam L15_WAY_WIDTH = $clog2(L15_SET_ASSOC);
localparam L1I_WAY_WIDTH = $clog2(ariane_pkg::ICACHE_SET_ASSOC);
localparam L1D_WAY_WIDTH = $clog2(ariane_pkg::DCACHE_SET_ASSOC);
// FIFO depths of L15 adapter
localparam ADAPTER_REQ_FIFO_DEPTH = 2;
localparam ADAPTER_RTRN_FIFO_DEPTH = 2;
// Calculated parameter
localparam ICACHE_OFFSET_WIDTH = $clog2(ariane_pkg::ICACHE_LINE_WIDTH/8);
localparam ICACHE_NUM_WORDS = 2**(ariane_pkg::ICACHE_INDEX_WIDTH-ICACHE_OFFSET_WIDTH);
localparam ICACHE_CL_IDX_WIDTH = $clog2(ICACHE_NUM_WORDS);// excluding byte offset
localparam DCACHE_OFFSET_WIDTH = $clog2(ariane_pkg::DCACHE_LINE_WIDTH/8);
localparam DCACHE_NUM_WORDS = 2**(ariane_pkg::DCACHE_INDEX_WIDTH-DCACHE_OFFSET_WIDTH);
localparam DCACHE_CL_IDX_WIDTH = $clog2(DCACHE_NUM_WORDS);// excluding byte offset
localparam DCACHE_NUM_BANKS = ariane_pkg::DCACHE_LINE_WIDTH/64;
// write buffer parameterization
localparam DCACHE_WBUF_DEPTH = 8;
localparam DCACHE_MAX_TX = 2**L15_TID_WIDTH;
localparam DCACHE_ID_WIDTH = $clog2(DCACHE_MAX_TX);
typedef struct packed {
logic [ariane_pkg::DCACHE_INDEX_WIDTH+ariane_pkg::DCACHE_TAG_WIDTH-1:0] wtag;
logic [63:0] data;
logic [7:0] dirty; // byte is dirty
logic [7:0] valid; // byte is valid
logic [7:0] txblock; // byte is part of transaction in-flight
logic checked; // if cache state of this word has been checked
logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] hit_oh; // valid way in the cache
} wbuffer_t;
// TX status registers are indexed with the transaction ID
// they basically store which bytes from which buffer entry are part
// of that transaction
typedef struct packed {
logic vld;
logic [7:0] be;
logic [$clog2(DCACHE_WBUF_DEPTH)-1:0] ptr;
} tx_stat_t;
// local interfaces between caches and L15 adapter
typedef enum logic [1:0] {
DCACHE_STORE_REQ,
DCACHE_LOAD_REQ,
DCACHE_ATOMIC_REQ,
DCACHE_INT_REQ
} dcache_out_t;
typedef enum logic [2:0] {
DCACHE_INV_REQ, // no ack from the core required
DCACHE_STORE_ACK,// note: this may contain an invalidation vector, too
DCACHE_LOAD_ACK,
DCACHE_ATOMIC_ACK,
DCACHE_INT_ACK
} dcache_in_t;
typedef enum logic [0:0] {
ICACHE_INV_REQ, // no ack from the core required
ICACHE_IFILL_ACK
} icache_in_t;
typedef struct packed {
logic vld; // invalidate only affected way
logic all; // invalidate all ways
logic [ariane_pkg::ICACHE_INDEX_WIDTH-1:0] idx; // physical address to invalidate
logic [L15_WAY_WIDTH-1:0] way; // way to invalidate
} cache_inval_t;
// icache interface
typedef struct packed {
logic [$clog2(ariane_pkg::ICACHE_SET_ASSOC)-1:0] way; // way to replace
logic [63:0] paddr; // physical address
logic nc; // noncacheable
logic [L15_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
} icache_req_t;
typedef struct packed {
icache_in_t rtype; // see definitions above
logic [ariane_pkg::ICACHE_LINE_WIDTH-1:0] data; // full cache line width
cache_inval_t inv; // invalidation vector
logic nc; // noncacheable
logic [L15_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
logic f4b; // fetch 4 bytes only (from I/O space)
} icache_rtrn_t;
// dcache interface
typedef struct packed {
dcache_out_t rtype; // see definitions above
logic [2:0] size; // transaction size: 000=Byte 001=2Byte; 010=4Byte; 011=8Byte; 111=Cache line (16/32Byte)
logic [L1D_WAY_WIDTH-1:0] way; // way to replace
logic [63:0] paddr; // physical address
logic [63:0] data; // word width of processor (no block stores at the moment)
logic nc; // noncacheable
logic [L15_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
ariane_pkg::amo_t amo_op; // amo opcode
} dcache_req_t;
typedef struct packed {
dcache_in_t rtype; // see definitions above
logic [ariane_pkg::DCACHE_LINE_WIDTH-1:0] data; // full cache line width
cache_inval_t inv; // invalidation vector
logic nc; // noncacheable
logic [L15_TID_WIDTH-1:0] tid; // threadi id (used as transaction id in Ariane)
} dcache_rtrn_t;
// taken from iop.h in openpiton
// to l1.5 (only marked subset is used)
typedef enum logic [4:0] {
L15_LOAD_RQ = 5'b00000, // load request
L15_IMISS_RQ = 5'b10000, // instruction fill request
L15_STORE_RQ = 5'b00001, // store request
L15_ATOMIC_RQ = 5'b00110, // atomic op
//L15_CAS1_RQ = 5'b00010, // compare and swap1 packet (OpenSparc atomics)
//L15_CAS2_RQ = 5'b00011, // compare and swap2 packet (OpenSparc atomics)
//L15_SWAP_RQ = 5'b00110, // swap packet (OpenSparc atomics)
L15_STRLOAD_RQ = 5'b00100, // unused
L15_STRST_RQ = 5'b00101, // unused
L15_STQ_RQ = 5'b00111, // unused
L15_INT_RQ = 5'b01001, // interrupt request
L15_FWD_RQ = 5'b01101, // unused
L15_FWD_RPY = 5'b01110, // unused
L15_RSVD_RQ = 5'b11111 // unused
} l15_reqtypes_t;
// from l1.5 (only marked subset is used)
typedef enum logic [3:0] {
L15_LOAD_RET = 4'b0000, // load packet
// L15_INV_RET = 4'b0011, // invalidate packet, not unique...
L15_ST_ACK = 4'b0100, // store ack packet
//L15_AT_ACK = 4'b0011, // unused, not unique...
L15_INT_RET = 4'b0111, // interrupt packet
L15_TEST_RET = 4'b0101, // unused
L15_FP_RET = 4'b1000, // unused
L15_IFILL_RET = 4'b0001, // instruction fill packet
L15_EVICT_REQ = 4'b0011, // eviction request
L15_ERR_RET = 4'b1100, // unused
L15_STRLOAD_RET = 4'b0010, // unused
L15_STRST_ACK = 4'b0110, // unused
L15_FWD_RQ_RET = 4'b1010, // unused
L15_FWD_RPY_RET = 4'b1011, // unused
L15_RSVD_RET = 4'b1111, // unused
L15_CPX_RESTYPE_ATOMIC_RES = 4'b1110 // custom type for atomic responses
} l15_rtrntypes_t;
typedef struct packed {
logic l15_val; // valid signal, asserted with request
logic l15_req_ack; // ack for response
l15_reqtypes_t l15_rqtype; // see below for encoding
logic l15_nc; // non-cacheable bit
logic [2:0] l15_size; // transaction size: 000=Byte 001=2Byte; 010=4Byte; 011=8Byte; 111=Cache line (16/32Byte)
logic [L15_TID_WIDTH-1:0] l15_threadid; // currently 0 or 1
logic l15_prefetch; // unused in openpiton
logic l15_invalidate_cacheline; // unused by Ariane as L1 has no ECC at the moment
logic l15_blockstore; // unused in openpiton
logic l15_blockinitstore; // unused in openpiton
logic [L15_WAY_WIDTH-1:0] l15_l1rplway; // way to replace
logic [39:0] l15_address; // physical address
logic [63:0] l15_data; // word to write
logic [63:0] l15_data_next_entry; // unused in Ariane (only used for CAS atomic requests)
logic [L15_TLB_CSM_WIDTH-1:0] l15_csm_data; // unused in Ariane
logic [3:0] l15_amo_op; // atomic operation type
} l15_req_t;
typedef struct packed {
logic l15_ack; // ack for request struct
logic l15_header_ack; // ack for request struct
logic l15_val; // valid signal for return struct
l15_rtrntypes_t l15_returntype; // see below for encoding
logic l15_l2miss; // unused in Ariane
logic [1:0] l15_error; // unused in openpiton
logic l15_noncacheable; // non-cacheable bit
logic l15_atomic; // asserted in load return and store ack packets of atomic tx
logic [L15_TID_WIDTH-1:0] l15_threadid; // used as transaction ID
logic l15_prefetch; // unused in openpiton
logic l15_f4b; // 4byte instruction fill from I/O space (nc).
logic [63:0] l15_data_0; // used for both caches
logic [63:0] l15_data_1; // used for both caches
logic [63:0] l15_data_2; // currently only used for I$
logic [63:0] l15_data_3; // currently only used for I$
logic l15_inval_icache_all_way; // invalidate all ways
logic l15_inval_dcache_all_way; // unused in openpiton
logic [15:4] l15_inval_address_15_4; // invalidate selected cacheline
logic l15_cross_invalidate; // unused in openpiton
logic [L15_WAY_WIDTH-1:0] l15_cross_invalidate_way; // unused in openpiton
logic l15_inval_dcache_inval; // invalidate selected cacheline and way
logic l15_inval_icache_inval; // unused in openpiton
logic [L15_WAY_WIDTH-1:0] l15_inval_way; // way to invalidate
logic l15_blockinitstore; // unused in openpiton
} l15_rtrn_t;
// swap endianess in a 64bit word
function automatic logic[63:0] swendian64(input logic[63:0] in);
automatic logic[63:0] out;
for(int k=0; k<64;k+=8)begin
out[k +: 8] = in[63-k -: 8];
end
return out;
endfunction
function automatic logic [ariane_pkg::ICACHE_SET_ASSOC-1:0] icache_way_bin2oh (
input logic [$clog2(ariane_pkg::ICACHE_SET_ASSOC)-1:0] in
);
logic [ariane_pkg::ICACHE_SET_ASSOC-1:0] out;
out = '0;
out[in] = 1'b1;
return out;
endfunction
function automatic logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] dcache_way_bin2oh (
input logic [$clog2(ariane_pkg::DCACHE_SET_ASSOC)-1:0] in
);
logic [ariane_pkg::DCACHE_SET_ASSOC-1:0] out;
out = '0;
out[in] = 1'b1;
return out;
endfunction
function automatic logic [DCACHE_NUM_BANKS-1:0] dcache_cl_bin2oh (
input logic [$clog2(DCACHE_NUM_BANKS)-1:0] in
);
logic [DCACHE_NUM_BANKS-1:0] out;
out = '0;
out[in] = 1'b1;
return out;
endfunction
function automatic logic [5:0] popcnt64 (
input logic [63:0] in
);
logic [5:0] cnt= 0;
foreach (in[k]) begin
cnt += in[k];
end
return cnt;
endfunction : popcnt64
function automatic logic [7:0] toByteEnable8(
input logic [2:0] offset,
input logic [1:0] size
);
logic [7:0] be;
be = '0;
unique case(size)
2'b00: be[offset] = '1; // byte
2'b01: be[offset +:2 ] = '1; // hword
2'b10: be[offset +:4 ] = '1; // word
default: be = '1; // dword
endcase // size
return be;
endfunction : toByteEnable8
// openpiton requires the data to be replicated in case of smaller sizes than dwords
function automatic logic [63:0] repData64(
input logic [63:0] data,
input logic [2:0] offset,
input logic [1:0] size
);
logic [63:0] out;
unique case(size)
2'b00: for(int k=0; k<8; k++) out[k*8 +: 8] = data[offset*8 +: 8]; // byte
2'b01: for(int k=0; k<4; k++) out[k*16 +: 16] = data[offset*8 +: 16]; // hword
2'b10: for(int k=0; k<2; k++) out[k*32 +: 32] = data[offset*8 +: 32]; // word
default: out = data; // dword
endcase // size
return out;
endfunction : repData64
// note: this is openpiton specific. cannot transmit unaligned words.
// hence we default to individual bytes in that case, and they have to be transmitted
// one after the other
function automatic logic [1:0] toSize64(
input logic [7:0] be
);
logic [1:0] size;
unique case(be)
8'b1111_1111: size = 2'b11; // dword
8'b0000_1111, 8'b1111_0000: size = 2'b10; // word
8'b1100_0000, 8'b0011_0000, 8'b0000_1100, 8'b0000_0011: size = 2'b01; // hword
default: size = 2'b00; // individual bytes
endcase // be
return size;
endfunction : toSize64
// align the physical address to the specified size:
// 000: bytes
// 001: hword
// 010: word
// 011: dword
// 111: DCACHE line
function automatic logic [63:0] paddrSizeAlign(
input logic [63:0] paddr,
input logic [2:0] size
);
logic [63:0] out;
out = paddr;
unique case (size)
3'b001: out[0:0] = '0;
3'b010: out[1:0] = '0;
3'b011: out[2:0] = '0;
3'b111: out[DCACHE_OFFSET_WIDTH-1:0] = '0;
default: ;
endcase
return out;
endfunction : paddrSizeAlign
endpackage : serpent_cache_pkg