1 |
2 |
alfik |
/*
|
2 |
|
|
* This file is subject to the terms and conditions of the BSD License. See
|
3 |
|
|
* the file "LICENSE" in the main directory of this archive for more details.
|
4 |
|
|
*
|
5 |
|
|
* Copyright (C) 2014 Aleksander Osman
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
`include "defines.v"
|
9 |
|
|
|
10 |
|
|
module memory_instr_tlb_micro(
|
11 |
|
|
input clk,
|
12 |
|
|
input rst_n,
|
13 |
|
|
|
14 |
|
|
//0-cycle; always accepted; highest priority
|
15 |
|
|
input micro_flush_do,
|
16 |
|
|
|
17 |
|
|
//0-cycle; always accepted; lower priority
|
18 |
|
|
input micro_write_do,
|
19 |
|
|
input [49:0] micro_write_value,
|
20 |
|
|
|
21 |
|
|
//0-cycle output; if together with flush, then no match
|
22 |
|
|
input micro_check_do,
|
23 |
|
|
input [19:0] micro_check_vpn,
|
24 |
|
|
input [5:0] micro_check_asid,
|
25 |
|
|
output micro_check_matched,
|
26 |
|
|
output [49:0] micro_check_result
|
27 |
|
|
);
|
28 |
|
|
|
29 |
|
|
//------------------------------------------------------------------------------
|
30 |
|
|
|
31 |
|
|
/*
|
32 |
|
|
[19:0] vpn
|
33 |
|
|
[39:20] pfn
|
34 |
|
|
[45:40] asid
|
35 |
|
|
[46] n noncachable
|
36 |
|
|
[47] d dirty = write-enable
|
37 |
|
|
[48] v valid
|
38 |
|
|
[49] g global
|
39 |
|
|
|
40 |
|
|
[50] loaded
|
41 |
|
|
*/
|
42 |
|
|
|
43 |
|
|
//------------------------------------------------------------------------------
|
44 |
|
|
|
45 |
|
|
reg [50:0] micro00; reg [50:0] micro01; reg [50:0] micro02; reg [50:0] micro03;
|
46 |
|
|
|
47 |
|
|
wire sel00 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro00[19:0] && micro00[50] && (micro00[49] || micro_check_asid == micro00[45:40]);
|
48 |
|
|
wire sel01 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro01[19:0] && micro01[50] && (micro01[49] || micro_check_asid == micro01[45:40]);
|
49 |
|
|
wire sel02 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro02[19:0] && micro02[50] && (micro02[49] || micro_check_asid == micro02[45:40]);
|
50 |
|
|
wire sel03 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro03[19:0] && micro03[50] && (micro03[49] || micro_check_asid == micro03[45:40]);
|
51 |
|
|
|
52 |
|
|
assign micro_check_matched = sel00 || sel01 || sel02 || sel03;
|
53 |
|
|
|
54 |
|
|
assign micro_check_result =
|
55 |
|
|
(sel00)? micro00[49:0] :
|
56 |
|
|
(sel01)? micro01[49:0] :
|
57 |
|
|
(sel02)? micro02[49:0] :
|
58 |
|
|
micro03[49:0];
|
59 |
|
|
|
60 |
|
|
wire ena00 = `TRUE;
|
61 |
|
|
wire ena01 = ena00 && micro00[50];
|
62 |
|
|
wire ena02 = ena01 && micro01[50];
|
63 |
|
|
wire ena03 = ena02 && micro02[50];
|
64 |
|
|
wire full = ena03 && micro03[50];
|
65 |
|
|
|
66 |
|
|
wire write00 = micro_write_do && ((~(micro00[50]) && ena00) || (full && ~(plru[0]) && ~(plru[1])));
|
67 |
|
|
wire write01 = micro_write_do && ((~(micro01[50]) && ena01) || (full && ~(plru[0]) && (plru[1])));
|
68 |
|
|
wire write02 = micro_write_do && ((~(micro02[50]) && ena02) || (full && (plru[0]) && ~(plru[2])));
|
69 |
|
|
wire write03 = micro_write_do && ((~(micro03[50]) && ena03) || (full && (plru[0]) && (plru[2])));
|
70 |
|
|
|
71 |
|
|
/* Tree pseudo LRU
|
72 |
|
|
* [0]
|
73 |
|
|
* [1] [2]
|
74 |
|
|
* 0 1 2 3
|
75 |
|
|
*/
|
76 |
|
|
|
77 |
|
|
localparam [2:0] MICRO_03_MASK = 3'b101; //0,2
|
78 |
|
|
localparam [2:0] MICRO_03_VALUE = 3'b000; //0,2
|
79 |
|
|
|
80 |
|
|
localparam [2:0] MICRO_02_MASK = 3'b101; //0,2
|
81 |
|
|
localparam [2:0] MICRO_02_VALUE = 3'b100; //0,2
|
82 |
|
|
|
83 |
|
|
localparam [2:0] MICRO_01_MASK = 3'b011; //0,1
|
84 |
|
|
localparam [2:0] MICRO_01_VALUE = 3'b001; //0,1
|
85 |
|
|
|
86 |
|
|
localparam [2:0] MICRO_00_MASK = 3'b011; //0,1
|
87 |
|
|
localparam [2:0] MICRO_00_VALUE = 3'b011; //0,1
|
88 |
|
|
|
89 |
|
|
reg [2:0] plru;
|
90 |
|
|
always @(posedge clk or negedge rst_n) begin
|
91 |
|
|
if(rst_n == 1'b0) plru <= 3'd0;
|
92 |
|
|
else if(micro_flush_do) plru <= 3'd0;
|
93 |
|
|
else if(write00 || sel00) plru <= (plru & ~(MICRO_00_MASK)) | MICRO_00_VALUE;
|
94 |
|
|
else if(write01 || sel01) plru <= (plru & ~(MICRO_01_MASK)) | MICRO_01_VALUE;
|
95 |
|
|
else if(write02 || sel02) plru <= (plru & ~(MICRO_02_MASK)) | MICRO_02_VALUE;
|
96 |
|
|
else if(write03 || sel03) plru <= (plru & ~(MICRO_03_MASK)) | MICRO_03_VALUE;
|
97 |
|
|
end
|
98 |
|
|
|
99 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro00 <= 51'd0; else if(micro_flush_do) micro00 <= 51'd0; else if(write00) micro00 <= { 1'b1, micro_write_value }; end
|
100 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro01 <= 51'd0; else if(micro_flush_do) micro01 <= 51'd0; else if(write01) micro01 <= { 1'b1, micro_write_value }; end
|
101 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro02 <= 51'd0; else if(micro_flush_do) micro02 <= 51'd0; else if(write02) micro02 <= { 1'b1, micro_write_value }; end
|
102 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro03 <= 51'd0; else if(micro_flush_do) micro03 <= 51'd0; else if(write03) micro03 <= { 1'b1, micro_write_value }; end
|
103 |
|
|
|
104 |
|
|
endmodule
|