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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [memory/] [tlb.v] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
`include "defines.v"
28
 
29
//PARSED_COMMENTS: this file contains parsed script comments
30
 
31
module tlb(
32
    input               clk,
33
    input               rst_n,
34
 
35
    input               pr_reset,
36
    input               rd_reset,
37
    input               exe_reset,
38
    input               wr_reset,
39
 
40
    // from control
41
    input               cr0_pg,
42
    input               cr0_wp,
43
    input               cr0_am,
44
    input               cr0_cd,
45
    input               cr0_nw,
46
 
47
    input               acflag,
48
 
49
    input   [31:0]      cr3,
50
 
51
    input               pipeline_after_read_empty,
52
    input               pipeline_after_prefetch_empty,
53
 
54
    output reg  [31:0]  tlb_code_pf_cr2,
55
    output reg  [15:0]  tlb_code_pf_error_code,
56
 
57
    output reg  [31:0]  tlb_check_pf_cr2,
58
    output reg  [15:0]  tlb_check_pf_error_code,
59
 
60
    output reg  [31:0]  tlb_write_pf_cr2,
61
    output reg  [15:0]  tlb_write_pf_error_code,
62
 
63
    output reg  [31:0]  tlb_read_pf_cr2,
64
    output reg  [15:0]  tlb_read_pf_error_code,
65
 
66
    //RESP:
67
    input               tlbflushsingle_do,
68
    output              tlbflushsingle_done,
69
    input   [31:0]      tlbflushsingle_address,
70
    //END
71
 
72
    //RESP:
73
    input               tlbflushall_do,
74
    //END
75
 
76
    //RESP:
77
    input               tlbread_do,
78
    output              tlbread_done,
79
    output              tlbread_page_fault,
80
    output              tlbread_ac_fault,
81
    output              tlbread_retry,
82
 
83
    input   [1:0]       tlbread_cpl,
84
    input   [31:0]      tlbread_address,
85
    input   [3:0]       tlbread_length,
86
    input   [3:0]       tlbread_length_full,
87
    input               tlbread_lock,
88
    input               tlbread_rmw,
89
    output  [63:0]      tlbread_data,
90
    //END
91
 
92
    //RESP:
93
    input               tlbwrite_do,
94
    output              tlbwrite_done,
95
    output              tlbwrite_page_fault,
96
    output              tlbwrite_ac_fault,
97
 
98
    input   [1:0]       tlbwrite_cpl,
99
    input   [31:0]      tlbwrite_address,
100
    input   [2:0]       tlbwrite_length,
101
    input   [2:0]       tlbwrite_length_full,
102
    input               tlbwrite_lock,
103
    input               tlbwrite_rmw,
104
    input   [31:0]      tlbwrite_data,
105
    //END
106
 
107
    //RESP:
108
    input               tlbcheck_do,
109
    output reg          tlbcheck_done,
110
    output              tlbcheck_page_fault,
111
 
112
    input   [31:0]      tlbcheck_address,
113
    input               tlbcheck_rw,
114
    //END
115
 
116
    //REQ:
117
    output              dcacheread_do,
118
    input               dcacheread_done,
119
 
120
    output  [3:0]       dcacheread_length,
121
    output              dcacheread_cache_disable,
122
    output  [31:0]      dcacheread_address,
123
    input   [63:0]      dcacheread_data,
124
    //END
125
 
126
    //REQ:
127
    output              dcachewrite_do,
128
    input               dcachewrite_done,
129
 
130
    output  [2:0]       dcachewrite_length,
131
    output              dcachewrite_cache_disable,
132
    output  [31:0]      dcachewrite_address,
133
    output              dcachewrite_write_through,
134
    output  [31:0]      dcachewrite_data,
135
    //END
136
 
137
    //RESP:
138
    input               tlbcoderequest_do,
139
    input       [31:0]  tlbcoderequest_address,
140
    input               tlbcoderequest_su,
141
    //END
142
 
143
    //REQ:
144
    output reg          tlbcode_do,
145
    output      [31:0]  tlbcode_linear,
146
    output reg  [31:0]  tlbcode_physical,
147
    output reg          tlbcode_cache_disable,
148
    //END
149
 
150
    //REQ:
151
    output              prefetchfifo_signal_pf_do
152
    //END
153
);
154
 
155
//------------------------------------------------------------------------------
156
 
157
reg [4:0]   state;
158
 
159
reg [31:0]  linear;
160
reg         su;
161
reg         rw;
162
reg         wp;
163
reg [1:0]   current_type;
164
 
165
reg [31:0]  pde;
166
reg [31:0]  pte;
167
 
168
reg         code_pf;
169
reg         check_pf;
170
 
171
reg         write_pf;
172
reg         write_ac;
173
 
174
reg         read_pf;
175
reg         read_ac;
176
 
177
reg         pr_reset_waiting;
178
 
179
reg         tlbflushall_do_waiting;
180
 
181
reg [1:0]   write_double_state;
182
reg [31:0]  write_double_linear;
183
 
184
//------------------------------------------------------------------------------
185
 
186
wire [31:0] memtype_physical;
187
wire        memtype_cache_disable;
188
wire        memtype_write_transparent;
189
 
190
wire        rw_entry;
191
wire        su_entry;
192
wire        fault;
193
 
194
wire        rw_entry_before_pte;
195
wire        su_entry_before_pte;
196
wire        fault_before_pte;
197
 
198
wire [31:0] cr3_base;
199
wire        cr3_pwt;
200
wire        cr3_pcd;
201
 
202
assign cr3_base = { cr3[31:12], 12'd0 };
203
assign cr3_pwt  = cr3[3];
204
assign cr3_pcd  = cr3[4];
205
 
206
//------------------------------------------------------------------------------
207
 
208
assign tlbread_data       = dcacheread_data;
209
assign tlbread_page_fault = read_pf;
210
assign tlbread_ac_fault   = read_ac;
211
 
212
assign tlbwrite_page_fault = write_pf;
213
assign tlbwrite_ac_fault   = write_ac;
214
 
215
assign tlbcheck_page_fault = check_pf;
216
 
217
assign rw_entry = (state == STATE_LOAD_PTE_END)? pde[1] & pte[1] : translate_combined_rw;
218
assign su_entry = (state == STATE_LOAD_PTE_END)? pde[2] & pte[2] : translate_combined_su;
219
 
220
assign fault =
221
    // user can not access supervisor
222
    (su && ~(su_entry)) ||
223
    // user can not write on read-only page
224
    (su && su_entry && ~(rw_entry) && rw) ||
225
    // supervisor can not write on read-only page when write-protect is on
226
    (wp && ~(su) && ~(rw_entry) && rw);
227
 
228
assign rw_entry_before_pte = pde[1] & dcacheread_data[1];
229
assign su_entry_before_pte = pde[2] & dcacheread_data[2];
230
 
231
assign fault_before_pte =
232
    // user can not access supervisor
233
    (su && ~(su_entry_before_pte)) ||
234
    // user can not write on read-only page
235
    (su && su_entry_before_pte && ~(rw_entry_before_pte) && rw) ||
236
    // supervisor can not write on read-only page when write-protect is on
237
    (wp && ~(su) && ~(rw_entry_before_pte) && rw);
238
 
239
 
240
assign tlbcode_linear = linear;
241
 
242
//------------------------------------------------------------------------------
243
 
244
localparam [4:0] STATE_IDLE             = 5'd0;
245
localparam [4:0] STATE_CODE_CHECK       = 5'd1;
246
localparam [4:0] STATE_LOAD_PDE         = 5'd2;
247
localparam [4:0] STATE_LOAD_PTE_START   = 5'd3;
248
localparam [4:0] STATE_LOAD_PTE         = 5'd4;
249
localparam [4:0] STATE_LOAD_PTE_END     = 5'd5;
250
localparam [4:0] STATE_SAVE_PDE         = 5'd6;
251
localparam [4:0] STATE_SAVE_PTE_START   = 5'd7;
252
localparam [4:0] STATE_SAVE_PTE         = 5'd8;
253
localparam [4:0] STATE_CHECK_CHECK      = 5'd9;
254
localparam [4:0] STATE_WRITE_CHECK      = 5'd10;
255
localparam [4:0] STATE_WRITE_WAIT_START = 5'd11;
256
localparam [4:0] STATE_WRITE_WAIT       = 5'd12;
257
localparam [4:0] STATE_WRITE_DOUBLE     = 5'd13;
258
localparam [4:0] STATE_READ_CHECK       = 5'd14;
259
localparam [4:0] STATE_READ_WAIT_START  = 5'd15;
260
localparam [4:0] STATE_READ_WAIT        = 5'd16;
261
localparam [4:0] STATE_RETRY            = 5'd17;
262
 
263
localparam [1:0] TYPE_CODE  = 2'd0;
264
localparam [1:0] TYPE_CHECK = 2'd1;
265
localparam [1:0] TYPE_WRITE = 2'd2;
266
localparam [1:0] TYPE_READ  = 2'd3;
267
 
268
localparam [1:0] WRITE_DOUBLE_NONE    = 2'd0;
269
localparam [1:0] WRITE_DOUBLE_CHECK   = 2'd1;
270
localparam [1:0] WRITE_DOUBLE_RESTART = 2'd2;
271
 
272
//------------------------------------------------------------------------------
273
 
274
tlb_memtype tlb_memtype_inst(
275
    .physical           (memtype_physical),             //input [31:0]
276
 
277
    .cache_disable      (memtype_cache_disable),        //output
278
    .write_transparent  (memtype_write_transparent)     //output
279
);
280
 
281
wire translate_combined_rw;
282
wire translate_combined_su;
283
 
284
wire tlbregs_tlbflushsingle_do;
285
wire tlbregs_tlbflushall_do;
286
 
287
wire        translate_do;
288
wire        translate_valid;
289
wire [31:0] translate_physical;
290
wire        translate_pwt;
291
wire        translate_pcd;
292
 
293
wire        tlbregs_write_do;
294
wire [31:0] tlbregs_write_linear;
295
wire [31:0] tlbregs_write_physical;
296
wire        tlbregs_write_pwt;
297
wire        tlbregs_write_pcd;
298
wire        tlbregs_write_combined_rw;
299
wire        tlbregs_write_combined_su;
300
 
301
tlb_regs tlb_regs_inst(
302
    .clk                        (clk),
303
    .rst_n                      (rst_n),
304
 
305
    //RESP:
306
    .tlbflushsingle_do          (tlbregs_tlbflushsingle_do),    //input
307
    .tlbflushsingle_address     (tlbflushsingle_address),       //input [31:0]
308
    //END
309
 
310
    //RESP:
311
    .tlbflushall_do             (tlbregs_tlbflushall_do),       //input
312
    //END
313
 
314
    .rw                         (rw),                           //input
315
 
316
    //RESP:
317
    .tlbregs_write_do           (tlbregs_write_do),             //input
318
    .tlbregs_write_linear       (tlbregs_write_linear),         //input [31:0]
319
    .tlbregs_write_physical     (tlbregs_write_physical),       //input [31:0]
320
 
321
    .tlbregs_write_pwt          (tlbregs_write_pwt),            //input
322
    .tlbregs_write_pcd          (tlbregs_write_pcd),            //input
323
    .tlbregs_write_combined_rw  (tlbregs_write_combined_rw),    //input
324
    .tlbregs_write_combined_su  (tlbregs_write_combined_su),    //input
325
    //END
326
 
327
    //RESP:
328
    .translate_do               (translate_do),                 //input
329
    .translate_linear           (linear),                       //input [31:0]
330
    .translate_valid            (translate_valid),              //output
331
    .translate_physical         (translate_physical),           //output [31:0]
332
    .translate_pwt              (translate_pwt),                //output
333
    .translate_pcd              (translate_pcd),                //output
334
    .translate_combined_rw      (translate_combined_rw),        //output
335
    .translate_combined_su      (translate_combined_su)         //output
336
    //END
337
);
338
 
339
//------------------------------------------------------------------------------
340
 
341
always @(posedge clk or negedge rst_n) begin
342
    if(rst_n == 1'b0)   code_pf <= `FALSE;
343
    else if(pr_reset)   code_pf <= `FALSE;
344
    else                code_pf <= code_pf_to_reg;
345
end
346
 
347
always @(posedge clk or negedge rst_n) begin
348
    if(rst_n == 1'b0)   check_pf <= `FALSE;
349
    else if(exe_reset)  check_pf <= `FALSE;
350
    else                check_pf <= check_pf_to_reg;
351
end
352
 
353
always @(posedge clk or negedge rst_n) begin
354
    if(rst_n == 1'b0)   read_pf <= `FALSE;
355
    else if(rd_reset)   read_pf <= `FALSE;
356
    else                read_pf <= read_pf_to_reg;
357
end
358
 
359
always @(posedge clk or negedge rst_n) begin
360
    if(rst_n == 1'b0)   read_ac <= `FALSE;
361
    else if(rd_reset)   read_ac <= `FALSE;
362
    else                read_ac <= read_ac_to_reg;
363
end
364
 
365
always @(posedge clk or negedge rst_n) begin
366
    if(rst_n == 1'b0)   write_pf <= `FALSE;
367
    else if(wr_reset)   write_pf <= `FALSE;
368
    else                write_pf <= write_pf_to_reg;
369
end
370
 
371
always @(posedge clk or negedge rst_n) begin
372
    if(rst_n == 1'b0)   write_ac <= `FALSE;
373
    else if(wr_reset)   write_ac <= `FALSE;
374
    else                write_ac <= write_ac_to_reg;
375
end
376
 
377
always @(posedge clk or negedge rst_n) begin
378
    if(rst_n == 1'b0)                           pr_reset_waiting <= `FALSE;
379
    else if(pr_reset && state != STATE_IDLE)    pr_reset_waiting <= `TRUE;
380
    else if(state == STATE_IDLE)                pr_reset_waiting <= `FALSE;
381
end
382
 
383
always @(posedge clk or negedge rst_n) begin
384
    if(rst_n == 1'b0)                               tlbflushall_do_waiting <= `FALSE;
385
    else if(tlbflushall_do && state != STATE_IDLE)  tlbflushall_do_waiting <= `TRUE;
386
    else if(tlbregs_tlbflushall_do)                 tlbflushall_do_waiting <= `FALSE;
387
end
388
 
389
//------------------------------------------------------------------------------
390
 
391
// synthesis translate_off
392
wire _unused_ok = &{ 1'b0, cr3[11:5], cr3[2:0], tlbread_lock, tlbwrite_lock, tlbwrite_rmw, cr3_base[11:0], 1'b0 };
393
// synthesis translate_on
394
 
395
//------------------------------------------------------------------------------
396
 
397
/*******************************************************************************SCRIPT
398
NO_ALWAYS_BLOCK(code_pf);
399
NO_ALWAYS_BLOCK(check_pf);
400
NO_ALWAYS_BLOCK(read_pf);
401
NO_ALWAYS_BLOCK(write_pf);
402
NO_ALWAYS_BLOCK(read_ac);
403
NO_ALWAYS_BLOCK(write_ac);
404
*/
405
 
406
/*******************************************************************************SCRIPT
407
IF(state == STATE_IDLE);
408
 
409
    SAVE(tlbcheck_done, `FALSE);
410
    SAVE(tlbcode_do,    `FALSE);
411
    SAVE(read_pf,       `FALSE);
412
    SAVE(write_pf,      `FALSE);
413
 
414
    IF(tlbflushsingle_do);
415
 
416
        SET(tlbregs_tlbflushsingle_do);
417
        SET(tlbflushsingle_done);
418
 
419
    ELSE_IF(tlbflushall_do || tlbflushall_do_waiting);
420
 
421
        SET(tlbregs_tlbflushall_do);
422
 
423
    ELSE_IF(~(wr_reset) && tlbwrite_do && ~(write_ac) && cr0_am && acflag && tlbwrite_cpl == 2'd3 &&
424
             ( (tlbwrite_length_full == 3'd2 && tlbwrite_address[0] != 1'b0) || (tlbwrite_length_full == 3'd4 && tlbwrite_address[1:0] != 2'b00) )
425
    );
426
 
427
        SAVE(write_ac, `TRUE);
428
 
429
    ELSE_IF(~(wr_reset) && tlbwrite_do && ~(write_pf) && ~(write_ac));
430
 
431
        SAVE(rw,             `TRUE);
432
        SAVE(su,             tlbwrite_cpl == 2'd3);
433
        SAVE(wp,             cr0_wp);
434
 
435
        SAVE(write_double_state, (cr0_pg && tlbwrite_length != tlbwrite_length_full && { 1'b0, tlbwrite_address[11:0] } + { 10'd0, tlbwrite_length_full } >= 13'h1000)? WRITE_DOUBLE_CHECK : WRITE_DOUBLE_NONE);
436
 
437
        SAVE(linear, tlbwrite_address);
438
        SAVE(state,  STATE_WRITE_CHECK);
439
 
440
    ELSE_IF(~(exe_reset) && tlbcheck_do && ~(tlbcheck_done) && ~(check_pf));
441
 
442
        SAVE(rw,             tlbcheck_rw);
443
        SAVE(su,             `FALSE);
444
        SAVE(wp,             cr0_wp);
445
 
446
        SAVE(write_double_state, WRITE_DOUBLE_NONE);
447
 
448
        SAVE(linear, tlbcheck_address);
449
        SAVE(state,  STATE_CHECK_CHECK);
450
 
451
    ELSE_IF(~(rd_reset) && tlbread_do && ~(read_ac) && cr0_am && acflag && tlbread_cpl == 2'd3 &&
452
             ( (tlbread_length_full == 4'd2 && tlbread_address[0] != 1'b0) || (tlbread_length_full == 4'd4 && tlbread_address[1:0] != 2'b00))
453
    );
454
 
455
        SAVE(read_ac, `TRUE);
456
 
457
    ELSE_IF(~(rd_reset) && tlbread_do && ~(read_pf) && ~(read_ac));
458
 
459
        SAVE(rw,             tlbread_rmw);
460
        SAVE(su,             tlbread_cpl == 2'd3);
461
        SAVE(wp,             cr0_wp);
462
 
463
        SAVE(write_double_state, WRITE_DOUBLE_NONE);
464
 
465
        SAVE(linear, tlbread_address);
466
        SAVE(state,  STATE_READ_CHECK);
467
 
468
 
469
    ELSE_IF(~(pr_reset) && tlbcoderequest_do && ~(code_pf) && ~(tlbcode_do));
470
 
471
        SAVE(rw,             `FALSE);
472
        SAVE(su,             tlbcoderequest_su);
473
        SAVE(wp,             cr0_wp);
474
 
475
        SAVE(write_double_state, WRITE_DOUBLE_NONE);
476
 
477
        SAVE(linear, tlbcoderequest_address);
478
        SAVE(state,  STATE_CODE_CHECK);
479
 
480
    ENDIF();
481
ENDIF();
482
*/
483
 
484
/*******************************************************************************SCRIPT
485
 
486
IF(state == STATE_WRITE_DOUBLE);
487
 
488
    IF(write_double_state == WRITE_DOUBLE_CHECK);
489
        SAVE(linear, { linear[31:12], 12'd0 } + 32'h00001000);
490
        SAVE(write_double_linear, linear);
491
 
492
        SAVE(write_double_state, WRITE_DOUBLE_RESTART);
493
        SAVE(state,              STATE_WRITE_CHECK);
494
    ELSE();
495
        SAVE(linear, write_double_linear);
496
 
497
        SAVE(write_double_state, WRITE_DOUBLE_NONE);
498
        SAVE(state,              STATE_WRITE_CHECK);
499
    ENDIF();
500
ENDIF();
501
 
502
*/
503
 
504
/*******************************************************************************SCRIPT
505
IF(state == STATE_WRITE_WAIT);
506
 
507
    IF(dcachewrite_done);
508
        SET(tlbwrite_done);
509
 
510
        SAVE(state, STATE_IDLE);
511
    ENDIF();
512
 
513
ENDIF();
514
*/
515
 
516
/*******************************************************************************SCRIPT
517
 
518
IF(state == STATE_READ_WAIT);
519
 
520
    IF(dcacheread_done);
521
        SET(tlbread_done);
522
 
523
        SAVE(state, STATE_IDLE);
524
    ENDIF();
525
 
526
ENDIF();
527
*/
528
 
529
/*******************************************************************************SCRIPT
530
 
531
IF(state == STATE_READ_CHECK);
532
 
533
    IF(cr0_pg);
534
        SET(translate_do);
535
    ENDIF();
536
 
537
    IF(~(cr0_pg) || translate_valid);
538
 
539
        IF(cr0_pg && fault);
540
            SAVE(read_pf,            `TRUE);
541
 
542
            SAVE(tlb_read_pf_cr2,        linear);
543
            SAVE(tlb_read_pf_error_code, { 13'd0, su, rw, `TRUE });
544
 
545
            SAVE(state, STATE_IDLE);
546
 
547
        ELSE();
548
 
549
            SET(memtype_physical, translate_physical);
550
 
551
            SET(dcacheread_do);
552
            SET(dcacheread_address,          memtype_physical);
553
            SET(dcacheread_length,           tlbread_length);
554
            SET(dcacheread_cache_disable,    cr0_cd || translate_pcd || memtype_cache_disable);
555
 
556
            SAVE(state, STATE_READ_WAIT);
557
        ENDIF();
558
 
559
    ELSE();
560
 
561
        SET(memtype_physical, { cr3_base[31:12], linear[31:22], 2'd0 });
562
 
563
        SET(dcacheread_do);
564
        SET(dcacheread_address,          memtype_physical);
565
        SET(dcacheread_length,           4'd4);
566
        SET(dcacheread_cache_disable,    cr0_cd || cr3_pcd || memtype_cache_disable);
567
 
568
        SAVE(current_type,   TYPE_READ);
569
        SAVE(state,          STATE_LOAD_PDE);
570
 
571
    ENDIF();
572
 
573
ENDIF();
574
*/
575
 
576
/*******************************************************************************SCRIPT
577
 
578
IF(state == STATE_WRITE_CHECK);
579
 
580
    IF(cr0_pg);
581
        SET(translate_do);
582
    ENDIF();
583
 
584
    IF(~(cr0_pg) || translate_valid);
585
 
586
        IF(cr0_pg && fault);
587
            SAVE(write_pf,                `TRUE);
588
 
589
            SAVE(tlb_write_pf_cr2,        linear);
590
            SAVE(tlb_write_pf_error_code, { 13'd0, su, rw, `TRUE });
591
 
592
            SAVE(state, STATE_IDLE);
593
 
594
        ELSE_IF(translate_valid && write_double_state != WRITE_DOUBLE_NONE);
595
 
596
            SAVE(state, STATE_WRITE_DOUBLE);
597
 
598
        ELSE();
599
 
600
            SET(memtype_physical, translate_physical);
601
 
602
            SET(dcachewrite_do);
603
            SET(dcachewrite_address,         memtype_physical);
604
            SET(dcachewrite_length,          tlbwrite_length);
605
            SET(dcachewrite_cache_disable,   cr0_cd || translate_pcd || memtype_cache_disable);
606
            SET(dcachewrite_write_through,   cr0_nw || translate_pwt || memtype_write_transparent);
607
            SET(dcachewrite_data,            tlbwrite_data);
608
 
609
            SAVE(state, STATE_WRITE_WAIT);
610
        ENDIF();
611
 
612
    ELSE();
613
 
614
        SET(memtype_physical, { cr3_base[31:12], linear[31:22], 2'd0 });
615
 
616
        SET(dcacheread_do);
617
        SET(dcacheread_address,          memtype_physical);
618
        SET(dcacheread_length,           4'd4);
619
        SET(dcacheread_cache_disable,    cr0_cd || cr3_pcd || memtype_cache_disable);
620
 
621
        SAVE(current_type,   TYPE_WRITE);
622
        SAVE(state,          STATE_LOAD_PDE);
623
 
624
    ENDIF();
625
 
626
ENDIF();
627
*/
628
 
629
/*******************************************************************************SCRIPT
630
 
631
IF(state == STATE_CHECK_CHECK);
632
 
633
    IF(cr0_pg);
634
        SET(translate_do);
635
    ENDIF();
636
 
637
    IF(~(cr0_pg) || translate_valid);
638
 
639
        IF(cr0_pg && fault);
640
            SAVE(check_pf,               `TRUE);
641
 
642
            SAVE(tlb_check_pf_cr2,       linear);
643
            SAVE(tlb_check_pf_error_code,{ 13'd0, su, rw, `TRUE });
644
 
645
        ELSE();
646
            SAVE(tlbcheck_done, `TRUE);
647
        ENDIF();
648
 
649
        SAVE(state, STATE_IDLE);
650
 
651
    ELSE();
652
 
653
        SET(memtype_physical, { cr3_base[31:12], linear[31:22], 2'd0 });
654
 
655
        SET(dcacheread_do);
656
        SET(dcacheread_address,          memtype_physical);
657
        SET(dcacheread_length,           4'd4);
658
        SET(dcacheread_cache_disable,    cr0_cd || cr3_pcd || memtype_cache_disable);
659
 
660
        SAVE(current_type,   TYPE_CHECK);
661
        SAVE(state,          STATE_LOAD_PDE);
662
 
663
    ENDIF();
664
 
665
ENDIF();
666
*/
667
 
668
/*******************************************************************************SCRIPT
669
 
670
IF(state == STATE_CODE_CHECK);
671
 
672
    IF(cr0_pg);
673
        SET(translate_do);
674
    ENDIF();
675
 
676
    IF(pr_reset || pr_reset_waiting); //NOTE: pr_reset required
677
 
678
        SAVE(state, STATE_IDLE);
679
 
680
    ELSE_IF(~(cr0_pg) || translate_valid);
681
 
682
        IF(cr0_pg && fault);
683
            SAVE(code_pf,                `TRUE);
684
 
685
            SAVE(tlb_code_pf_cr2,       linear);
686
            SAVE(tlb_code_pf_error_code,{ 13'd0, su, rw, `TRUE });
687
 
688
            SET(prefetchfifo_signal_pf_do);
689
 
690
        ELSE();
691
 
692
            SET(memtype_physical, translate_physical);
693
 
694
            SAVE(tlbcode_do, `TRUE);
695
            SAVE(tlbcode_physical,        memtype_physical);
696
            SAVE(tlbcode_cache_disable,   cr0_cd || translate_pcd || memtype_cache_disable);
697
 
698
        ENDIF();
699
 
700
        SAVE(state, STATE_IDLE);
701
 
702
    ELSE();
703
 
704
        SET(memtype_physical, { cr3_base[31:12], linear[31:22], 2'd0 });
705
 
706
 
707
        SET(dcacheread_do);
708
        SET(dcacheread_address,          memtype_physical);
709
        SET(dcacheread_length,           4'd4);
710
        SET(dcacheread_cache_disable,    cr0_cd || cr3_pcd || memtype_cache_disable);
711
 
712
        SAVE(current_type,   TYPE_CODE);
713
        SAVE(state,          STATE_LOAD_PDE);
714
    ENDIF();
715
ENDIF();
716
*/
717
 
718
/*******************************************************************************SCRIPT
719
 
720
IF(state == STATE_LOAD_PDE);
721
 
722
    IF(dcacheread_done);
723
 
724
        SAVE(pde, dcacheread_data[31:0]);
725
 
726
        IF(dcacheread_data[0] == `FALSE);
727
 
728
            IF(current_type == TYPE_CODE && ~(pr_reset) && ~(pr_reset_waiting));
729
 
730
                SAVE(code_pf,                `TRUE);
731
                SAVE(tlb_code_pf_cr2,        linear);
732
                SAVE(tlb_code_pf_error_code, { 13'd0, su, rw, `FALSE });
733
 
734
                SET(prefetchfifo_signal_pf_do);
735
 
736
            ELSE_IF(current_type == TYPE_CHECK);
737
 
738
                SAVE(check_pf,               `TRUE);
739
                SAVE(tlb_check_pf_cr2,       linear);
740
                SAVE(tlb_check_pf_error_code,{ 13'd0, su, rw, `FALSE });
741
 
742
            ELSE_IF(current_type == TYPE_WRITE);
743
 
744
                SAVE(write_pf,               `TRUE);
745
                SAVE(tlb_write_pf_cr2,       linear);
746
                SAVE(tlb_write_pf_error_code,{ 13'd0, su, rw, `FALSE });
747
 
748
            ELSE_IF(current_type == TYPE_READ);
749
 
750
                SAVE(read_pf,                `TRUE);
751
                SAVE(tlb_read_pf_cr2,        linear);
752
                SAVE(tlb_read_pf_error_code, { 13'd0, su, rw, `FALSE });
753
 
754
            ENDIF();
755
 
756
            SAVE(state, STATE_IDLE);
757
 
758
        ELSE();
759
 
760
            SAVE(state, STATE_LOAD_PTE_START);
761
 
762
        ENDIF();
763
    ENDIF();
764
ENDIF();
765
*/
766
 
767
/*******************************************************************************SCRIPT
768
IF(state == STATE_LOAD_PTE_START);
769
 
770
    SET(memtype_physical, { pde[31:12], linear[21:12], 2'd0 });
771
 
772
    SET(dcacheread_do);
773
    SET(dcacheread_address,          memtype_physical);
774
    SET(dcacheread_length,           4'd4);
775
    SET(dcacheread_cache_disable,    cr0_cd || pde[4] || memtype_cache_disable);
776
 
777
    SAVE(state, STATE_LOAD_PTE);
778
 
779
ENDIF();
780
*/
781
 
782
/*******************************************************************************SCRIPT
783
IF(state == STATE_RETRY);
784
 
785
    SAVE(state, STATE_IDLE);
786
 
787
    SET(tlbread_retry, current_type == TYPE_READ);
788
ENDIF();
789
*/
790
 
791
/*******************************************************************************SCRIPT
792
IF(state == STATE_LOAD_PTE);
793
 
794
    IF(dcacheread_done);
795
 
796
        SAVE(pte, dcacheread_data[31:0]);
797
 
798
        IF(dcacheread_data[0] == `FALSE || fault_before_pte);
799
 
800
            IF(current_type == TYPE_CODE && ~(pr_reset) && ~(pr_reset_waiting));
801
 
802
                SAVE(code_pf,                `TRUE);
803
                SAVE(tlb_code_pf_cr2,        linear);
804
                SAVE(tlb_code_pf_error_code, { 13'd0, su, rw, dcacheread_data[0] });
805
 
806
                SET(prefetchfifo_signal_pf_do);
807
 
808
            ELSE_IF(current_type == TYPE_CHECK);
809
 
810
                SAVE(check_pf,               `TRUE);
811
                SAVE(tlb_check_pf_cr2,       linear);
812
                SAVE(tlb_check_pf_error_code,{ 13'd0, su, rw, dcacheread_data[0] });
813
 
814
            ELSE_IF(current_type == TYPE_WRITE);
815
 
816
                SAVE(write_pf,               `TRUE);
817
                SAVE(tlb_write_pf_cr2,       linear);
818
                SAVE(tlb_write_pf_error_code,{ 13'd0, su, rw, dcacheread_data[0] });
819
 
820
            ELSE_IF(current_type == TYPE_READ);
821
 
822
                SAVE(read_pf,            `TRUE);
823
                SAVE(tlb_read_pf_cr2,        linear);
824
                SAVE(tlb_read_pf_error_code, { 13'd0, su, rw, dcacheread_data[0] });
825
 
826
            ENDIF();
827
 
828
            SAVE(state, STATE_IDLE);
829
 
830
        ELSE_IF(((current_type == TYPE_READ && ~(pipeline_after_read_empty)) || (current_type == TYPE_CODE && (~(pipeline_after_prefetch_empty) || pr_reset_waiting))) &&
831
                 (pde[5] == `FALSE || dcacheread_data[5] == `FALSE || (dcacheread_data[6] == `FALSE && rw)));
832
 
833
                // no side effects for read or code possible yet
834
                SAVE(state, STATE_RETRY);
835
 
836
//AO-notlb: ELSE_IF(current_type == TYPE_CODE && (pr_reset || pr_reset_waiting));
837
//AO-notlb: SAVE(state, STATE_IDLE);
838
 
839
        ELSE();
840
            SAVE(state, STATE_LOAD_PTE_END);
841
        ENDIF();
842
    ENDIF();
843
ENDIF();
844
*/
845
 
846
 
847
/*******************************************************************************SCRIPT
848
IF(state == STATE_LOAD_PTE_END);
849
 
850
//NOTE: always write to TLB: IF(cr0_cd == `FALSE && pde[4] == `FALSE && pte[4] == `FALSE);
851
 
852
    SET(tlbregs_write_do);
853
    SET(tlbregs_write_linear,        linear);
854
    SET(tlbregs_write_physical,      { pte[31:12], linear[11:0] });
855
    SET(tlbregs_write_pwt,           pte[3]);
856
    SET(tlbregs_write_pcd,           pte[4]);
857
    SET(tlbregs_write_combined_rw,   rw_entry);
858
    SET(tlbregs_write_combined_su,   su_entry);
859
 
860
    // PDE not accessed
861
    IF(pde[5] == `FALSE);
862
 
863
        SET(memtype_physical, { cr3_base[31:12], linear[31:22], 2'd0 });
864
 
865
        SET(dcachewrite_do);
866
        SET(dcachewrite_address,         memtype_physical);
867
        SET(dcachewrite_length,          3'd4);
868
        SET(dcachewrite_cache_disable,   cr0_cd || cr3_pcd || memtype_cache_disable);
869
        SET(dcachewrite_write_through,   cr0_nw || cr3_pwt || memtype_write_transparent);
870
        SET(dcachewrite_data,            pde | 32'h00000020);
871
 
872
        SAVE(state, STATE_SAVE_PDE);
873
 
874
    // PTE not accessed or has to become dirty
875
    ELSE_IF(pte[5] == `FALSE || (pte[6] == `FALSE && rw));
876
 
877
        SET(memtype_physical, { pde[31:12], linear[21:12], 2'b00 });
878
 
879
        SET(dcachewrite_do);
880
        SET(dcachewrite_address,         memtype_physical);
881
        SET(dcachewrite_length,          3'd4);
882
        SET(dcachewrite_cache_disable,   cr0_cd || pde[4] || memtype_cache_disable);
883
        SET(dcachewrite_write_through,   cr0_nw || pde[3] || memtype_write_transparent);
884
        SET(dcachewrite_data,            pte[31:0] | 32'h00000020 | ((pte[6] == `FALSE && rw)? 32'h00000040 : 32'h00000000));
885
 
886
        SAVE(state, STATE_SAVE_PTE);
887
 
888
    ELSE();
889
 
890
        IF(current_type == TYPE_WRITE && write_double_state != WRITE_DOUBLE_NONE);
891
 
892
            SAVE(state, STATE_WRITE_DOUBLE);
893
 
894
        ELSE_IF(current_type == TYPE_WRITE);
895
 
896
            SET(memtype_physical, { pte[31:12], linear[11:0] });
897
 
898
            SET(dcachewrite_do);
899
            SET(dcachewrite_address,         memtype_physical);
900
            SET(dcachewrite_length,          tlbwrite_length);
901
            SET(dcachewrite_cache_disable,   cr0_cd || pte[4] || memtype_cache_disable);
902
            SET(dcachewrite_write_through,   cr0_nw || pte[3] || memtype_write_transparent);
903
            SET(dcachewrite_data,            tlbwrite_data);
904
 
905
            SAVE(state, STATE_WRITE_WAIT);
906
 
907
        ELSE_IF(current_type == TYPE_READ);
908
 
909
            SAVE(state, STATE_READ_WAIT_START);
910
 
911
//AO-notlb: ELSE_IF(current_type == TYPE_CODE && pr_reset == 1'b0 && pr_reset_waiting == 1'b0);
912
//AO-notlb: SAVE(tlbcode_do, `TRUE);
913
//AO-notlb: SAVE(tlbcode_physical,    { pte[31:12], linear[11:0] });
914
//AO-notlb: SAVE(tlbcode_cache_disable,   cr0_cd);
915
//AO-notlb: SAVE(state, STATE_IDLE);
916
        ELSE();
917
 
918
            SAVE(state, STATE_IDLE);
919
        ENDIF();
920
    ENDIF();
921
ENDIF();
922
*/
923
 
924
/*******************************************************************************SCRIPT
925
IF(state == STATE_READ_WAIT_START);
926
 
927
    SET(memtype_physical, { pte[31:12], linear[11:0] });
928
 
929
    SET(dcacheread_do);
930
    SET(dcacheread_address,          memtype_physical);
931
    SET(dcacheread_length,           tlbread_length);
932
    SET(dcacheread_cache_disable,    cr0_cd || pte[4] || memtype_cache_disable);
933
 
934
    SAVE(state, STATE_READ_WAIT);
935
 
936
ENDIF();
937
*/
938
 
939
/*******************************************************************************SCRIPT
940
 
941
IF(state == STATE_SAVE_PDE);
942
 
943
    IF(dcachewrite_done);
944
 
945
        // PTE not accessed or has to become dirty
946
        IF(pte[5] == `FALSE || (pte[6] == `FALSE && rw));
947
 
948
            SAVE(state, STATE_SAVE_PTE_START);
949
 
950
        ELSE();
951
 
952
            IF(current_type == TYPE_WRITE);
953
 
954
                SAVE(state, STATE_WRITE_WAIT_START);
955
 
956
            ELSE_IF(current_type == TYPE_READ);
957
 
958
                SET(memtype_physical, { pte[31:12], linear[11:0] });
959
 
960
                SET(dcacheread_do);
961
                SET(dcacheread_address,          memtype_physical);
962
                SET(dcacheread_length,           tlbread_length);
963
                SET(dcacheread_cache_disable,    cr0_cd || pte[4] || memtype_cache_disable);
964
 
965
                SAVE(state, STATE_READ_WAIT);
966
 
967
//AO-notlb: ELSE_IF(current_type == TYPE_CODE && pr_reset == 1'b0 && pr_reset_waiting == 1'b0);
968
//AO-notlb: SAVE(tlbcode_do, `TRUE);
969
//AO-notlb: SAVE(tlbcode_physical,    { pte[31:12], linear[11:0] });
970
//AO-notlb: SAVE(tlbcode_cache_disable,   cr0_cd);
971
//AO-notlb: SAVE(state, STATE_IDLE);
972
 
973
            ELSE();
974
 
975
                SAVE(state, STATE_IDLE);
976
 
977
            ENDIF();
978
 
979
        ENDIF();
980
    ENDIF();
981
ENDIF();
982
*/
983
 
984
/*******************************************************************************SCRIPT
985
 
986
IF(state == STATE_SAVE_PTE_START);
987
 
988
    SET(memtype_physical, { pde[31:12], linear[21:12], 2'b00 });
989
 
990
    SET(dcachewrite_do);
991
    SET(dcachewrite_address,         memtype_physical);
992
    SET(dcachewrite_length,          3'd4);
993
    SET(dcachewrite_cache_disable,   cr0_cd || pde[4] || memtype_cache_disable);
994
    SET(dcachewrite_write_through,   cr0_nw || pde[3] || memtype_write_transparent);
995
    SET(dcachewrite_data,            pte[31:0] | 32'h00000020 | ((pte[6] == `FALSE && rw)? 32'h00000040 : 32'h00000000));
996
 
997
    SAVE(state, STATE_SAVE_PTE);
998
 
999
ENDIF();
1000
*/
1001
 
1002
/*******************************************************************************SCRIPT
1003
 
1004
IF(state == STATE_WRITE_WAIT_START);
1005
 
1006
    IF(current_type == TYPE_WRITE && write_double_state != WRITE_DOUBLE_NONE);
1007
 
1008
        SAVE(state, STATE_WRITE_DOUBLE);
1009
 
1010
    ELSE();
1011
 
1012
        SET(memtype_physical, { pte[31:12], linear[11:0] });
1013
 
1014
        SET(dcachewrite_do);
1015
        SET(dcachewrite_address,         memtype_physical);
1016
        SET(dcachewrite_length,          tlbwrite_length);
1017
        SET(dcachewrite_cache_disable,   cr0_cd || pte[4] || memtype_cache_disable);
1018
        SET(dcachewrite_write_through,   cr0_nw || pte[3] || memtype_write_transparent);
1019
        SET(dcachewrite_data,            tlbwrite_data);
1020
 
1021
        SAVE(state, STATE_WRITE_WAIT);
1022
    ENDIF();
1023
ENDIF();
1024
*/
1025
 
1026
/*******************************************************************************SCRIPT
1027
 
1028
IF(state == STATE_SAVE_PTE);
1029
 
1030
    IF(dcachewrite_done);
1031
 
1032
        IF(current_type == TYPE_WRITE);
1033
 
1034
            SAVE(state, STATE_WRITE_WAIT_START);
1035
 
1036
        ELSE_IF(current_type == TYPE_READ);
1037
 
1038
            SET(memtype_physical, { pte[31:12], linear[11:0] });
1039
 
1040
            SET(dcacheread_do);
1041
            SET(dcacheread_address,          memtype_physical);
1042
            SET(dcacheread_length,           tlbread_length);
1043
            SET(dcacheread_cache_disable,    cr0_cd || pte[4] || memtype_cache_disable);
1044
 
1045
            SAVE(state, STATE_READ_WAIT);
1046
 
1047
//AO-notlb: ELSE_IF(current_type == TYPE_CODE && pr_reset == 1'b0 && pr_reset_waiting == 1'b0);
1048
//AO-notlb: SAVE(tlbcode_do, `TRUE);
1049
//AO-notlb: SAVE(tlbcode_physical,    { pte[31:12], linear[11:0] });
1050
//AO-notlb: SAVE(tlbcode_cache_disable,   cr0_cd);
1051
//AO-notlb: SAVE(state, STATE_IDLE);
1052
 
1053
        ELSE();
1054
 
1055
            SAVE(state, STATE_IDLE);
1056
        ENDIF();
1057
 
1058
    ENDIF();
1059
ENDIF();
1060
*/
1061
 
1062
//------------------------------------------------------------------------------
1063
 
1064
`include "autogen/tlb.v"
1065
 
1066
endmodule

powered by: WebSVN 2.1.0

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