-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddr_trans.v
250 lines (230 loc) · 8.69 KB
/
addr_trans.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
`include "csr.h"
module addr_trans
#(
parameter TLBNUM = 32
)
(
input clk ,
input [ 9:0] asid ,
//trans mode
input inst_addr_trans_en ,
input data_addr_trans_en ,
//inst addr trans
input inst_fetch ,
input [31:0] inst_vaddr ,
input inst_dmw0_en ,
input inst_dmw1_en ,
output [ 7:0] inst_index ,
output [19:0] inst_tag ,
output [ 3:0] inst_offset ,
output inst_tlb_found ,
output inst_tlb_v ,
output inst_tlb_d ,
output [ 1:0] inst_tlb_mat ,
output [ 1:0] inst_tlb_plv ,
//data addr trans
input data_fetch ,
input [31:0] data_vaddr ,
input data_dmw0_en ,
input data_dmw1_en ,
input cacop_op_mode_di ,
output [ 7:0] data_index ,
output [19:0] data_tag ,
output [ 3:0] data_offset ,
output data_tlb_found ,
output [ 4:0] data_tlb_index ,
output data_tlb_v ,
output data_tlb_d ,
output [ 1:0] data_tlb_mat ,
output [ 1:0] data_tlb_plv ,
//tlbwi tlbwr tlb write
input tlbfill_en ,
input tlbwr_en ,
input [ 4:0] rand_index ,
input [31:0] tlbehi_in ,
input [31:0] tlbelo0_in ,
input [31:0] tlbelo1_in ,
input [31:0] tlbidx_in ,
input [ 5:0] ecode_in ,
//tlbr tlb read
output [31:0] tlbehi_out ,
output [31:0] tlbelo0_out ,
output [31:0] tlbelo1_out ,
output [31:0] tlbidx_out ,
output [ 9:0] asid_out ,
//invtlb
input invtlb_en ,
input [ 9:0] invtlb_asid ,
input [18:0] invtlb_vpn ,
input [ 4:0] invtlb_op ,
//from csr
input [31:0] csr_dmw0 ,
input [31:0] csr_dmw1 ,
input csr_da ,
input csr_pg
);
wire [18:0] s0_vppn ;
wire s0_odd_page ;
wire [ 5:0] s0_ps ;
wire [19:0] s0_ppn ;
wire [18:0] s1_vppn ;
wire s1_odd_page ;
wire [ 5:0] s1_ps ;
wire [19:0] s1_ppn ;
wire we ;
wire [ 4:0] w_index ;
wire [18:0] w_vppn ;
wire w_g ;
wire [ 5:0] w_ps ;
wire w_e ;
wire w_v0 ;
wire w_d0 ;
wire [ 1:0] w_mat0 ;
wire [ 1:0] w_plv0 ;
wire [19:0] w_ppn0 ;
wire w_v1 ;
wire w_d1 ;
wire [ 1:0] w_mat1 ;
wire [ 1:0] w_plv1 ;
wire [19:0] w_ppn1 ;
wire [ 4:0] r_index ;
wire [18:0] r_vppn ;
wire [ 9:0] r_asid ;
wire r_g ;
wire [ 5:0] r_ps ;
wire r_e ;
wire r_v0 ;
wire r_d0 ;
wire [ 1:0] r_mat0 ;
wire [ 1:0] r_plv0 ;
wire [19:0] r_ppn0 ;
wire r_v1 ;
wire r_d1 ;
wire [ 1:0] r_mat1 ;
wire [ 1:0] r_plv1 ;
wire [19:0] r_ppn1 ;
reg [31:0] inst_vaddr_buffer ;
reg [31:0] data_vaddr_buffer ;
wire [31:0] inst_paddr;
wire [31:0] data_paddr;
wire pg_mode;
wire da_mode;
always @(posedge clk) begin
if (inst_fetch) begin
inst_vaddr_buffer <= inst_vaddr;
end
if (data_fetch) begin
data_vaddr_buffer <= data_vaddr;
end
end
//trans search port sig
assign s0_vppn = inst_vaddr[31:13];
assign s0_odd_page = inst_vaddr[12];
assign s1_vppn = data_vaddr[31:13];
assign s1_odd_page = data_vaddr[12];
//trans write port sig
assign we = tlbfill_en || tlbwr_en;
assign w_index = ({5{tlbfill_en}} & rand_index) | ({5{tlbwr_en}} & tlbidx_in[`INDEX]);
assign w_vppn = tlbehi_in[`VPPN];
assign w_g = tlbelo0_in[`TLB_G] && tlbelo1_in[`TLB_G];
assign w_ps = tlbidx_in[`PS];
assign w_e = (ecode_in == 6'h3f) ? 1'b1 : !tlbidx_in[`NE];
assign w_v0 = tlbelo0_in[`TLB_V];
assign w_d0 = tlbelo0_in[`TLB_D];
assign w_plv0 = tlbelo0_in[`TLB_PLV];
assign w_mat0 = tlbelo0_in[`TLB_MAT];
assign w_ppn0 = tlbelo0_in[`TLB_PPN_EN];
assign w_v1 = tlbelo1_in[`TLB_V];
assign w_d1 = tlbelo1_in[`TLB_D];
assign w_plv1 = tlbelo1_in[`TLB_PLV];
assign w_mat1 = tlbelo1_in[`TLB_MAT];
assign w_ppn1 = tlbelo1_in[`TLB_PPN_EN];
//trans read port sig
assign r_index = tlbidx_in[`INDEX];
assign tlbehi_out = {r_vppn, 13'b0};
assign tlbelo0_out = {4'b0, r_ppn0, 1'b0, r_g, r_mat0, r_plv0, r_d0, r_v0};
assign tlbelo1_out = {4'b0, r_ppn1, 1'b0, r_g, r_mat1, r_plv1, r_d1, r_v1};
assign tlbidx_out = {!r_e, 1'b0, r_ps, 24'b0}; //note do not write index
assign asid_out = r_asid;
tlb_entry tlb_entry(
.clk (clk ),
// search port 0
.s0_fetch (inst_fetch ),
.s0_vppn (s0_vppn ),
.s0_odd_page (s0_odd_page ),
.s0_asid (asid ),
.s0_found (inst_tlb_found ),
.s0_index (),
.s0_ps (s0_ps ),
.s0_ppn (s0_ppn ),
.s0_v (inst_tlb_v ),
.s0_d (inst_tlb_d ),
.s0_mat (inst_tlb_mat ),
.s0_plv (inst_tlb_plv ),
// search port 1
.s1_fetch (data_fetch ),
.s1_vppn (s1_vppn ),
.s1_odd_page (s1_odd_page ),
.s1_asid (asid ),
.s1_found (data_tlb_found ),
.s1_index (data_tlb_index ),
.s1_ps (s1_ps ),
.s1_ppn (s1_ppn ),
.s1_v (data_tlb_v ),
.s1_d (data_tlb_d ),
.s1_mat (data_tlb_mat ),
.s1_plv (data_tlb_plv ),
// write port
.we (we ),
.w_index (w_index ),
.w_vppn (w_vppn ),
.w_asid (asid ),
.w_g (w_g ),
.w_ps (w_ps ),
.w_e (w_e ),
.w_v0 (w_v0 ),
.w_d0 (w_d0 ),
.w_plv0 (w_plv0 ),
.w_mat0 (w_mat0 ),
.w_ppn0 (w_ppn0 ),
.w_v1 (w_v1 ),
.w_d1 (w_d1 ),
.w_plv1 (w_plv1 ),
.w_mat1 (w_mat1 ),
.w_ppn1 (w_ppn1 ),
//read port
.r_index (r_index ),
.r_vppn (r_vppn ),
.r_asid (r_asid ),
.r_g (r_g ),
.r_ps (r_ps ),
.r_e (r_e ),
.r_v0 (r_v0 ),
.r_d0 (r_d0 ),
.r_mat0 (r_mat0 ),
.r_plv0 (r_plv0 ),
.r_ppn0 (r_ppn0 ),
.r_v1 (r_v1 ),
.r_d1 (r_d1 ),
.r_mat1 (r_mat1 ),
.r_plv1 (r_plv1 ),
.r_ppn1 (r_ppn1 ),
//invalid port
.inv_en (invtlb_en ),
.inv_op (invtlb_op ),
.inv_asid (invtlb_asid ),
.inv_vpn (invtlb_vpn )
);
assign pg_mode = !csr_da && csr_pg;
assign da_mode = csr_da && !csr_pg;
assign inst_paddr = (pg_mode && inst_dmw0_en) ? {csr_dmw0[`PSEG], inst_vaddr_buffer[28:0]} :
(pg_mode && inst_dmw1_en) ? {csr_dmw1[`PSEG], inst_vaddr_buffer[28:0]} : inst_vaddr_buffer;
assign inst_offset = inst_vaddr[3:0];
assign inst_index = inst_vaddr[11:4];
assign inst_tag = inst_addr_trans_en ? ((s0_ps == 6'd12) ? s0_ppn : {s0_ppn[19:10], inst_paddr[21:12]}) : inst_paddr[31:12];
assign data_paddr = (pg_mode && data_dmw0_en && !cacop_op_mode_di) ? {csr_dmw0[`PSEG], data_vaddr_buffer[28:0]} :
(pg_mode && data_dmw1_en && !cacop_op_mode_di) ? {csr_dmw1[`PSEG], data_vaddr_buffer[28:0]} : data_vaddr_buffer;
assign data_offset = data_vaddr[3:0];
assign data_index = data_vaddr[11:4];
assign data_tag = data_addr_trans_en ? ((s1_ps == 6'd12) ? s1_ppn : {s1_ppn[19:10], data_paddr[21:12]}) : data_paddr[31:12];
endmodule