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

Subversion Repositories aor3000

[/] [aor3000/] [trunk/] [rtl/] [memory/] [memory_tlb_ram.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
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

powered by: WebSVN 2.1.0

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