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_tlb_ram(
|
11 |
|
|
input clk,
|
12 |
|
|
input rst_n,
|
13 |
|
|
|
14 |
|
|
//
|
15 |
|
|
input tlb_ram_read_do,
|
16 |
|
|
input [5:0] tlb_ram_read_index,
|
17 |
|
|
output reg tlb_ram_read_result_ready,
|
18 |
|
|
output [49:0] tlb_ram_read_result,
|
19 |
|
|
|
20 |
|
|
//
|
21 |
|
|
input tlb_ram_write_do,
|
22 |
|
|
input [5:0] tlb_ram_write_index,
|
23 |
|
|
input [49:0] tlb_ram_write_value,
|
24 |
|
|
|
25 |
|
|
//
|
26 |
|
|
input [5:0] entryhi_asid,
|
27 |
|
|
|
28 |
|
|
//
|
29 |
|
|
input tlb_ram_data_start,
|
30 |
|
|
input [19:0] tlb_ram_data_vpn,
|
31 |
|
|
output reg tlb_ram_data_hit,
|
32 |
|
|
output reg [5:0] tlb_ram_data_index,
|
33 |
|
|
output reg [49:0] tlb_ram_data_result,
|
34 |
|
|
output tlb_ram_data_missed,
|
35 |
|
|
|
36 |
|
|
//
|
37 |
|
|
input tlb_ram_fetch_start,
|
38 |
|
|
input [19:0] tlb_ram_fetch_vpn,
|
39 |
|
|
output reg tlb_ram_fetch_hit,
|
40 |
|
|
output reg [49:0] tlb_ram_fetch_result,
|
41 |
|
|
output tlb_ram_fetch_missed
|
42 |
|
|
); /* verilator public_module */
|
43 |
|
|
|
44 |
|
|
//------------------------------------------------------------------------------
|
45 |
|
|
|
46 |
|
|
/*
|
47 |
|
|
[19:0] vpn
|
48 |
|
|
[39:20] pfn
|
49 |
|
|
[45:40] asid
|
50 |
|
|
[46] n noncachable
|
51 |
|
|
[47] d dirty = write-enable
|
52 |
|
|
[48] v valid
|
53 |
|
|
[49] g global
|
54 |
|
|
*/
|
55 |
|
|
|
56 |
|
|
//------------------------------------------------------------------------------
|
57 |
|
|
|
58 |
|
|
reg invalid_ram_q;
|
59 |
|
|
always @(posedge clk or negedge rst_n) begin
|
60 |
|
|
if(rst_n == 1'b0) invalid_ram_q <= `FALSE;
|
61 |
|
|
else invalid_ram_q <= tlb_ram_read_do || tlb_ram_write_do;
|
62 |
|
|
end
|
63 |
|
|
|
64 |
|
|
always @(posedge clk or negedge rst_n) begin
|
65 |
|
|
if(rst_n == 1'b0) tlb_ram_read_result_ready <= `FALSE;
|
66 |
|
|
else tlb_ram_read_result_ready <= tlb_ram_read_do;
|
67 |
|
|
end
|
68 |
|
|
|
69 |
|
|
//------------------------------------------------------------------------------
|
70 |
|
|
|
71 |
|
|
reg [2:0] index;
|
72 |
|
|
always @(posedge clk or negedge rst_n) begin
|
73 |
|
|
if(rst_n == 1'b0) index <= 3'd0;
|
74 |
|
|
else index <= index_next;
|
75 |
|
|
end
|
76 |
|
|
|
77 |
|
|
wire [2:0] index_next = (tlb_ram_read_do || tlb_ram_write_do)? index : index + 3'd1;
|
78 |
|
|
|
79 |
|
|
wire [2:0] read_index = (tlb_ram_read_do)? tlb_ram_read_index[5:3] : index_next;
|
80 |
|
|
|
81 |
|
|
//------------------------------------------------------------------------------
|
82 |
|
|
|
83 |
|
|
wire [49:0] tlb0_q_a;
|
84 |
|
|
wire [49:0] tlb0_q_b;
|
85 |
|
|
wire [49:0] tlb1_q_a;
|
86 |
|
|
wire [49:0] tlb1_q_b;
|
87 |
|
|
wire [49:0] tlb2_q_a;
|
88 |
|
|
wire [49:0] tlb2_q_b;
|
89 |
|
|
wire [49:0] tlb3_q_a;
|
90 |
|
|
wire [49:0] tlb3_q_b;
|
91 |
|
|
|
92 |
|
|
reg [2:0] read_index_part;
|
93 |
|
|
always @(posedge clk or negedge rst_n) begin
|
94 |
|
|
if(rst_n == 1'b0) read_index_part <= 3'd0;
|
95 |
|
|
else read_index_part <= tlb_ram_read_index[2:0];
|
96 |
|
|
end
|
97 |
|
|
|
98 |
|
|
assign tlb_ram_read_result =
|
99 |
|
|
(read_index_part == 3'd0)? tlb0_q_a[49:0] :
|
100 |
|
|
(read_index_part == 3'd1)? tlb0_q_b[49:0] :
|
101 |
|
|
(read_index_part == 3'd2)? tlb1_q_a[49:0] :
|
102 |
|
|
(read_index_part == 3'd3)? tlb1_q_b[49:0] :
|
103 |
|
|
(read_index_part == 3'd4)? tlb2_q_a[49:0] :
|
104 |
|
|
(read_index_part == 3'd5)? tlb2_q_b[49:0] :
|
105 |
|
|
(read_index_part == 3'd6)? tlb3_q_a[49:0] :
|
106 |
|
|
tlb3_q_b[49:0];
|
107 |
|
|
|
108 |
|
|
//------------------------------------------------------------------------------
|
109 |
|
|
|
110 |
|
|
wire match_data0 = tlb_ram_data_vpn == tlb0_q_a[19:0] && (tlb0_q_a[49] || entryhi_asid == tlb0_q_a[45:40]);
|
111 |
|
|
wire match_data1 = tlb_ram_data_vpn == tlb0_q_b[19:0] && (tlb0_q_b[49] || entryhi_asid == tlb0_q_b[45:40]);
|
112 |
|
|
wire match_data2 = tlb_ram_data_vpn == tlb1_q_a[19:0] && (tlb1_q_a[49] || entryhi_asid == tlb1_q_a[45:40]);
|
113 |
|
|
wire match_data3 = tlb_ram_data_vpn == tlb1_q_b[19:0] && (tlb1_q_b[49] || entryhi_asid == tlb1_q_b[45:40]);
|
114 |
|
|
wire match_data4 = tlb_ram_data_vpn == tlb2_q_a[19:0] && (tlb2_q_a[49] || entryhi_asid == tlb2_q_a[45:40]);
|
115 |
|
|
wire match_data5 = tlb_ram_data_vpn == tlb2_q_b[19:0] && (tlb2_q_b[49] || entryhi_asid == tlb2_q_b[45:40]);
|
116 |
|
|
wire match_data6 = tlb_ram_data_vpn == tlb3_q_a[19:0] && (tlb3_q_a[49] || entryhi_asid == tlb3_q_a[45:40]);
|
117 |
|
|
wire match_data7 = tlb_ram_data_vpn == tlb3_q_b[19:0] && (tlb3_q_b[49] || entryhi_asid == tlb3_q_b[45:40]);
|
118 |
|
|
|
119 |
|
|
wire match_fetch0 = tlb_ram_fetch_vpn == tlb0_q_a[19:0] && (tlb0_q_a[49] || entryhi_asid == tlb0_q_a[45:40]);
|
120 |
|
|
wire match_fetch1 = tlb_ram_fetch_vpn == tlb0_q_b[19:0] && (tlb0_q_b[49] || entryhi_asid == tlb0_q_b[45:40]);
|
121 |
|
|
wire match_fetch2 = tlb_ram_fetch_vpn == tlb1_q_a[19:0] && (tlb1_q_a[49] || entryhi_asid == tlb1_q_a[45:40]);
|
122 |
|
|
wire match_fetch3 = tlb_ram_fetch_vpn == tlb1_q_b[19:0] && (tlb1_q_b[49] || entryhi_asid == tlb1_q_b[45:40]);
|
123 |
|
|
wire match_fetch4 = tlb_ram_fetch_vpn == tlb2_q_a[19:0] && (tlb2_q_a[49] || entryhi_asid == tlb2_q_a[45:40]);
|
124 |
|
|
wire match_fetch5 = tlb_ram_fetch_vpn == tlb2_q_b[19:0] && (tlb2_q_b[49] || entryhi_asid == tlb2_q_b[45:40]);
|
125 |
|
|
wire match_fetch6 = tlb_ram_fetch_vpn == tlb3_q_a[19:0] && (tlb3_q_a[49] || entryhi_asid == tlb3_q_a[45:40]);
|
126 |
|
|
wire match_fetch7 = tlb_ram_fetch_vpn == tlb3_q_b[19:0] && (tlb3_q_b[49] || entryhi_asid == tlb3_q_b[45:40]);
|
127 |
|
|
|
128 |
|
|
wire tlb_ram_data_hit_next = (data_cnt > 4'd0) && (match_data0 || match_data1 || match_data2 || match_data3 || match_data4 || match_data5 || match_data6 || match_data7);
|
129 |
|
|
wire tlb_ram_fetch_hit_next = (fetch_cnt > 4'd0 && ~(invalid_ram_q)) && (match_fetch0 || match_fetch1 || match_fetch2 || match_fetch3 || match_fetch4 || match_fetch5 || match_fetch6 || match_fetch7);
|
130 |
|
|
|
131 |
|
|
wire [5:0] tlb_ram_data_index_next =
|
132 |
|
|
(match_data0)? { index, 3'd0 } :
|
133 |
|
|
(match_data1)? { index, 3'd1 } :
|
134 |
|
|
(match_data2)? { index, 3'd2 } :
|
135 |
|
|
(match_data3)? { index, 3'd3 } :
|
136 |
|
|
(match_data4)? { index, 3'd4 } :
|
137 |
|
|
(match_data5)? { index, 3'd5 } :
|
138 |
|
|
(match_data6)? { index, 3'd6 } :
|
139 |
|
|
{ index, 3'd7 };
|
140 |
|
|
|
141 |
|
|
wire [49:0] tlb_ram_data_result_next =
|
142 |
|
|
(match_data0)? tlb0_q_a :
|
143 |
|
|
(match_data1)? tlb0_q_b :
|
144 |
|
|
(match_data2)? tlb1_q_a :
|
145 |
|
|
(match_data3)? tlb1_q_b :
|
146 |
|
|
(match_data4)? tlb2_q_a :
|
147 |
|
|
(match_data5)? tlb2_q_b :
|
148 |
|
|
(match_data6)? tlb3_q_a :
|
149 |
|
|
tlb3_q_b;
|
150 |
|
|
|
151 |
|
|
wire [49:0] tlb_ram_fetch_result_next =
|
152 |
|
|
(match_fetch0)? tlb0_q_a :
|
153 |
|
|
(match_fetch1)? tlb0_q_b :
|
154 |
|
|
(match_fetch2)? tlb1_q_a :
|
155 |
|
|
(match_fetch3)? tlb1_q_b :
|
156 |
|
|
(match_fetch4)? tlb2_q_a :
|
157 |
|
|
(match_fetch5)? tlb2_q_b :
|
158 |
|
|
(match_fetch6)? tlb3_q_a :
|
159 |
|
|
tlb3_q_b;
|
160 |
|
|
|
161 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_hit <= `FALSE; else tlb_ram_data_hit <= tlb_ram_data_hit_next; end
|
162 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_fetch_hit <= `FALSE; else tlb_ram_fetch_hit <= tlb_ram_fetch_hit_next; end
|
163 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_index <= 6'd0; else tlb_ram_data_index <= tlb_ram_data_index_next; end
|
164 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_data_result <= 50'd0; else tlb_ram_data_result <= tlb_ram_data_result_next; end
|
165 |
|
|
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) tlb_ram_fetch_result <= 50'd0; else tlb_ram_fetch_result <= tlb_ram_fetch_result_next; end
|
166 |
|
|
|
167 |
|
|
//------------------------------------------------------------------------------
|
168 |
|
|
|
169 |
|
|
reg [3:0] data_cnt;
|
170 |
|
|
always @(posedge clk or negedge rst_n) begin
|
171 |
|
|
if(rst_n == 1'b0) data_cnt <= 4'd0;
|
172 |
|
|
else if(tlb_ram_data_start) data_cnt <= 4'd1;
|
173 |
|
|
else if(tlb_ram_data_hit) data_cnt <= 4'd0;
|
174 |
|
|
else if(data_cnt == 4'd9) data_cnt <= 4'd0;
|
175 |
|
|
else if(data_cnt > 4'd0) data_cnt <= data_cnt + 4'd1;
|
176 |
|
|
end
|
177 |
|
|
assign tlb_ram_data_missed = data_cnt == 4'd9 && ~(tlb_ram_data_hit);
|
178 |
|
|
|
179 |
|
|
//------------------------------------------------------------------------------
|
180 |
|
|
|
181 |
|
|
reg [3:0] fetch_cnt;
|
182 |
|
|
always @(posedge clk or negedge rst_n) begin
|
183 |
|
|
if(rst_n == 1'b0) fetch_cnt <= 4'd0;
|
184 |
|
|
else if(tlb_ram_fetch_start) fetch_cnt <= 4'd1;
|
185 |
|
|
else if(tlb_ram_fetch_hit) fetch_cnt <= 4'd0;
|
186 |
|
|
else if(fetch_cnt == 4'd9) fetch_cnt <= 4'd0;
|
187 |
|
|
else if(fetch_cnt > 4'd0 && ~(invalid_ram_q)) fetch_cnt <= fetch_cnt + 4'd1;
|
188 |
|
|
end
|
189 |
|
|
assign tlb_ram_fetch_missed = fetch_cnt == 4'd9 && ~(tlb_ram_fetch_hit);
|
190 |
|
|
|
191 |
|
|
//------------------------------------------------------------------------------
|
192 |
|
|
|
193 |
|
|
model_true_dual_ram #(
|
194 |
|
|
.width (50),
|
195 |
|
|
.widthad (4)
|
196 |
|
|
)
|
197 |
|
|
tlb0_inst(
|
198 |
|
|
.clk (clk),
|
199 |
|
|
|
200 |
|
|
.address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
|
201 |
|
|
.wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd0),
|
202 |
|
|
.data_a (tlb_ram_write_value),
|
203 |
|
|
.q_a (tlb0_q_a),
|
204 |
|
|
|
205 |
|
|
.address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
|
206 |
|
|
.wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd1),
|
207 |
|
|
.data_b (tlb_ram_write_value),
|
208 |
|
|
.q_b (tlb0_q_b)
|
209 |
|
|
);
|
210 |
|
|
|
211 |
|
|
model_true_dual_ram #(
|
212 |
|
|
.width (50),
|
213 |
|
|
.widthad (4)
|
214 |
|
|
)
|
215 |
|
|
tlb1_inst(
|
216 |
|
|
.clk (clk),
|
217 |
|
|
|
218 |
|
|
.address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
|
219 |
|
|
.wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd2),
|
220 |
|
|
.data_a (tlb_ram_write_value),
|
221 |
|
|
.q_a (tlb1_q_a),
|
222 |
|
|
|
223 |
|
|
.address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
|
224 |
|
|
.wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd3),
|
225 |
|
|
.data_b (tlb_ram_write_value),
|
226 |
|
|
.q_b (tlb1_q_b)
|
227 |
|
|
);
|
228 |
|
|
|
229 |
|
|
model_true_dual_ram #(
|
230 |
|
|
.width (50),
|
231 |
|
|
.widthad (4)
|
232 |
|
|
)
|
233 |
|
|
tlb2_inst(
|
234 |
|
|
.clk (clk),
|
235 |
|
|
|
236 |
|
|
.address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
|
237 |
|
|
.wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd4),
|
238 |
|
|
.data_a (tlb_ram_write_value),
|
239 |
|
|
.q_a (tlb2_q_a),
|
240 |
|
|
|
241 |
|
|
.address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
|
242 |
|
|
.wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd5),
|
243 |
|
|
.data_b (tlb_ram_write_value),
|
244 |
|
|
.q_b (tlb2_q_b)
|
245 |
|
|
);
|
246 |
|
|
|
247 |
|
|
model_true_dual_ram #(
|
248 |
|
|
.width (50),
|
249 |
|
|
.widthad (4)
|
250 |
|
|
)
|
251 |
|
|
tlb3_inst(
|
252 |
|
|
.clk (clk),
|
253 |
|
|
|
254 |
|
|
.address_a (tlb_ram_write_do? { 1'b0, tlb_ram_write_index[5:3] } : { 1'b0, read_index }),
|
255 |
|
|
.wren_a (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd6),
|
256 |
|
|
.data_a (tlb_ram_write_value),
|
257 |
|
|
.q_a (tlb3_q_a),
|
258 |
|
|
|
259 |
|
|
.address_b (tlb_ram_write_do? { 1'b1, tlb_ram_write_index[5:3] } : { 1'b1, read_index }),
|
260 |
|
|
.wren_b (tlb_ram_write_do && tlb_ram_write_index[2:0] == 3'd7),
|
261 |
|
|
.data_b (tlb_ram_write_value),
|
262 |
|
|
.q_b (tlb3_q_b)
|
263 |
|
|
);
|
264 |
|
|
|
265 |
|
|
//------------------------------------------------------------------------------
|
266 |
|
|
|
267 |
|
|
endmodule
|