236 lines
9.1 KiB
Verilog
236 lines
9.1 KiB
Verilog
module tlb_entry
|
|
#(
|
|
parameter TLBNUM = 32
|
|
)
|
|
(
|
|
input clk,
|
|
// search port 0
|
|
input s0_fetch ,
|
|
input [18:0] s0_vppn ,
|
|
input s0_odd_page ,
|
|
input [ 9:0] s0_asid ,
|
|
output s0_found ,
|
|
output [ 4:0] s0_index ,
|
|
output [ 5:0] s0_ps ,
|
|
output [19:0] s0_ppn ,
|
|
output s0_v ,
|
|
output s0_d ,
|
|
output [ 1:0] s0_mat ,
|
|
output [ 1:0] s0_plv ,
|
|
//search port 1
|
|
input s1_fetch ,
|
|
input [18:0] s1_vppn ,
|
|
input s1_odd_page ,
|
|
input [ 9:0] s1_asid ,
|
|
output s1_found ,
|
|
output [ 4:0] s1_index ,
|
|
output [ 5:0] s1_ps ,
|
|
output [19:0] s1_ppn ,
|
|
output s1_v ,
|
|
output s1_d ,
|
|
output [ 1:0] s1_mat ,
|
|
output [ 1:0] s1_plv ,
|
|
// write port
|
|
input we ,
|
|
input [$clog2(TLBNUM)-1:0] w_index ,
|
|
input [18:0] w_vppn ,
|
|
input [ 9:0] w_asid ,
|
|
input w_g ,
|
|
input [ 5:0] w_ps ,
|
|
input w_e ,
|
|
input w_v0 ,
|
|
input w_d0 ,
|
|
input [ 1:0] w_mat0 ,
|
|
input [ 1:0] w_plv0 ,
|
|
input [19:0] w_ppn0 ,
|
|
input w_v1 ,
|
|
input w_d1 ,
|
|
input [ 1:0] w_mat1 ,
|
|
input [ 1:0] w_plv1 ,
|
|
input [19:0] w_ppn1 ,
|
|
// read port
|
|
input [$clog2(TLBNUM)-1:0] r_index ,
|
|
output [18:0] r_vppn ,
|
|
output [ 9:0] r_asid ,
|
|
output r_g ,
|
|
output [ 5:0] r_ps ,
|
|
output r_e ,
|
|
output r_v0 ,
|
|
output r_d0 ,
|
|
output [ 1:0] r_mat0 ,
|
|
output [ 1:0] r_plv0 ,
|
|
output [19:0] r_ppn0 ,
|
|
output r_v1 ,
|
|
output r_d1 ,
|
|
output [ 1:0] r_mat1 ,
|
|
output [ 1:0] r_plv1 ,
|
|
output [19:0] r_ppn1 ,
|
|
// invalid port
|
|
input inv_en ,
|
|
input [ 4:0] inv_op ,
|
|
input [ 9:0] inv_asid ,
|
|
input [18:0] inv_vpn
|
|
);
|
|
|
|
reg [18:0] tlb_vppn [TLBNUM-1:0];
|
|
reg tlb_e [TLBNUM-1:0];
|
|
reg [ 9:0] tlb_asid [TLBNUM-1:0];
|
|
reg tlb_g [TLBNUM-1:0];
|
|
reg [ 5:0] tlb_ps [TLBNUM-1:0];
|
|
reg [19:0] tlb_ppn0 [TLBNUM-1:0];
|
|
reg [ 1:0] tlb_plv0 [TLBNUM-1:0];
|
|
reg [ 1:0] tlb_mat0 [TLBNUM-1:0];
|
|
reg tlb_d0 [TLBNUM-1:0];
|
|
reg tlb_v0 [TLBNUM-1:0];
|
|
reg [19:0] tlb_ppn1 [TLBNUM-1:0];
|
|
reg [ 1:0] tlb_plv1 [TLBNUM-1:0];
|
|
reg [ 1:0] tlb_mat1 [TLBNUM-1:0];
|
|
reg tlb_d1 [TLBNUM-1:0];
|
|
reg tlb_v1 [TLBNUM-1:0];
|
|
|
|
reg s0_fetch_r ;
|
|
reg [18:0] s0_vppn_r ;
|
|
reg s0_odd_page_r;
|
|
reg [ 9:0] s0_asid_r ;
|
|
reg s1_fetch_r ;
|
|
reg [18:0] s1_vppn_r ;
|
|
reg s1_odd_page_r;
|
|
reg [ 9:0] s1_asid_r ;
|
|
|
|
wire [TLBNUM-1:0] match0;
|
|
wire [TLBNUM-1:0] match1;
|
|
|
|
wire [$clog2(TLBNUM)-1:0] match0_en;
|
|
wire [$clog2(TLBNUM)-1:0] match1_en;
|
|
|
|
wire [TLBNUM-1:0] s0_odd_page_buffer;
|
|
wire [TLBNUM-1:0] s1_odd_page_buffer;
|
|
|
|
always @(posedge clk) begin
|
|
s0_fetch_r <= s0_fetch;
|
|
if (s0_fetch) begin
|
|
s0_vppn_r <= s0_vppn;
|
|
s0_odd_page_r <= s0_odd_page;
|
|
s0_asid_r <= s0_asid;
|
|
end
|
|
s1_fetch_r <= s1_fetch;
|
|
if (s1_fetch) begin
|
|
s1_vppn_r <= s1_vppn;
|
|
s1_odd_page_r <= s1_odd_page;
|
|
s1_asid_r <= s1_asid;
|
|
end
|
|
end
|
|
|
|
genvar i;
|
|
generate
|
|
for (i = 0; i < TLBNUM; i = i + 1)
|
|
begin: match
|
|
assign s0_odd_page_buffer[i] = (tlb_ps[i] == 6'd12) ? s0_odd_page_r : s0_vppn_r[8];
|
|
assign match0[i] = tlb_e[i] && ((tlb_ps[i] == 6'd12) ? s0_vppn_r == tlb_vppn[i] : s0_vppn_r[18: 9] == tlb_vppn[i][18: 9]) && ((s0_asid_r == tlb_asid[i]) || tlb_g[i]);
|
|
assign s1_odd_page_buffer[i] = (tlb_ps[i] == 6'd12) ? s1_odd_page_r : s1_vppn_r[8];
|
|
assign match1[i] = tlb_e[i] && ((tlb_ps[i] == 6'd12) ? s1_vppn_r == tlb_vppn[i] : s1_vppn_r[18: 9] == tlb_vppn[i][18: 9]) && ((s1_asid_r == tlb_asid[i]) || tlb_g[i]);
|
|
end
|
|
endgenerate
|
|
|
|
encoder_32_5 en_match0 (.in({{(32-TLBNUM){1'b0}},match0}), .out(match0_en));
|
|
encoder_32_5 en_match1 (.in({{(32-TLBNUM){1'b0}},match1}), .out(match1_en));
|
|
|
|
assign s0_found = |match0;
|
|
assign s0_index = {{(5-$clog2(TLBNUM)){1'b0}},match0_en};
|
|
assign s0_ps = tlb_ps[match0_en];
|
|
assign s0_ppn = s0_odd_page_buffer[match0_en] ? tlb_ppn1[match0_en] : tlb_ppn0[match0_en];
|
|
assign s0_v = s0_odd_page_buffer[match0_en] ? tlb_v1[match0_en] : tlb_v0[match0_en] ;
|
|
assign s0_d = s0_odd_page_buffer[match0_en] ? tlb_d1[match0_en] : tlb_d0[match0_en] ;
|
|
assign s0_mat = s0_odd_page_buffer[match0_en] ? tlb_mat1[match0_en] : tlb_mat0[match0_en];
|
|
assign s0_plv = s0_odd_page_buffer[match0_en] ? tlb_plv1[match0_en] : tlb_plv0[match0_en];
|
|
|
|
assign s1_found = |match1;
|
|
assign s1_index = {{(5-$clog2(TLBNUM)){1'b0}},match1_en};
|
|
assign s1_ps = tlb_ps[match1_en];
|
|
assign s1_ppn = s1_odd_page_buffer[match1_en] ? tlb_ppn1[match1_en] : tlb_ppn0[match1_en];
|
|
assign s1_v = s1_odd_page_buffer[match1_en] ? tlb_v1[match1_en] : tlb_v0[match1_en] ;
|
|
assign s1_d = s1_odd_page_buffer[match1_en] ? tlb_d1[match1_en] : tlb_d0[match1_en] ;
|
|
assign s1_mat = s1_odd_page_buffer[match1_en] ? tlb_mat1[match1_en] : tlb_mat0[match1_en];
|
|
assign s1_plv = s1_odd_page_buffer[match1_en] ? tlb_plv1[match1_en] : tlb_plv0[match1_en];
|
|
|
|
always @(posedge clk) begin
|
|
if (we) begin
|
|
tlb_vppn [w_index] <= w_vppn;
|
|
tlb_asid [w_index] <= w_asid;
|
|
tlb_g [w_index] <= w_g;
|
|
tlb_ps [w_index] <= w_ps;
|
|
tlb_ppn0 [w_index] <= w_ppn0;
|
|
tlb_plv0 [w_index] <= w_plv0;
|
|
tlb_mat0 [w_index] <= w_mat0;
|
|
tlb_d0 [w_index] <= w_d0;
|
|
tlb_v0 [w_index] <= w_v0;
|
|
tlb_ppn1 [w_index] <= w_ppn1;
|
|
tlb_plv1 [w_index] <= w_plv1;
|
|
tlb_mat1 [w_index] <= w_mat1;
|
|
tlb_d1 [w_index] <= w_d1;
|
|
tlb_v1 [w_index] <= w_v1;
|
|
end
|
|
end
|
|
|
|
assign r_vppn = tlb_vppn [r_index];
|
|
assign r_asid = tlb_asid [r_index];
|
|
assign r_g = tlb_g [r_index];
|
|
assign r_ps = tlb_ps [r_index];
|
|
assign r_e = tlb_e [r_index];
|
|
assign r_v0 = tlb_v0 [r_index];
|
|
assign r_d0 = tlb_d0 [r_index];
|
|
assign r_mat0 = tlb_mat0 [r_index];
|
|
assign r_plv0 = tlb_plv0 [r_index];
|
|
assign r_ppn0 = tlb_ppn0 [r_index];
|
|
assign r_v1 = tlb_v1 [r_index];
|
|
assign r_d1 = tlb_d1 [r_index];
|
|
assign r_mat1 = tlb_mat1 [r_index];
|
|
assign r_plv1 = tlb_plv1 [r_index];
|
|
assign r_ppn1 = tlb_ppn1 [r_index];
|
|
|
|
//tlb entry invalid
|
|
generate
|
|
for (i = 0; i < TLBNUM; i = i + 1)
|
|
begin: invalid_tlb_entry
|
|
always @(posedge clk) begin
|
|
if (we && (w_index == i)) begin
|
|
tlb_e[i] <= w_e;
|
|
end
|
|
else if (inv_en) begin
|
|
if (inv_op == 5'd0 || inv_op == 5'd1) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
else if (inv_op == 5'd2) begin
|
|
if (tlb_g[i]) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
end
|
|
else if (inv_op == 5'd3) begin
|
|
if (!tlb_g[i]) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
end
|
|
else if (inv_op == 5'd4) begin
|
|
if (!tlb_g[i] && (tlb_asid[i] == inv_asid)) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
end
|
|
else if (inv_op == 5'd5) begin
|
|
if (!tlb_g[i] && (tlb_asid[i] == inv_asid) &&
|
|
((tlb_ps[i] == 6'd12) ? (tlb_vppn[i] == inv_vpn) : (tlb_vppn[i][18:9] == inv_vpn[18:9]))) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
end
|
|
else if (inv_op == 5'd6) begin
|
|
if ((tlb_g[i] || (tlb_asid[i] == inv_asid)) &&
|
|
((tlb_ps[i] == 6'd12) ? (tlb_vppn[i] == inv_vpn) : (tlb_vppn[i][18:9] == inv_vpn[18:9]))) begin
|
|
tlb_e[i] <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|