// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: itlb_wr.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 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 0; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC0.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES0.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC0.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC0.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC0.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_1 module itlb_wr_c1 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 1; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC1.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES1.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC1.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC1.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC1.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_2 module itlb_wr_c2 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 2; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC2.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES2.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC2.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC2.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC2.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_3 module itlb_wr_c3 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 3; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC3.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES3.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC3.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC3.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC3.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_4 module itlb_wr_c4 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 4; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC4.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES4.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC4.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC4.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC4.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_5 module itlb_wr_c5 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 5; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC5.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES5.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC5.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC5.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC5.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_6 module itlb_wr_c6 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 6; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC6.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES6.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC6.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC6.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC6.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif `ifdef CORE_7 module itlb_wr_c7 (); `ifndef GATESIM `include "tlb_sync.vh" `include "nas.vh" 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; reg [(`TS_WIDTH-1):0] tstamp; reg [7:0] data_in_ready; reg hwtw; 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; wire ready; assign mycid = 7; //---------------------------------------------------------- // Instantiate fifo - 1 entry per thread fifo fifo (); // Define fifo parameters defparam fifo.ENTRY_BITS = 4; // {hwtw,tid[2:0]} defparam fifo.DEPTH = 9; // 1 extra entry for overflow detection defparam fifo.PTR_BITS = 4; //---------------------------------------------------------- // DUT probes assign data_in = `SPC7.mmu.asi.htc_wr_itlb_data_in; assign tlb_wr = `PROBES7.itlb_wr; 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; // 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 assign ready = `PARGS.tlb_sync_on & !`SPC7.tcu_spc_mbist_start; //---------------------------------------------------------- initial begin // { #1; hwtw = 1'b0; data_in_ready = 8'b0; @ (posedge `SPC7.l2clk); end // } //---------------------------------------------------------- // Must use negedge to avoid race condition // tlb_replacement_index (aka entry) is created in always block using blocking assignments always @ (negedge (`SPC7.l2clk & ready)) begin // { tstamp = `TOP.core_cycle_cnt; demap_tstamp = `TOP.core_cycle_cnt; // 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; // Signal to nas_pipe to suppress SSTEP if (asi_wr_itlb!=8'b0) begin // for (i=0;i<=7;i=i+1) begin // { if (asi_wr_itlb[i]) begin // `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: suppress sstep. sstep_sent=1)", mycid,i,((mycid * 6'h8) + i[2:0]),tstamp); `NASTOP.sstep_sent[(mycid * 8) + i] <= 1'b1; // suppress SSTEP end // } end // } end // } //---------------------------------------------------------- // Send I/DTLBWRITE due to demap // if ((demap!=0) && (demap_1!=0)) begin // { `PR_ERROR ("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}); if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h (demap)", mycid,demap_tid_1,demap_tnum_1,demap_tstamp,8'hff); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,demap_tid_1,demap_tnum_1,tstamp); junk = $sim_send(`PLI_ITLBWRITE, demap_tnum_1,demap_tstamp,8'hff); junk = $sim_send(`PLI_SSTEP, demap_tnum_1); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[demap_tnum_1]==1) begin // { `NASTOP.sstep_early[demap_tnum_1] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end //} //-------------------- if (`PARGS.show_tlb_on & (|demap_1)) begin // { $write ("SHOW_TLB: ITLB_DEMAP C%0d T%0d ",mycid,demap_tid_1); if (demap_active) begin case (demap_1) 4'b0001: $write ("type=real "); 4'b0010: $write ("type=cntx "); 4'b0100: $write ("type=page "); 4'b1000: $write ("type=all "); default: `PR_ERROR ("tlb_sync", `ERROR, "Bench Problem - demap_1(%b) should be one-hot.",demap_1); endcase end else begin $write("type=autodemap "); end $display ("match=%h ts=%0d", tlb_match,demap_tstamp*`TOP.core_period); for (cnt=0; cnt<=NUM_TLB; cnt=cnt+1) begin // { if (tlb_match[cnt]==1'b1) begin // { $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 // } //---------------------------------------------------------- // 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 // { `PR_ERROR ("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 // { fifo.push_fifo ({1'b1,i[2:0]}); // {hwtw,tid[2:0]} data_in_ready[i] <= 1'b0; end // } else begin // { fifo.push_fifo ({1'b0,i[2:0]}); // {!hwtw,tid[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 (hwtw) begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_IHWTW tid=%d ts=%0d va=%h entry=%h", mycid,mytid,mytnum,tstamp,tte_va,entry); junk = $sim_send(`PLI_IHWTW, mytnum, tstamp,tte_va,entry); end //} end // } else begin // { if (`PARGS.nas_check_on && `PARGS.tlb_sync_on) begin // { `PR_INFO ("pli_tlb", `INFO, " C%0d T%0d PLI_ITLBWRITE tid=%d ts=%0d entry=%h", mycid,mytid,mytnum,tstamp,entry); `PR_INFO ("pli_nas", `INFO, " C%0d T%0d PLI_SSTEP tid=%d ts=%0d (tlb_sync: send SSTEP)", mycid,mytid,mytnum,tstamp); junk = $sim_send(`PLI_ITLBWRITE, mytnum,tstamp,entry); junk = $sim_send(`PLI_SSTEP, mytnum); // Check to see if sstep was sent early if (`NASTOP.sstep_sent[mytnum]==1) begin // { `NASTOP.sstep_early[mytnum] <= 1'b1; // SSTEP was sent before nas_pipe capture end //} end //} end // } //-------------------- if (`PARGS.show_tlb_on) begin // { $write ("SHOW_TLB: ITLB_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: 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 // always} //---------------------------------------------------------- `endif endmodule `endif //---------------------------------------------------------- //----------------------------------------------------------