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_data_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 |
|
|
reg [50:0] micro04; reg [50:0] micro05; reg [50:0] micro06; reg [50:0] micro07;
|
47 |
|
|
|
48 |
|
|
wire sel00 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro00[19:0] && micro00[50] && (micro00[49] || micro_check_asid == micro00[45:40]);
|
49 |
|
|
wire sel01 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro01[19:0] && micro01[50] && (micro01[49] || micro_check_asid == micro01[45:40]);
|
50 |
|
|
wire sel02 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro02[19:0] && micro02[50] && (micro02[49] || micro_check_asid == micro02[45:40]);
|
51 |
|
|
wire sel03 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro03[19:0] && micro03[50] && (micro03[49] || micro_check_asid == micro03[45:40]);
|
52 |
|
|
wire sel04 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro04[19:0] && micro04[50] && (micro04[49] || micro_check_asid == micro04[45:40]);
|
53 |
|
|
wire sel05 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro05[19:0] && micro05[50] && (micro05[49] || micro_check_asid == micro05[45:40]);
|
54 |
|
|
wire sel06 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro06[19:0] && micro06[50] && (micro06[49] || micro_check_asid == micro06[45:40]);
|
55 |
|
|
wire sel07 = micro_check_do && ~(micro_flush_do) && micro_check_vpn == micro07[19:0] && micro07[50] && (micro07[49] || micro_check_asid == micro07[45:40]);
|
56 |
|
|
|
57 |
|
|
assign micro_check_matched = sel00 || sel01 || sel02 || sel03 || sel04 || sel05 || sel06 || sel07;
|
58 |
|
|
|
59 |
|
|
assign micro_check_result =
|
60 |
|
|
(sel00)? micro00[49:0] :
|
61 |
|
|
(sel01)? micro01[49:0] :
|
62 |
|
|
(sel02)? micro02[49:0] :
|
63 |
|
|
(sel03)? micro03[49:0] :
|
64 |
|
|
(sel04)? micro04[49:0] :
|
65 |
|
|
(sel05)? micro05[49:0] :
|
66 |
|
|
(sel06)? micro06[49:0] :
|
67 |
|
|
micro07[49:0];
|
68 |
|
|
|
69 |
|
|
wire ena00 = `TRUE;
|
70 |
|
|
wire ena01 = ena00 && micro00[50];
|
71 |
|
|
wire ena02 = ena01 && micro01[50];
|
72 |
|
|
wire ena03 = ena02 && micro02[50];
|
73 |
|
|
wire ena04 = ena03 && micro03[50];
|
74 |
|
|
wire ena05 = ena04 && micro04[50];
|
75 |
|
|
wire ena06 = ena05 && micro05[50];
|
76 |
|
|
wire ena07 = ena06 && micro06[50];
|
77 |
|
|
wire full = ena07 && micro07[50];
|
78 |
|
|
|
79 |
|
|
wire write00 = micro_write_do && ((~(micro00[50]) && ena00) || (full && ~(plru[0]) && ~(plru[1]) && ~(plru[3])));
|
80 |
|
|
wire write01 = micro_write_do && ((~(micro01[50]) && ena01) || (full && ~(plru[0]) && ~(plru[1]) && (plru[3])));
|
81 |
|
|
wire write02 = micro_write_do && ((~(micro02[50]) && ena02) || (full && ~(plru[0]) && (plru[1]) && ~(plru[4])));
|
82 |
|
|
wire write03 = micro_write_do && ((~(micro03[50]) && ena03) || (full && ~(plru[0]) && (plru[1]) && (plru[4])));
|
83 |
|
|
wire write04 = micro_write_do && ((~(micro04[50]) && ena04) || (full && (plru[0]) && ~(plru[2]) && ~(plru[5])));
|
84 |
|
|
wire write05 = micro_write_do && ((~(micro05[50]) && ena05) || (full && (plru[0]) && ~(plru[2]) && (plru[5])));
|
85 |
|
|
wire write06 = micro_write_do && ((~(micro06[50]) && ena06) || (full && (plru[0]) && (plru[2]) && ~(plru[6])));
|
86 |
|
|
wire write07 = micro_write_do && ((~(micro07[50]) && ena07) || (full && (plru[0]) && (plru[2]) && (plru[6])));
|
87 |
|
|
|
88 |
|
|
/* Tree pseudo LRU
|
89 |
|
|
* [0]
|
90 |
|
|
* [1] [2]
|
91 |
|
|
* [3] [4] [5] [6]
|
92 |
|
|
* 0 1 2 3 4 5 6 7
|
93 |
|
|
*
|
94 |
|
|
*/
|
95 |
|
|
|
96 |
|
|
localparam [6:0] MICRO_07_MASK = 7'b1000101; //0,2,6
|
97 |
|
|
localparam [6:0] MICRO_07_VALUE = 7'b0000000; //0,2,6
|
98 |
|
|
|
99 |
|
|
localparam [6:0] MICRO_06_MASK = 7'b1000101; //0,2,6
|
100 |
|
|
localparam [6:0] MICRO_06_VALUE = 7'b1000000; //0,2,6
|
101 |
|
|
|
102 |
|
|
localparam [6:0] MICRO_05_MASK = 7'b0100101; //0,2,5
|
103 |
|
|
localparam [6:0] MICRO_05_VALUE = 7'b0000100; //0,2,5
|
104 |
|
|
|
105 |
|
|
localparam [6:0] MICRO_04_MASK = 7'b0100101; //0,2,5
|
106 |
|
|
localparam [6:0] MICRO_04_VALUE = 7'b0100100; //0,2,5
|
107 |
|
|
|
108 |
|
|
localparam [6:0] MICRO_03_MASK = 7'b0010011; //0,1,4
|
109 |
|
|
localparam [6:0] MICRO_03_VALUE = 7'b0000001; //0,1,4
|
110 |
|
|
|
111 |
|
|
localparam [6:0] MICRO_02_MASK = 7'b0010011; //0,1,4
|
112 |
|
|
localparam [6:0] MICRO_02_VALUE = 7'b0010001; //0,1,4
|
113 |
|
|
|
114 |
|
|
localparam [6:0] MICRO_01_MASK = 7'b0001011; //0,1,3
|
115 |
|
|
localparam [6:0] MICRO_01_VALUE = 7'b0000011; //0,1,3
|
116 |
|
|
|
117 |
|
|
localparam [6:0] MICRO_00_MASK = 7'b0001011; //0,1,3
|
118 |
|
|
localparam [6:0] MICRO_00_VALUE = 7'b0001011; //0,1,3
|
119 |
|
|
|
120 |
|
|
reg [6:0] plru;
|
121 |
|
|
always @(posedge clk or negedge rst_n) begin
|
122 |
|
|
if(rst_n == 1'b0) plru <= 7'd0;
|
123 |
|
|
else if(micro_flush_do) plru <= 7'd0;
|
124 |
|
|
else if(write00 || sel00) plru <= (plru & ~(MICRO_00_MASK)) | MICRO_00_VALUE;
|
125 |
|
|
else if(write01 || sel01) plru <= (plru & ~(MICRO_01_MASK)) | MICRO_01_VALUE;
|
126 |
|
|
else if(write02 || sel02) plru <= (plru & ~(MICRO_02_MASK)) | MICRO_02_VALUE;
|
127 |
|
|
else if(write03 || sel03) plru <= (plru & ~(MICRO_03_MASK)) | MICRO_03_VALUE;
|
128 |
|
|
else if(write04 || sel04) plru <= (plru & ~(MICRO_04_MASK)) | MICRO_04_VALUE;
|
129 |
|
|
else if(write05 || sel05) plru <= (plru & ~(MICRO_05_MASK)) | MICRO_05_VALUE;
|
130 |
|
|
else if(write06 || sel06) plru <= (plru & ~(MICRO_06_MASK)) | MICRO_06_VALUE;
|
131 |
|
|
else if(write07 || sel07) plru <= (plru & ~(MICRO_07_MASK)) | MICRO_07_VALUE;
|
132 |
|
|
end
|
133 |
|
|
|
134 |
|
|
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
|
135 |
|
|
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
|
136 |
|
|
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
|
137 |
|
|
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
|
138 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro04 <= 51'd0; else if(micro_flush_do) micro04 <= 51'd0; else if(write04) micro04 <= { 1'b1, micro_write_value }; end
|
139 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro05 <= 51'd0; else if(micro_flush_do) micro05 <= 51'd0; else if(write05) micro05 <= { 1'b1, micro_write_value }; end
|
140 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro06 <= 51'd0; else if(micro_flush_do) micro06 <= 51'd0; else if(write06) micro06 <= { 1'b1, micro_write_value }; end
|
141 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) micro07 <= 51'd0; else if(micro_flush_do) micro07 <= 51'd0; else if(write07) micro07 <= { 1'b1, micro_write_value }; end
|
142 |
|
|
|
143 |
|
|
endmodule
|