// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: axis_tlb_mon.v // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ `ifdef CORE_0 module itlb_wr_c0 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 0; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC0.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC0.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC0.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC0.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC0.ifu_ftu.itc_demap_context; assign demap_real = `SPC0.ifu_ftu.itc_demap_real; assign demap_all = `SPC0.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC0.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC0.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC0.tlu.trl1.take_itw & `SPC0.tlu.trl1.trap[3]), (`SPC0.tlu.trl1.take_itw & `SPC0.tlu.trl1.trap[2]), (`SPC0.tlu.trl1.take_itw & `SPC0.tlu.trl1.trap[1]), (`SPC0.tlu.trl1.take_itw & `SPC0.tlu.trl1.trap[0]), (`SPC0.tlu.trl0.take_itw & `SPC0.tlu.trl0.trap[3]), (`SPC0.tlu.trl0.take_itw & `SPC0.tlu.trl0.trap[2]), (`SPC0.tlu.trl0.take_itw & `SPC0.tlu.trl0.trap[1]), (`SPC0.tlu.trl0.take_itw & `SPC0.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC0.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC0.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC0.mmu.asd1.asi_wr_itlb_data_access, `SPC0.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC0.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC0.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC0.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC0.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC0.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c0 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 0; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC0.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC0.mmu_reload_done; assign wr_en = `SPC0.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC0.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC0.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC0.lsu.tlc_demap_context; assign demap_real = `SPC0.lsu.tlc_demap_real; assign demap_all = `SPC0.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC0.lsu.tlc_wr_u_en; assign demap_tid = `SPC0.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC0.lsu.tlb.array.cam.valid; assign tlb_match = `SPC0.lsu.tlb.array.cam.match; assign tte_va = {`SPC0.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC0.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC0.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC0.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC0.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC0.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC0.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC0.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC0.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC0.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC0.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC0.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC0.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC0.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC0.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC0.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC0.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC0.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC0.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_1 module itlb_wr_c1 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 1; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC1.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC1.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC1.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC1.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC1.ifu_ftu.itc_demap_context; assign demap_real = `SPC1.ifu_ftu.itc_demap_real; assign demap_all = `SPC1.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC1.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC1.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC1.tlu.trl1.take_itw & `SPC1.tlu.trl1.trap[3]), (`SPC1.tlu.trl1.take_itw & `SPC1.tlu.trl1.trap[2]), (`SPC1.tlu.trl1.take_itw & `SPC1.tlu.trl1.trap[1]), (`SPC1.tlu.trl1.take_itw & `SPC1.tlu.trl1.trap[0]), (`SPC1.tlu.trl0.take_itw & `SPC1.tlu.trl0.trap[3]), (`SPC1.tlu.trl0.take_itw & `SPC1.tlu.trl0.trap[2]), (`SPC1.tlu.trl0.take_itw & `SPC1.tlu.trl0.trap[1]), (`SPC1.tlu.trl0.take_itw & `SPC1.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC1.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC1.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC1.mmu.asd1.asi_wr_itlb_data_access, `SPC1.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC1.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC1.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC1.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC1.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC1.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c1 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 1; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC1.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC1.mmu_reload_done; assign wr_en = `SPC1.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC1.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC1.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC1.lsu.tlc_demap_context; assign demap_real = `SPC1.lsu.tlc_demap_real; assign demap_all = `SPC1.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC1.lsu.tlc_wr_u_en; assign demap_tid = `SPC1.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC1.lsu.tlb.array.cam.valid; assign tlb_match = `SPC1.lsu.tlb.array.cam.match; assign tte_va = {`SPC1.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC1.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC1.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC1.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC1.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC1.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC1.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC1.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC1.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC1.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC1.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC1.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC1.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC1.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC1.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC1.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC1.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC1.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC1.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_2 module itlb_wr_c2 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 2; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC2.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC2.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC2.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC2.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC2.ifu_ftu.itc_demap_context; assign demap_real = `SPC2.ifu_ftu.itc_demap_real; assign demap_all = `SPC2.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC2.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC2.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC2.tlu.trl1.take_itw & `SPC2.tlu.trl1.trap[3]), (`SPC2.tlu.trl1.take_itw & `SPC2.tlu.trl1.trap[2]), (`SPC2.tlu.trl1.take_itw & `SPC2.tlu.trl1.trap[1]), (`SPC2.tlu.trl1.take_itw & `SPC2.tlu.trl1.trap[0]), (`SPC2.tlu.trl0.take_itw & `SPC2.tlu.trl0.trap[3]), (`SPC2.tlu.trl0.take_itw & `SPC2.tlu.trl0.trap[2]), (`SPC2.tlu.trl0.take_itw & `SPC2.tlu.trl0.trap[1]), (`SPC2.tlu.trl0.take_itw & `SPC2.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC2.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC2.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC2.mmu.asd1.asi_wr_itlb_data_access, `SPC2.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC2.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC2.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC2.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC2.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC2.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c2 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 2; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC2.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC2.mmu_reload_done; assign wr_en = `SPC2.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC2.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC2.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC2.lsu.tlc_demap_context; assign demap_real = `SPC2.lsu.tlc_demap_real; assign demap_all = `SPC2.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC2.lsu.tlc_wr_u_en; assign demap_tid = `SPC2.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC2.lsu.tlb.array.cam.valid; assign tlb_match = `SPC2.lsu.tlb.array.cam.match; assign tte_va = {`SPC2.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC2.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC2.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC2.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC2.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC2.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC2.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC2.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC2.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC2.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC2.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC2.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC2.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC2.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC2.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC2.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC2.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC2.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC2.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_3 module itlb_wr_c3 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 3; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC3.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC3.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC3.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC3.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC3.ifu_ftu.itc_demap_context; assign demap_real = `SPC3.ifu_ftu.itc_demap_real; assign demap_all = `SPC3.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC3.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC3.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC3.tlu.trl1.take_itw & `SPC3.tlu.trl1.trap[3]), (`SPC3.tlu.trl1.take_itw & `SPC3.tlu.trl1.trap[2]), (`SPC3.tlu.trl1.take_itw & `SPC3.tlu.trl1.trap[1]), (`SPC3.tlu.trl1.take_itw & `SPC3.tlu.trl1.trap[0]), (`SPC3.tlu.trl0.take_itw & `SPC3.tlu.trl0.trap[3]), (`SPC3.tlu.trl0.take_itw & `SPC3.tlu.trl0.trap[2]), (`SPC3.tlu.trl0.take_itw & `SPC3.tlu.trl0.trap[1]), (`SPC3.tlu.trl0.take_itw & `SPC3.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC3.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC3.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC3.mmu.asd1.asi_wr_itlb_data_access, `SPC3.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC3.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC3.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC3.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC3.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC3.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c3 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 3; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC3.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC3.mmu_reload_done; assign wr_en = `SPC3.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC3.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC3.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC3.lsu.tlc_demap_context; assign demap_real = `SPC3.lsu.tlc_demap_real; assign demap_all = `SPC3.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC3.lsu.tlc_wr_u_en; assign demap_tid = `SPC3.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC3.lsu.tlb.array.cam.valid; assign tlb_match = `SPC3.lsu.tlb.array.cam.match; assign tte_va = {`SPC3.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC3.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC3.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC3.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC3.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC3.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC3.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC3.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC3.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC3.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC3.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC3.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC3.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC3.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC3.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC3.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC3.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC3.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC3.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_4 module itlb_wr_c4 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 4; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC4.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC4.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC4.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC4.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC4.ifu_ftu.itc_demap_context; assign demap_real = `SPC4.ifu_ftu.itc_demap_real; assign demap_all = `SPC4.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC4.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC4.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC4.tlu.trl1.take_itw & `SPC4.tlu.trl1.trap[3]), (`SPC4.tlu.trl1.take_itw & `SPC4.tlu.trl1.trap[2]), (`SPC4.tlu.trl1.take_itw & `SPC4.tlu.trl1.trap[1]), (`SPC4.tlu.trl1.take_itw & `SPC4.tlu.trl1.trap[0]), (`SPC4.tlu.trl0.take_itw & `SPC4.tlu.trl0.trap[3]), (`SPC4.tlu.trl0.take_itw & `SPC4.tlu.trl0.trap[2]), (`SPC4.tlu.trl0.take_itw & `SPC4.tlu.trl0.trap[1]), (`SPC4.tlu.trl0.take_itw & `SPC4.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC4.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC4.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC4.mmu.asd1.asi_wr_itlb_data_access, `SPC4.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC4.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC4.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC4.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC4.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC4.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c4 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 4; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC4.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC4.mmu_reload_done; assign wr_en = `SPC4.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC4.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC4.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC4.lsu.tlc_demap_context; assign demap_real = `SPC4.lsu.tlc_demap_real; assign demap_all = `SPC4.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC4.lsu.tlc_wr_u_en; assign demap_tid = `SPC4.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC4.lsu.tlb.array.cam.valid; assign tlb_match = `SPC4.lsu.tlb.array.cam.match; assign tte_va = {`SPC4.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC4.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC4.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC4.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC4.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC4.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC4.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC4.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC4.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC4.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC4.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC4.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC4.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC4.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC4.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC4.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC4.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC4.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC4.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_5 module itlb_wr_c5 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 5; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC5.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC5.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC5.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC5.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC5.ifu_ftu.itc_demap_context; assign demap_real = `SPC5.ifu_ftu.itc_demap_real; assign demap_all = `SPC5.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC5.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC5.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC5.tlu.trl1.take_itw & `SPC5.tlu.trl1.trap[3]), (`SPC5.tlu.trl1.take_itw & `SPC5.tlu.trl1.trap[2]), (`SPC5.tlu.trl1.take_itw & `SPC5.tlu.trl1.trap[1]), (`SPC5.tlu.trl1.take_itw & `SPC5.tlu.trl1.trap[0]), (`SPC5.tlu.trl0.take_itw & `SPC5.tlu.trl0.trap[3]), (`SPC5.tlu.trl0.take_itw & `SPC5.tlu.trl0.trap[2]), (`SPC5.tlu.trl0.take_itw & `SPC5.tlu.trl0.trap[1]), (`SPC5.tlu.trl0.take_itw & `SPC5.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC5.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC5.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC5.mmu.asd1.asi_wr_itlb_data_access, `SPC5.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC5.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC5.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC5.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC5.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC5.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c5 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 5; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC5.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC5.mmu_reload_done; assign wr_en = `SPC5.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC5.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC5.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC5.lsu.tlc_demap_context; assign demap_real = `SPC5.lsu.tlc_demap_real; assign demap_all = `SPC5.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC5.lsu.tlc_wr_u_en; assign demap_tid = `SPC5.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC5.lsu.tlb.array.cam.valid; assign tlb_match = `SPC5.lsu.tlb.array.cam.match; assign tte_va = {`SPC5.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC5.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC5.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC5.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC5.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC5.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC5.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC5.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC5.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC5.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC5.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC5.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC5.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC5.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC5.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC5.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC5.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC5.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC5.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_6 module itlb_wr_c6 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 6; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC6.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC6.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC6.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC6.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC6.ifu_ftu.itc_demap_context; assign demap_real = `SPC6.ifu_ftu.itc_demap_real; assign demap_all = `SPC6.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC6.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC6.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC6.tlu.trl1.take_itw & `SPC6.tlu.trl1.trap[3]), (`SPC6.tlu.trl1.take_itw & `SPC6.tlu.trl1.trap[2]), (`SPC6.tlu.trl1.take_itw & `SPC6.tlu.trl1.trap[1]), (`SPC6.tlu.trl1.take_itw & `SPC6.tlu.trl1.trap[0]), (`SPC6.tlu.trl0.take_itw & `SPC6.tlu.trl0.trap[3]), (`SPC6.tlu.trl0.take_itw & `SPC6.tlu.trl0.trap[2]), (`SPC6.tlu.trl0.take_itw & `SPC6.tlu.trl0.trap[1]), (`SPC6.tlu.trl0.take_itw & `SPC6.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC6.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC6.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC6.mmu.asd1.asi_wr_itlb_data_access, `SPC6.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC6.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC6.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC6.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC6.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC6.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c6 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 6; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC6.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC6.mmu_reload_done; assign wr_en = `SPC6.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC6.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC6.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC6.lsu.tlc_demap_context; assign demap_real = `SPC6.lsu.tlc_demap_real; assign demap_all = `SPC6.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC6.lsu.tlc_wr_u_en; assign demap_tid = `SPC6.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC6.lsu.tlb.array.cam.valid; assign tlb_match = `SPC6.lsu.tlb.array.cam.match; assign tte_va = {`SPC6.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC6.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC6.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC6.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC6.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC6.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC6.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC6.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC6.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC6.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC6.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC6.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC6.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC6.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC6.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC6.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC6.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC6.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC6.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //---------------------------------------------------------- `ifdef CORE_7 module itlb_wr_c7 (dbg_in); `ifndef GATESIM parameter NUM_TLB=64; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; wire [7:0] asi_wr_itlb; wire [7:0] asi_wr_itlb_demap; wire [7:0] asi_wr_itlb_data_in; wire [7:0] asi_wr_itlb_data_access; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; reg [(`TS_WIDTH-1):0] demap_tstamp; reg dbg_en; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 7; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC7.mmu.asi.htc_wr_itlb_data_in; assign wr_en = `SPC7.ifu_ftu.ftu_itb_cust.tlb_wr_1_in_dout; assign entry = `SPC7.ifu_ftu.ftu_itb_cust.rw_index_1[5:0]; assign demap_page = `SPC7.ifu_ftu.ftu_itc_ctl.itc_demap_page; assign demap_context = `SPC7.ifu_ftu.itc_demap_context; assign demap_real = `SPC7.ifu_ftu.itc_demap_real; assign demap_all = `SPC7.ifu_ftu.itc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap = `SPC7.ifu_ftu.itc_wr_u_en; assign demap_tid = `SPC7.ifu_ftu.ftu_itd_dp.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; wire [7:0] itlb_wr = {(`SPC7.tlu.trl1.take_itw & `SPC7.tlu.trl1.trap[3]), (`SPC7.tlu.trl1.take_itw & `SPC7.tlu.trl1.trap[2]), (`SPC7.tlu.trl1.take_itw & `SPC7.tlu.trl1.trap[1]), (`SPC7.tlu.trl1.take_itw & `SPC7.tlu.trl1.trap[0]), (`SPC7.tlu.trl0.take_itw & `SPC7.tlu.trl0.trap[3]), (`SPC7.tlu.trl0.take_itw & `SPC7.tlu.trl0.trap[2]), (`SPC7.tlu.trl0.take_itw & `SPC7.tlu.trl0.trap[1]), (`SPC7.tlu.trl0.take_itw & `SPC7.tlu.trl0.trap[0]) }; assign tlb_wr = itlb_wr; // Signals that are early indication that TLBWRITE or TLBWRITE(demap) will happen. // Once these signals assert, the write to the TLB cannot be cancelled. // These signals assert before the MMU reorders the TLB writes. // Use these to suppress SSTEP in nas_pipe. // Best case, these signals assert 1 cycle after the previous SSTEP. assign asi_wr_itlb_demap = `SPC7.mmu.asi_wr_immu_demap; assign asi_wr_itlb_data_in = `SPC7.mmu.asi_wr_itlb_data_in; assign asi_wr_itlb_data_access = {`SPC7.mmu.asd1.asi_wr_itlb_data_access, `SPC7.mmu.asd0.asi_wr_itlb_data_access}; assign asi_wr_itlb = asi_wr_itlb_demap | asi_wr_itlb_data_in | asi_wr_itlb_data_access; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_64x59_cust_l/n2_tlb_tl_64x59_cust/rtl // n2_tlb_tl_64x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_64x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC7.ifu_ftu.ftu_itb_cust.array.cam.valid; assign tlb_match = `SPC7.ifu_ftu.ftu_itb_cust.array.cam.match; assign tte_va = {`SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_47:`VA_28], `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_27:`VA_22], `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_21:`VA_16], `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC7.ifu_ftu.ftu_itb_cust.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC7.ifu_ftu.ftu_itb_cust.tte_page_size_mask_1; assign tte_pa = {`SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_IE]; assign tte_cp = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_CP]; assign tte_e = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_X]; assign tte_p = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_P]; assign tte_w = `SPC7.ifu_ftu.ftu_itb_cust.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // not stored in array, but implied as 1 //---------------------------------------------------------- initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; data_in_ready = 8'b0; end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back ITLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1() should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: ITLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. if ((tlb_wr!=8'b0) || (data_in!=8'b0)) begin // { for (i=0;i<=7;i=i+1) begin // { if ((data_in[i])&&(tlb_wr[i])) begin // { $display ("tlb_sync", `ERROR, "Bad Inputs - iwr_data_in & iwr_tlb_wr should not be asserted at same time"); end // } else begin // { // data_in[tid] determines if the write is HWTW or TLBWRITE if (data_in[i]) begin // { data_in_ready[i] <= 1'b1; end // } // tlb_wr[tid] determines which thread will write next // Use fifo to save the tids of the tlb_wr signals in order if (tlb_wr[i]) begin // { if (data_in_ready[i]) begin // { hwtw <= 1'b1; mytid[2:0] <= i[2:0]; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} mytid[2:0] <= i[2:0]; end // } end // } end // if} end // for} end // if} //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); end begin // axis tbcall_region if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); end begin // axis tbcall_region case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: ITLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=%b W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_ep,tte_w,tstamp*`TOP.core_period); end end // } //-------------------- end // } end // always} `endif //---------------------------------------------------------- endmodule module dtlb_wr_c7 (dbg_in); `ifndef GATESIM parameter NUM_TLB=128; wire [7:0] data_in; wire [7:0] tlb_wr; wire wr_en; wire [7:0] entry; wire [7:0] asi_num; wire asi_enable0; // 1 per thread group wire asi_enable1; // wire [7:0] store_asi; // 1 per thread wire [3:0] demap; reg [3:0] demap_1; wire demap_page; wire demap_context; wire demap_real; wire demap_all; wire skip_demap; wire demap_active; wire auto_demap; wire [2:0] demap_tid; reg [2:0] demap_tid_1; reg [5:0] demap_tnum_1; input dbg_in; reg [(`TS_WIDTH-1):0] tstamp; reg hwtw; // reg [7:0] my_asi [0:7]; // 1 asi number stored per thread reg [(`TS_WIDTH-1):0] demap_tstamp; reg [2:0] mytid; reg [5:0] mytnum; wire [2:0] mycid; integer junk; integer i; reg [7:0] cnt; assign mycid = 7; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread //fifo fifo (); // Define fifo parameters `ifndef PALLADIUM defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; `endif //---------------------------------------------------------- // DUT probes assign data_in = `SPC7.mmu.asi.wrote_dtlb; assign tlb_wr = `SPC7.mmu_reload_done; assign wr_en = `SPC7.lsu.tlb.tlb_wr_1_in_dout; assign entry = `SPC7.lsu.tlb.rw_index_1[6:0]; // assign asi_num = `PROBES0.asi_num; // assign asi_enable0 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls0.lsu_inst_b; //assign asi_enable1 = `PROBES0.tlb_rd_vld_b & // !`PROBES0.tlb_bypass_b & // `SPC0.tlu.fls1.lsu_inst_b; // assign store_asi[3:0] = asi_enable0 ? `PROBES0.select_pc_b[3:0] : 4'b0; // assign store_asi[7:4] = asi_enable1 ? `PROBES0.select_pc_b[7:4] : 4'b0; assign demap_page = `SPC7.lsu.tlc_demap & ~(demap_context | demap_real | demap_all); assign demap_context = `SPC7.lsu.tlc_demap_context; assign demap_real = `SPC7.lsu.tlc_demap_real; assign demap_all = `SPC7.lsu.tlc_demap_all; assign demap = {demap_all,demap_page,demap_context,demap_real}; assign skip_demap =`SPC7.lsu.tlc_wr_u_en; assign demap_tid = `SPC7.lsu.tld.tte1[37:35]; // if (|demap_1 && skip_demap ), then Implicit demap so don't send to NAS assign demap_active = |demap_1 && !skip_demap; assign auto_demap = |demap_1 && skip_demap; //--------------------- // Probes for debugging // defines copied from :/libs/n2sram/tlbs/tlbs/n2_tlb_tl_128x59_cust_l/n2_tlb_tl_128x59_cust/rtl // n2_tlb_tl_128x59_cam.sv `define CNTX1_HI 65 `define CNTX1_LO 53 `define PID_HI 52 `define PID_LO 50 `define REAL_BIT 49 `define VA_47 48 `define VA_28 29 `define VA_27 28 `define VA_22 23 `define TTE_VALID 22 `define VA_21 21 `define VA_16 16 `define VA_15 15 `define VA_13 13 `define CNTX0_HI 12 `define CNTX0_LO 0 // n2_tlb_tl_128x59_ram.sv `define DATA_PARITY 36 `define DATA_PA_39_28_HI 35 `define DATA_PA_39_28_LO 24 `define DATA_PA_27_22_HI 23 `define DATA_PA_27_22_LO 18 `define DATA_VA_27_22_V 17 `define DATA_PA_21_16_HI 16 `define DATA_PA_21_16_LO 11 `define DATA_VA_21_16_V 10 `define DATA_PA_15_13_HI 9 `define DATA_PA_15_13_LO 7 `define DATA_VA_15_13_V 6 `define DATA_NFO 5 `define DATA_IE 4 `define DATA_CP 3 `define DATA_X 2 `define DATA_P 1 `define DATA_W 0 wire [(NUM_TLB-1):0] tlb_valid; wire [(NUM_TLB-1):0] tlb_match; wire tte_valid; wire [47:0] tte_va; wire [12:0] tte_context; wire tte_real; wire [2:0] tte_pid; wire [2:0] tte_page_mask; wire [39:0] tte_pa; wire tte_nfo; wire tte_ie; wire tte_cp; wire tte_e; wire tte_p; wire tte_w; wire tte_ep; assign tlb_valid = `SPC7.lsu.tlb.array.cam.valid; assign tlb_match = `SPC7.lsu.tlb.array.cam.match; assign tte_va = {`SPC7.lsu.tlb.tte_tag_1_dout[`VA_47:`VA_28], `SPC7.lsu.tlb.tte_tag_1_dout[`VA_27:`VA_22], `SPC7.lsu.tlb.tte_tag_1_dout[`VA_21:`VA_16], `SPC7.lsu.tlb.tte_tag_1_dout[`VA_15:`VA_13], 13'b0 }; assign tte_context = `SPC7.lsu.tlb.tte_tag_1_dout[`CNTX1_HI:`CNTX1_LO]; assign tte_pid = `SPC7.lsu.tlb.tte_tag_1_dout[`PID_HI:`PID_LO]; assign tte_real = `SPC7.lsu.tlb.tte_tag_1_dout[`REAL_BIT]; assign tte_valid = `SPC7.lsu.tlb.tte_tag_1_dout[`TTE_VALID]; assign tte_page_mask = `SPC7.lsu.tlb.tte_page_size_mask_1; assign tte_pa = {`SPC7.lsu.tlb.tte_data_1[`DATA_PA_39_28_HI:`DATA_PA_39_28_LO], `SPC7.lsu.tlb.tte_data_1[`DATA_PA_27_22_HI:`DATA_PA_27_22_LO], `SPC7.lsu.tlb.tte_data_1[`DATA_PA_21_16_HI:`DATA_PA_21_16_LO], `SPC7.lsu.tlb.tte_data_1[`DATA_PA_15_13_HI:`DATA_PA_15_13_LO], 13'b0 }; assign tte_nfo = `SPC7.lsu.tlb.tte_data_1[`DATA_NFO]; assign tte_ie = `SPC7.lsu.tlb.tte_data_1[`DATA_IE]; assign tte_cp = `SPC7.lsu.tlb.tte_data_1[`DATA_CP]; assign tte_e = `SPC7.lsu.tlb.tte_data_1[`DATA_X]; assign tte_p = `SPC7.lsu.tlb.tte_data_1[`DATA_P]; assign tte_w = `SPC7.lsu.tlb.tte_data_1[`DATA_W]; assign tte_ep = 1'b1; // Does not apply for DTLB //---------------------------------------------------------- // Initialize state machine to idle state initial begin // { `ifndef PALLADIUM #1; `endif hwtw = 1'b0; //for (i=0; i<=7; i=i+1) begin // my_asi[i] = 8'b0; //end end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_entry_replace (aka entry) is created in always block using blocking assignments always @ (negedge `CPU.l2clk) begin // { tstamp = `TOP.cycle; demap_tstamp = `TOP.cycle; // Delay by 1 cycle to align with skip_demap demap_tid_1 <= demap_tid; // demap_tid is active when demap is asserted demap_tnum_1 <= (mycid * 8) + demap_tid; demap_1 <= demap; //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { $display("tlb_sync", `ERROR, "C%0d T%0d Illegal Back to Back DTLB demap", mycid,demap_tid_1); end // } //if (demap_active) begin // { // fifo.pop_fifo ({hwtw,mytid}); //end //} //-------------------- if (dbg_in & (|demap_1)) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); end if (demap_active) begin begin // axis tbcall_region case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: $display ("tlb_sync", `ERROR, "Bench Problem - demap_1 should be one-hot."); // "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end end else begin begin // axis tbcall_region $write ("type=autodemap "); end end begin // axis tbcall_region $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); end for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { begin // axis tbcall_region $display ("SHOW_TLB: DTLB_DEMAP C%0d T%0d entry=%h V=0 ts=%0d", mycid,demap_tid_1,cnt,demap_tstamp*`TOP.core_period); end end // } end // } //-------------------- end // } //---------------------------------------------------------- // Send I/DHWTW due to HWTW // Send I/DTLBWRITE due to ASI write // Save asi num when DTLBREAD happens. // Otherwise, hold state. // Send asi num later with DHWTW // for (i=0;i<=7;i=i+1) begin // { // my_asi[i] = (store_asi[i]) ? asi_num : my_asi[i]; // end // } // There are 3 main signals to watch for TLBWRITE (data_in, tlb_wr, wr_en) // These signals will be interleaved between the threads. // Need to queue up the signals over time so they can be processed in order. // Each thread will only be doing 1 thing at a time. for (i=0;i<=7;i=i+1) begin // { // tlb_wr[tid] determines if the write is HWTW or TLBWRITE // data_in[tid] determines which thread will write next // Use fifo to save the tids of the data_in signals in order if (data_in[i]) begin // { mytid[2:0] <= i[2:0]; if (tlb_wr[i]) begin // { hwtw <= 1'b1; //fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} end // } else begin // { hwtw <= 1'b0; //fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[2:0]} end // } end // } end // } //---------------------------------------------------------- // wr_en means that the write is occurring if (wr_en) begin // { //fifo.pop_fifo ({hwtw,mytid}); mytnum = (mycid * 8) + mytid; //-------------------- if (dbg_in) begin // { begin // axis tbcall_region $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); if (tte_real==0) $write ("entry=%h V=%b VA=%h ",entry,tte_valid,tte_va); else $write ("entry=%h V=%b RA=%h ",entry,tte_valid,tte_va); case (tte_page_mask) 3'b000: $write("R=%b CNTX=%h PID=%h sz=8k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b001: $write("R=%b CNTX=%h PID=%h sz=64k ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b011: $write("R=%b CNTX=%h PID=%h sz=4MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); 3'b111: $write("R=%b CNTX=%h PID=%h sz=256MB ts=%0d", tte_real,tte_context,tte_pid,tstamp*`TOP.core_period); endcase if (hwtw) $display (" (hwtw)"); else $display (""); $write ("SHOW_TLB: DTLB_WRITE C%0d T%0d ",mycid,mytid); $display (" PA=00%h P=%b IE=%b CP=%b NFO=%b E=%b EP=X W=%b ts=%0d", tte_pa,tte_p,tte_ie,tte_cp,tte_nfo,tte_e,tte_w,tstamp*`TOP.core_period); end // } //-------------------- end // } end // } end // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //----------------------------------------------------------