`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