Project

General

Profile

MMU description » History » Version 132

Alexander Kamkin, 04/25/2015 01:14 PM

1 24 Alexander Kamkin
h1. MMU Description
2 1 Taya Sergeeva
3 128 Alexander Kamkin
_~By Alexander Kamkin, Taya Sergeeva, and Andrei Tatarnikov~_
4 62 Alexander Kamkin
5 63 Alexander Kamkin
{{toc}}
6
7 35 Alexander Kamkin
A _memory management unit_ (_MMU_) is known to be one of the most complex and error-prone components of a modern microprocessor. MicroTESK has a special subsystem, called _MMU subsystem_, intended for (1) specifying memory devices and (2) deriving testing knowledge from such specifications. The subsystem provides unified facilities for describing memory buffers (like _L1_ and _L2 caches_, _translation look-aside buffers_ (_TLBs_), etc.) as well as a means for connecting several buffers into a memory hierarchy.
8 1 Taya Sergeeva
9 72 Alexander Kamkin
h2. Grammar
10 66 Alexander Kamkin
11
<pre>
12 102 Andrei Tatarnikov
startRule
13
    : declaration* EOF!
14 66 Alexander Kamkin
    ;
15 1 Taya Sergeeva
16 102 Andrei Tatarnikov
declaration
17 66 Alexander Kamkin
    : address
18 102 Andrei Tatarnikov
    | segment
19 66 Alexander Kamkin
    | buffer
20 102 Andrei Tatarnikov
    | mmu
21 66 Alexander Kamkin
    ;
22
</pre>
23
24 103 Andrei Tatarnikov
The expression syntax is derived from nML/Sim-nML (see [[Sim-nML Language Reference]]).
25 89 Alexander Kamkin
26 91 Alexander Kamkin
h2. Address Description (address)
27 56 Taya Sergeeva
28 1 Taya Sergeeva
A buffer is accessed by an _address_, which is typically a _bit vector_ of a fixed length (width). Different buffers are allowed to have a common address space (e.g., L1 and L2 are usually both addressed by physical addresses). However, in general case, each buffer has its own domain.
29
30 110 Andrei Tatarnikov
An address space is described using a keyword @address@. The description includes the address type _identifier_ and the address _width_. The latter is specified in brackets. Its value should be non-negative (zero-length addresses are permitted).
31 1 Taya Sergeeva
32 75 Alexander Kamkin
h3. Grammar
33 69 Alexander Kamkin
34
<pre>
35
address
36 104 Andrei Tatarnikov
    : ''address'' addressTypeID ''('' expr '')''
37 69 Alexander Kamkin
    ;
38
</pre>
39
40 111 Andrei Tatarnikov
h3. Examples
41 106 Andrei Tatarnikov
42
<pre>// A 64-bit virtual address (VA).
43
address VA(64)</pre>
44
45
<pre>// A 36-bit physical address (PA).
46
address PA(36)</pre>
47
48 112 Andrei Tatarnikov
h2. Address Space Segment Description (segment)
49 1 Taya Sergeeva
50 112 Andrei Tatarnikov
An address space segment is specified using the @segment@ keyword. A segment is associated with a specific address type. It is possible to specify any number (&ge; 0) of segments (with different names) for one address type. Each segment is characterized by its _identifier_ and _address range_. Different segments should have different names, but address ranges are allowed to overlap, and moreover, to be the same.
51 1 Taya Sergeeva
52 112 Andrei Tatarnikov
h3. Grammar
53 69 Alexander Kamkin
54
<pre>
55 112 Andrei Tatarnikov
segment
56
    : ''segment'' segmentID ''('' argumentID '':'' addressTypeID '')''
57
        ''range'' ''='' ''('' expr '','' expr '')''
58 99 Alexander Kamkin
    ;
59 97 Alexander Kamkin
</pre>
60
61 112 Andrei Tatarnikov
h3. Examples
62 97 Alexander Kamkin
63 1 Taya Sergeeva
<pre>
64 112 Andrei Tatarnikov
segment USEG (va: VA)
65
  range = (0x0000000000000000, 0x000000007fffffff)
66 97 Alexander Kamkin
</pre>
67
68 91 Alexander Kamkin
h2. Buffer Description (buffer)
69 76 Alexander Kamkin
70 115 Andrei Tatarnikov
A buffer is described using a keyword @buffer@. The description specifies a set of parameters, including @ways@, @sets@, @entry@, @index@, @match@ and @policy@. All of the parameters except @index@ (if @sets = 1@) and @policy@ are obligatory.
71 75 Alexander Kamkin
72
h3. Grammar
73 1 Taya Sergeeva
74 75 Alexander Kamkin
<pre>
75 83 Alexander Kamkin
buffer
76 115 Andrei Tatarnikov
    : ''buffer'' bufferTypeID ''('' addressArgID '':'' addressTypeID '')''
77 90 Alexander Kamkin
        (bufferParameter)*
78 75 Alexander Kamkin
    ;
79
80
bufferParameter
81
    : ways
82
    | sets
83 115 Andrei Tatarnikov
    | entry
84 75 Alexander Kamkin
    | index
85
    | match
86
    | policy
87
    ;
88 1 Taya Sergeeva
</pre>
89
90 78 Alexander Kamkin
h3. Buffer Associativity (ways)
91
92 84 Alexander Kamkin
The @ways@ parameter specifies the buffer _associativity_ (the number of lines in a set). The parameter is obligatory; its value should be positive.
93 78 Alexander Kamkin
94 1 Taya Sergeeva
h4. Grammar
95 80 Alexander Kamkin
96
<pre>
97
ways
98
    : ''ways'' ''='' expr
99 1 Taya Sergeeva
    ;
100
</pre>
101
102 80 Alexander Kamkin
h3. Buffer Length (sets)
103 83 Alexander Kamkin
104 84 Alexander Kamkin
The @sets@ parameter specifies the buffer _length_ (the number of sets a cache). The parameter is obligatory; its value should be positive.
105 78 Alexander Kamkin
106 1 Taya Sergeeva
h4. Grammar
107 80 Alexander Kamkin
108
<pre>
109 1 Taya Sergeeva
sets
110 80 Alexander Kamkin
    : ''sets'' ''='' expr
111
    ;
112 1 Taya Sergeeva
</pre>
113
114 116 Andrei Tatarnikov
h3. Buffer Line Format (entry)
115 96 Alexander Kamkin
116 120 Andrei Tatarnikov
The @entry@ parameter specifies the buffer _line format_ (a number of named fields). A field has three attributes: a name, a width and, optionally, an initial value.
117 82 Alexander Kamkin
118
h4. Grammar
119 1 Taya Sergeeva
120 82 Alexander Kamkin
<pre>
121 83 Alexander Kamkin
format
122 119 Andrei Tatarnikov
    : ''entry'' ''='' ''('' field ('','' field)* '')''
123 82 Alexander Kamkin
    ;
124 1 Taya Sergeeva
125
field
126
    : fieldID '':'' expr (''='' expr)?
127
    ;
128
</pre>
129
130
h3. Buffer Index Function (index)
131 83 Alexander Kamkin
132 84 Alexander Kamkin
The @index@ parameter specifies the _address-to-index function_, which maps an address into the set index. The function may be omitted if the number of sets is @1@.
133 1 Taya Sergeeva
134
h4. Grammar
135
136 83 Alexander Kamkin
<pre>
137 1 Taya Sergeeva
index
138 90 Alexander Kamkin
    : ''index'' ''='' expr
139 83 Alexander Kamkin
    ;
140
</pre>
141 1 Taya Sergeeva
142
h3. Buffer Match Predicate (match)
143 83 Alexander Kamkin
144 84 Alexander Kamkin
The @match@ parameter specifies the _address-line match predicate_, which checks if an address matches a line. The parameter is obligatory.
145 83 Alexander Kamkin
146
h4. Grammar
147 1 Taya Sergeeva
148 83 Alexander Kamkin
<pre>
149
index
150 90 Alexander Kamkin
    : ''match'' ''='' expr
151 1 Taya Sergeeva
    ;
152
</pre>
153 83 Alexander Kamkin
154 1 Taya Sergeeva
h3. Buffer Data Replacement Policy (policy)
155
156 57 Taya Sergeeva
The @policy@ parameters specifies the _data replacement_ (_eviction_) _policy_. The parameter is optional. The list of supported policies includes: @RANDOM@, @FIFO@, @PLRU@ and @LRU@.
157 84 Alexander Kamkin
158 1 Taya Sergeeva
h4. Grammar
159
160
<pre>
161
policy
162
    : ''policy'' ''='' policyID
163 54 Taya Sergeeva
    ;
164
</pre>
165
166 1 Taya Sergeeva
h3. Examples
167
168 84 Alexander Kamkin
<pre>
169 90 Alexander Kamkin
// A 4-way set associative cache (L1) addressed by physical addresses (PA).
170 118 Andrei Tatarnikov
buffer L1(addr: PA)
171 84 Alexander Kamkin
  // The cache associativity.
172 1 Taya Sergeeva
  ways = 4
173 84 Alexander Kamkin
  // The number of sets.
174 90 Alexander Kamkin
  sets = 128
175 1 Taya Sergeeva
  // The line format.
176 118 Andrei Tatarnikov
  entry = (
177 85 Alexander Kamkin
    V    : 1 = 0, // The validity flag (by default, the line is invalid).
178
    TAG  : 24,    // The tag (the <35..12> address bits).
179 1 Taya Sergeeva
    DATA : 256    // The data (4 double words).
180 90 Alexander Kamkin
  )
181
  // The address-to-index function (example: using address fields).
182
  index = addr.INDEX
183
  // The address-line predicate (example: using address bits).
184 121 Andrei Tatarnikov
  match = addr<35..12> == TAG
185 1 Taya Sergeeva
  // The data replacement policy (example: using predefined policy LRU - Least Recently Used).
186
  policy = LRU
187 91 Alexander Kamkin
</pre>
188
189 122 Andrei Tatarnikov
h2. MMU Description (mmu)
190 91 Alexander Kamkin
191 125 Andrei Tatarnikov
Memory management unit logic is described using the @mmu@ keyword. The description includes two obligatory parameters @read@ and @write@ that describe the semantics of memory read and memory write actions respectively.
192 92 Alexander Kamkin
193 91 Alexander Kamkin
h3. Grammar
194
195
<pre>
196 126 Andrei Tatarnikov
mmu
197
    : ''mmu'' memoryTypeID ''('' addressArgID '':'' addressTypeID '')'' = dataArgID
198 127 Andrei Tatarnikov
        (mmuVariable)*
199
        (mmuParameter)*
200 91 Alexander Kamkin
    ;
201 1 Taya Sergeeva
202 127 Andrei Tatarnikov
mmuVariable
203
    : ''var'' variableID '':'' variableTypeID (''.'' ''entry'')? '';''
204
    ;
205
206 126 Andrei Tatarnikov
mmuParameter
207 127 Andrei Tatarnikov
    : read
208
    | write
209 1 Taya Sergeeva
    ;
210 91 Alexander Kamkin
</pre>
211 92 Alexander Kamkin
212 1 Taya Sergeeva
h3. Memory Read Action (read)
213 92 Alexander Kamkin
214
The @read@ parameter specifies the _read action_, which is a sequence of statements describing how the read operation is to be performed (by means of data transfers between buffers). The parameter is obligatory.
215 91 Alexander Kamkin
216
h4. Grammar
217
218
<pre>
219
read
220 1 Taya Sergeeva
    : ''read'' ''='' ''{'' sequence ''}''
221
    ;
222
</pre>
223 92 Alexander Kamkin
224
h3. Memory Write Action (write)
225
226 91 Alexander Kamkin
The @write@ parameter specifies the _read action_, which is a sequence of statements describing how the write operation is to be performed (by means of data transfers between buffers). The parameter is obligatory.
227
228
h4. Grammar
229
230
<pre>
231
write
232
    : ''write'' ''='' ''{'' sequence ''}''
233
    ;
234
</pre>
235
236
h3. Examples
237
238 93 Alexander Kamkin
<pre>
239 123 Andrei Tatarnikov
// A memory unit addressed by virtual addresses (VA).
240 93 Alexander Kamkin
mmu Memory(addr: VA) = data
241 1 Taya Sergeeva
  // The read action.
242 93 Alexander Kamkin
  read = {
243
    // Some statements.
244 1 Taya Sergeeva
    ...
245 93 Alexander Kamkin
  }
246 1 Taya Sergeeva
  // The write action.
247 93 Alexander Kamkin
  write = {
248
    // Some statements.
249 91 Alexander Kamkin
    ...
250 1 Taya Sergeeva
  }
251 130 Alexander Kamkin
</pre>
252 129 Alexander Kamkin
253
h2. Simplified Specification of MIPS''s MMU
254
255
<pre>
256
//==================================================================================================
257
// Virtual Address (VA)
258
//==================================================================================================
259
260
address VA(64)
261
262
//--------------------------------------------------------------------------------------------------
263
// User Mode Segments
264
//--------------------------------------------------------------------------------------------------
265
266
segment USEG (va: VA)
267
  range = (0x0000000000000000, 0x000000007fffffff)
268
269
segment XUSEG(va: VA)
270
  range = (0x0000000080000000, 0x000000ffffffffff)
271
272
//--------------------------------------------------------------------------------------------------
273
// Supervisor Mode Segments
274
//--------------------------------------------------------------------------------------------------
275
276
segment SUSEG(va: VA)
277
  range = (0x0000000000000000, 0x000000007fffffff)
278
279
segment XSUSEG(va: VA)
280
  range = (0x0000000080000000, 0x000000ffffffffff)
281
282
segment XSSEG(va: VA)
283
  range = (0x4000000000000000, 0x400000ffffffffff)
284
  
285
segment CSSEG(va: VA)
286
  range = (0xffffffffc0000000, 0xffffffffdfffffff)
287
288
//--------------------------------------------------------------------------------------------------
289
// Kernel Mode Segments
290
//--------------------------------------------------------------------------------------------------
291
292
segment KUSEG (va: VA)
293
  range = (0x0000000000000000, 0x000000007fffffff)
294
295
segment XKUSEG (va: VA)
296
  range = (0x0000000080000000, 0x000000ffffffffff)
297
298
segment XKSSEG (va: VA)
299
  range = (0x4000000000000000, 0x400000ffffffffff)
300
301
segment XKSEG (va: VA)
302
  range = (0xc000000000000000, 0xc00000ff7fffffff)
303
304
segment CKSSEG (va: VA)
305
  range = (0xffffffffc0000000, 0xffffffffdfffffff)
306
307
segment CKSEG3(va: VA)
308
  range = (0xffffffffe0000000, 0xffffffffffffffff)
309
310
//==================================================================================================
311
// Physical Address (PA)
312
//==================================================================================================
313
314
address PA(36)
315
316
//==================================================================================================
317
// Translation Lookaside Buffer (TLB)
318
//==================================================================================================
319
320
buffer DTLB (va: VA)
321
  ways   = 4
322
  sets   = 1
323
  entry  = (ASID: 8, VPN2: 27, R: 2,               // EntryHi
324
            G0: 1, V0: 1, D0: 1, C0: 3, PFN0: 24,  // EntryLo0
325
            G1: 1, V1: 1, D1: 1, C1: 3, PFN1: 24)  // EntryLo1
326
  index  = 0
327 131 Alexander Kamkin
  match  = VPN2 == va<39..13> // ASID, G and non-4KB pages are unsupported
328 129 Alexander Kamkin
  policy = PLRU
329
330
buffer JTLB (va: VA)
331
  ways   = 64
332
  sets   = 1
333
  entry  = (ASID: 8, VPN2: 27, R: 2,               // EntryHi
334
            G0: 1, V0: 1, D0: 1, C0: 3, PFN0: 24,  // EntryLo0
335
            G1: 1, V1: 1, D1: 1, C1: 3, PFN1: 24)  // EntryLo1
336
  index  = 0
337 131 Alexander Kamkin
  match  = VPN2 == va<39..13> // ASID, G and non-4KB pages are unsupported
338 129 Alexander Kamkin
  policy = NONE
339
340
//==================================================================================================
341
// Cache Memory (L1 and L2)
342
//==================================================================================================
343
344
buffer L1 (pa: PA)
345
  ways   = 4
346
  sets   = 128
347
  entry  = (V: 1 = 0, TAG: 24, DATA: 256)
348
  index  = pa<11..5>
349
  match  = V == 1 && TAG == pa<35..12>
350
  policy = PLRU
351
352
buffer L2 (pa: PA)
353
  ways   = 4
354
  sets   = 4096
355
  entry  = (V: 1 = 0, TAG: 19, DATA: 256)
356
  index  = pa<16..5>
357
  match  = V == 1 && TAG == pa<35..17>
358
  policy = PLRU
359
360
//==================================================================================================
361
// MMU Logic (Interaction between TLB, L1 and L2)
362
//==================================================================================================
363
364
mmu pmem(va: VA) = (data: 64) 
365
  var tlbEntry: JTLB.entry;
366
  var l1Entry: L1.entry;
367
  var l2Entry: L2.entry;
368
369
  var evenOddBit: 5;
370
371
  var g: 1;
372
  var v: 1;
373
  var d: 1;
374
  var c: 3;
375
  var pfn: 24;
376
377
  var pa: PA;
378
379
  var cachePA: PA;
380
  var cacheData: 256;
381
382
  read = {
383
    // The address is unaligned.
384
    if va<0..2> != 0 then
385
      exception("AddressError");
386
    endif; // If the address is unaligned.
387
388
    // The default cache policy.
389
    c = 3;
390
391
    // The address is from the USEG segment (only USEG and KSEG segments are supported).
392
    if USEG(va).hit then
393
      // The address hits the DTLB.
394
      if DTLB(va).hit then
395
        tlbEntry = DTLB(va);
396
      // The address hits the JTLB.
397
      elif JTLB(va).hit then
398
        tlbEntry = JTLB(va);
399
      // The address does not hit the TLB.
400
      else
401 132 Alexander Kamkin
        exception("TLBRefill");
402 129 Alexander Kamkin
      endif; // If the address hits the DTLB.
403
404
      // Only 4KB pages are supported.
405
      evenOddBit = 12;
406
407
      // The VPN is even.
408
      if va<evenOddBit> == 0 then
409
        g   = tlbEntry.G0;
410
        v   = tlbEntry.V0;
411
        d   = tlbEntry.D0;
412
        c   = tlbEntry.C0;
413
        pfn = tlbEntry.PFN0;
414
      // The VPN is odd.
415
      else
416
        g   = tlbEntry.G1;
417
        v   = tlbEntry.V1;
418
        d   = tlbEntry.D1;
419
        c   = tlbEntry.C1;
420
        pfn = tlbEntry.PFN1;
421
      endif; // If the VPN is even.
422
423
      // The EntryLo is valid.
424
      if v == 1 then
425
        pa = pfn<24..(evenOddBit - 12)>::va<(evenOddBit - 1)..0>;
426
      // The EntryLo is invalid.
427
      else
428
        exception("TLBInvalid");
429
      endif; // If the EntryLo is valid.
430
    // The address is from the KSEG0 or KSEG1 segment.
431
    else
432
      pa = va<28..0>;
433
    endif; // If the address is from the USEG segment.
434
435
    // The address is cacheable.
436
    if c<1..0> != 2 then
437
      cachePA = pa;
438
      cachePA<4..0> = 0;
439
440
      // The address hits the L1.
441
      if L1(pa).hit then
442
        l1Entry = L1(pa);
443
        cacheData = l1Entry.DATA;
444
        data = cacheData<(8 * pa<4..0> + 63)..(8 * pa<4..0>)>;
445
      // The address does not hit the L1.
446
      else
447
        // The L2 cache is used.
448
        if c<1..0> == 3 then
449
          // The address hits the L2.
450
          if L2(pa).hit then
451
            l2Entry = L2(pa);
452
            cacheData = l2Entry.DATA;
453
            data = cacheData<(8 * pa<4..0> + 63)..(8 * pa<4..0>)>;
454
455
            // Fill the L1.
456
            l1Entry.V = 1;
457
            l1Entry.TAG = pa<35..12>;
458
            l1Entry.DATA = cacheData;
459
            L1(pa) = l1Entry;
460
          // The address does not hit the L2.
461
          else
462
            cacheData = pmem[cachePA + 24]::pmem[cachePA + 16]::pmem[cachePA + 8]::pmem[cachePA];
463
            data = cacheData<(8 * pa<4..0> + 63)..(8 * pa<4..0>)>;
464
465
            // Fill L2.
466
            l2Entry.V = 1;
467
            l2Entry.TAG = pa<35..17>;
468
            l2Entry.DATA = cacheData;
469
            L2(pa) = l2Entry;
470
471
            // Fill L1.
472
            l1Entry.V = 1;
473
            l1Entry.TAG = pa<35..12>;
474
            l1Entry.DATA = cacheData;
475
            L1(pa) = l1Entry;
476
          endif; // If the address hits the L2.
477
        // The L2 cache is bypassed.
478
        else
479
          cacheData = pmem[cachePA + 24]::pmem[cachePA + 16]::pmem[cachePA + 8]::pmem[cachePA];
480
          data = cacheData<(8 * pa<4..0> + 63)..(8 * pa<4..0>)>;
481
482
          l1Entry.V = 1;
483
          l1Entry.TAG = pa<35..12>;
484
          l1Entry.DATA = cacheData;
485
          L1(pa) = l1Entry;
486
        endif; // If the L2 cache is used.
487
      endif; // If the address hits the L1.
488
    // The address is uncacheable.
489
    else
490
      data = pmem[pa];
491
    endif; // If the address is cacheable.
492
  }
493
494
  write = {
495
    // The address is unaligned.
496
    if va<0..2> != 0 then
497
      exception("AddressError");
498
    endif; // If the address is unaligned.
499
500
    // The default cache policy.
501
    c = 3;
502
503
    // The address is from the USEG segment (only USEG and KSEG segments are supported).
504
    if USEG(va).hit then
505
      // The address hits the DTLB.
506
      if DTLB(va).hit then
507
        tlbEntry = DTLB(va);
508
      // The address hits the JTLB.
509
      elif JTLB(va).hit then
510
        tlbEntry = JTLB(va);
511
      // The address does not hit the TLB.
512
      else
513 132 Alexander Kamkin
        exception("TLBRefill");
514 129 Alexander Kamkin
      endif; // If the address hits the DTLB.
515
516
      // Only 4KB pages are supported.
517
      evenOddBit = 12;
518
519
      // The VPN is even.
520
      if va<evenOddBit> == 0 then
521
        g   = tlbEntry.G0;
522
        v   = tlbEntry.V0;
523
        d   = tlbEntry.D0;
524
        c   = tlbEntry.C0;
525
        pfn = tlbEntry.PFN0;
526
      // The VPN is odd.
527
      else
528
        g   = tlbEntry.G1;
529
        v   = tlbEntry.V1;
530
        d   = tlbEntry.D1;
531
        c   = tlbEntry.C1;
532
        pfn = tlbEntry.PFN1;
533
      endif; // If the VPN is even.
534
535
      // The EntryLo is valid.
536
      if v == 1 then
537
        // The EntryLo is clean.
538
        if d == 1 then
539
          pa = pfn<24..(evenOddBit - 12)>::va<(evenOddBit - 1)..0>;
540
        // The EntryLo is dirty.
541
        else
542
          exception("TLBModified");
543
        endif; // If the EntryLo is clean.
544
      // The EntryLo is invalid.
545
      else
546
        exception("TLBInvalid");
547
      endif; // If the EntryLo is valid.
548
    // The address is from the KSEG0 or KSEG1 segment.
549
    else
550
      pa = va<28..0>;
551
    endif; // If the address is from the USEG segment.
552
553
    // The address is cacheable.
554
    if c<1..0> != 2 then
555
      cachePA = pa;
556
      cachePA<4..0> = 0;
557
558
      // The address hits the L1.
559
      if L1(pa).hit then
560
        // Update the L1.
561
        l1Entry = L1(pa);
562
        l1Entry.DATA<(8 * pa<4..0> + 63)..(8 * pa<4..0>)> = data;
563
        L1(pa) = l1Entry;
564
565
        // Only the write-through policy is supported.
566
        pmem[pa] = data;
567
      // The address does not hit the L1.
568
      else
569
        // The L2 cache is used.
570
        if c<1..0> == 3 then
571
          // The address hits the L2.
572
          if L2(pa).hit then
573
            // Update the L2.
574
            l2Entry = L2(pa);
575
            l2Entry.DATA<(8 * pa<4..0> + 63)..(8 * pa<4..0>)> = data;
576
            L2(pa) = l2Entry;
577
578
            // Fill the L1.
579
            l1Entry.V = 1;
580
            l1Entry.TAG = pa<35..12>;
581
            l1Entry.DATA = l2Entry.DATA;
582
            L1(pa) = l1Entry;
583
584
            // Only the write-through policy is supported.
585
            pmem[pa] = data;
586
          // The address does not hit the L2.
587
          else
588
            pmem[pa] = data;
589
            cacheData = pmem[cachePA + 24]::pmem[cachePA + 16]::pmem[cachePA + 8]::pmem[cachePA];
590
591
            // Fill the L2.
592
            l2Entry.V = 1;
593
            l2Entry.TAG = pa<35..17>;
594
            l2Entry.DATA = cacheData;
595
            L2(pa) = l2Entry;
596
597
            // Fill the L1.
598
            l1Entry.V = 1;
599
            l1Entry.TAG = pa<35..12>;
600
            l1Entry.DATA = cacheData;
601
            L1(pa) = l1Entry;
602
          endif; // If the address hits the L2.
603
        // The L2 cache is bypassed.
604
        else
605
          pmem[pa] = data;
606
          cacheData = pmem[cachePA + 24]::pmem[cachePA + 16]::pmem[cachePA + 8]::pmem[cachePA];
607
608
          // Fill the L2
609
          l1Entry.V = 1;
610
          l1Entry.TAG = pa<35..12>;
611
          l1Entry.DATA = cacheData;
612
          L1(pa) = l1Entry;
613
        endif; // If the L2 cache is used.
614
      endif; // If the address hits the L1.
615
    // The address is uncacheable.
616
    else
617
      pmem[pa] = data;
618
    endif; // If the address is cacheable.
619
  }
620
621
//==================================================================================================
622
// The End
623
//==================================================================================================
624 1 Taya Sergeeva
</pre>