// © IBM Corp. 2020 // Licensed under the Apache License, Version 2.0 (the "License"), as modified by // the terms below; you may not use the files in this repository except in // compliance with the License as modified. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // // Modified Terms: // // 1) For the purpose of the patent license granted to you in Section 3 of the // License, the "Work" hereby includes implementations of the work of authorship // in physical form. // // 2) Notwithstanding any terms to the contrary in the License, any licenses // necessary for implementation of the Work that are available from OpenPOWER // via the Power ISA End User License Agreement (EULA) are explicitly excluded // hereunder, and may be obtained from OpenPOWER under the terms and conditions // of the EULA. // // Unless required by applicable law or agreed to in writing, the reference design // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License // for the specific language governing permissions and limitations under the License. // // Additional rights, including the ability to physically implement a softcore that // is compliant with the required sections of the Power ISA Specification, are // available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be // obtained (along with the Power ISA) here: https://openpowerfoundation.org. `timescale 1 ns / 1 ns //******************************************************************** //* //* TITLE: D-ERAT CAM Match Line Logic for Functional Model //* //* NAME: tri_cam_32x143_1r1w1c_matchline //* //********************************************************************* module tri_cam_32x143_1r1w1c_matchline( addr_in, addr_enable, comp_pgsize, pgsize_enable, entry_size, entry_cmpmask, entry_xbit, entry_xbitmask, entry_epn, comp_class, entry_class, class_enable, comp_extclass, entry_extclass, extclass_enable, comp_state, entry_hv, entry_ds, state_enable, entry_thdid, comp_thdid, thdid_enable, entry_pid, comp_pid, pid_enable, entry_v, comp_invalidate, match ); parameter HAVE_XBIT = 1; parameter NUM_PGSIZES = 5; parameter HAVE_CMPMASK = 1; parameter CMPMASK_WIDTH = 4; // @{default:nclk}@ input [0:51] addr_in; input [0:1] addr_enable; input [0:2] comp_pgsize; input pgsize_enable; input [0:2] entry_size; input [0:CMPMASK_WIDTH-1] entry_cmpmask; input entry_xbit; input [0:CMPMASK_WIDTH-1] entry_xbitmask; input [0:51] entry_epn; input [0:1] comp_class; input [0:1] entry_class; input [0:2] class_enable; input [0:1] comp_extclass; input [0:1] entry_extclass; input [0:1] extclass_enable; input [0:1] comp_state; input entry_hv; input entry_ds; input [0:1] state_enable; input [0:3] entry_thdid; input [0:3] comp_thdid; input [0:1] thdid_enable; input [0:7] entry_pid; input [0:7] comp_pid; input pid_enable; input entry_v; input comp_invalidate; output match; // tri_cam_32x143_1r1w1c_matchline //---------------------------------------------------------------------- // Signals //---------------------------------------------------------------------- wire [34:51] entry_epn_b; wire function_50_51; wire function_48_51; wire function_46_51; wire function_44_51; wire function_40_51; wire function_36_51; wire function_34_51; wire pgsize_eq_16K; wire pgsize_eq_64K; wire pgsize_eq_256K; wire pgsize_eq_1M; wire pgsize_eq_16M; wire pgsize_eq_256M; wire pgsize_eq_1G; wire pgsize_gte_16K; wire pgsize_gte_64K; wire pgsize_gte_256K; wire pgsize_gte_1M; wire pgsize_gte_16M; wire pgsize_gte_256M; wire pgsize_gte_1G; wire comp_or_34_35; wire comp_or_34_39; wire comp_or_36_39; wire comp_or_40_43; wire comp_or_44_45; wire comp_or_44_47; wire comp_or_46_47; wire comp_or_48_49; wire comp_or_48_51; wire comp_or_50_51; wire [0:72] match_line; wire pgsize_match; wire addr_match; wire class_match; wire extclass_match; wire state_match; wire thdid_match; wire pid_match; (* analysis_not_referenced="true" *) wire [0:2] unused; assign match_line[0:72] = (~({entry_epn[0:51], entry_size[0:2], entry_class[0:1], entry_extclass[0:1], entry_hv, entry_ds, entry_pid[0:7], entry_thdid[0:3]} ^ {addr_in[0:51], comp_pgsize[0:2], comp_class[0:1], comp_extclass[0:1], comp_state[0:1], comp_pid[0:7], comp_thdid[0:3]})); generate if (NUM_PGSIZES == 8) begin : numpgsz8 // tie off unused signals assign comp_or_34_39 = 1'b0; assign comp_or_44_47 = 1'b0; assign comp_or_48_51 = 1'b0; assign unused[0] = |{comp_or_34_39, comp_or_44_47, comp_or_48_51}; assign entry_epn_b[34:51] = (~(entry_epn[34:51])); if (HAVE_CMPMASK == 0) begin assign pgsize_eq_1G = ( entry_size[0] & entry_size[1] & entry_size[2]); assign pgsize_eq_256M = ( entry_size[0] & entry_size[1] & (~(entry_size[2]))); assign pgsize_eq_16M = ( entry_size[0] & (~(entry_size[1])) & entry_size[2]); assign pgsize_eq_1M = ( entry_size[0] & (~(entry_size[1])) & (~(entry_size[2]))); assign pgsize_eq_256K = ((~(entry_size[0])) & entry_size[1] & entry_size[2]); assign pgsize_eq_64K = ((~(entry_size[0])) & entry_size[1] & (~(entry_size[2]))); assign pgsize_eq_16K = ((~(entry_size[0])) & (~(entry_size[1])) & entry_size[2]); assign pgsize_gte_1G = ( entry_size[0] & entry_size[1] & entry_size[2]); assign pgsize_gte_256M = ( entry_size[0] & entry_size[1] & (~(entry_size[2]))) | pgsize_gte_1G; assign pgsize_gte_16M = ( entry_size[0] & (~(entry_size[1])) & entry_size[2]) | pgsize_gte_256M; assign pgsize_gte_1M = ( entry_size[0] & (~(entry_size[1])) & (~(entry_size[2]))) | pgsize_gte_16M; assign pgsize_gte_256K = ((~(entry_size[0])) & entry_size[1] & entry_size[2]) | pgsize_gte_1M; assign pgsize_gte_64K = ((~(entry_size[0])) & entry_size[1] & (~(entry_size[2]))) | pgsize_gte_256K; assign pgsize_gte_16K = ((~(entry_size[0])) & (~(entry_size[1])) & entry_size[2]) | pgsize_gte_64K; assign unused[1] = |{entry_cmpmask, entry_xbitmask}; end if (HAVE_CMPMASK == 1) begin // size entry_cmpmask: 0123456 // 1GB 0000000 // 256MB 1000000 // 16MB 1100000 // 1MB 1110000 // 256KB 1111000 // 64KB 1111100 // 16KB 1111110 // 4KB 1111111 assign pgsize_gte_1G = (~entry_cmpmask[0]); assign pgsize_gte_256M = (~entry_cmpmask[1]); assign pgsize_gte_16M = (~entry_cmpmask[2]); assign pgsize_gte_1M = (~entry_cmpmask[3]); assign pgsize_gte_256K = (~entry_cmpmask[4]); assign pgsize_gte_64K = (~entry_cmpmask[5]); assign pgsize_gte_16K = (~entry_cmpmask[6]); // size entry_xbitmask: 0123456 // 1GB 1000000 // 256MB 0100000 // 16MB 0010000 // 1MB 0001000 // 256KB 0000100 // 64KB 0000010 // 16KB 0000001 // 4KB 0000000 assign pgsize_eq_1G = entry_xbitmask[0]; assign pgsize_eq_256M = entry_xbitmask[1]; assign pgsize_eq_16M = entry_xbitmask[2]; assign pgsize_eq_1M = entry_xbitmask[3]; assign pgsize_eq_256K = entry_xbitmask[4]; assign pgsize_eq_64K = entry_xbitmask[5]; assign pgsize_eq_16K = entry_xbitmask[6]; assign unused[1] = 1'b0; end if (HAVE_XBIT == 0) begin assign function_34_51 = 1'b0; assign function_36_51 = 1'b0; assign function_40_51 = 1'b0; assign function_44_51 = 1'b0; assign function_46_51 = 1'b0; assign function_48_51 = 1'b0; assign function_50_51 = 1'b0; assign unused[2] = |{function_34_51, function_36_51, function_40_51, function_44_51, function_46_51, function_48_51, function_50_51, entry_xbit, entry_epn_b, pgsize_eq_1G, pgsize_eq_256M, pgsize_eq_16M, pgsize_eq_1M, pgsize_eq_256K, pgsize_eq_64K, pgsize_eq_16K}; end if (HAVE_XBIT != 0) begin assign function_34_51 = (~(entry_xbit)) | (~(pgsize_eq_1G)) | (|(entry_epn_b[34:51] & addr_in[34:51])); assign function_36_51 = (~(entry_xbit)) | (~(pgsize_eq_256M)) | (|(entry_epn_b[36:51] & addr_in[36:51])); assign function_40_51 = (~(entry_xbit)) | (~(pgsize_eq_16M)) | (|(entry_epn_b[40:51] & addr_in[40:51])); assign function_44_51 = (~(entry_xbit)) | (~(pgsize_eq_1M)) | (|(entry_epn_b[44:51] & addr_in[44:51])); assign function_46_51 = (~(entry_xbit)) | (~(pgsize_eq_256K)) | (|(entry_epn_b[46:51] & addr_in[46:51])); assign function_48_51 = (~(entry_xbit)) | (~(pgsize_eq_64K)) | (|(entry_epn_b[48:51] & addr_in[48:51])); assign function_50_51 = (~(entry_xbit)) | (~(pgsize_eq_16K)) | (|(entry_epn_b[50:51] & addr_in[50:51])); assign unused[2] = 1'b0; end assign comp_or_50_51 = (&(match_line[50:51])) | pgsize_gte_16K; assign comp_or_48_49 = (&(match_line[48:49])) | pgsize_gte_64K; assign comp_or_46_47 = (&(match_line[46:47])) | pgsize_gte_256K; assign comp_or_44_45 = (&(match_line[44:45])) | pgsize_gte_1M; assign comp_or_40_43 = (&(match_line[40:43])) | pgsize_gte_16M; assign comp_or_36_39 = (&(match_line[36:39])) | pgsize_gte_256M; assign comp_or_34_35 = (&(match_line[34:35])) | pgsize_gte_1G; if (HAVE_XBIT == 0) begin assign addr_match = (comp_or_34_35 & // Ignore functions based on page size comp_or_36_39 & comp_or_40_43 & comp_or_44_45 & comp_or_46_47 & comp_or_48_49 & comp_or_50_51 & (&(match_line[31:33])) & // Regular compare largest page size ((&(match_line[0:30])) | (~(addr_enable[1])))) | // ignored part of epn (~(addr_enable[0])); // Include address as part of compare, // should never ignore for regular compare/read. // Could ignore for compare/invalidate end if (HAVE_XBIT != 0) begin assign addr_match = (function_50_51 & // Exclusion functions function_48_51 & function_46_51 & function_44_51 & function_40_51 & function_36_51 & function_34_51 & comp_or_34_35 & // Ignore functions based on page size comp_or_36_39 & comp_or_40_43 & comp_or_44_45 & comp_or_46_47 & comp_or_48_49 & comp_or_50_51 & (&(match_line[31:33])) & // Regular compare largest page size (&(match_line[0:30]) | (~(addr_enable[1])))) | // ignored part of epn (~(addr_enable[0])); // Include address as part of compare, // should never ignore for regular compare/read. // Could ignore for compare/invalidate end end // numpgsz8: NUM_PGSIZES = 8 if (NUM_PGSIZES == 5) begin : numpgsz5 // tie off unused signals assign function_50_51 = 1'b0; assign function_46_51 = 1'b0; assign function_36_51 = 1'b0; assign pgsize_eq_16K = 1'b0; assign pgsize_eq_256K = 1'b0; assign pgsize_eq_256M = 1'b0; assign pgsize_gte_16K = 1'b0; assign pgsize_gte_256K = 1'b0; assign pgsize_gte_256M = 1'b0; assign comp_or_34_35 = 1'b0; assign comp_or_36_39 = 1'b0; assign comp_or_44_45 = 1'b0; assign comp_or_46_47 = 1'b0; assign comp_or_48_49 = 1'b0; assign comp_or_50_51 = 1'b0; assign unused[0] = |{function_50_51, function_46_51, function_36_51, pgsize_eq_16K, pgsize_eq_256K, pgsize_eq_256M, pgsize_gte_16K, pgsize_gte_256K, pgsize_gte_256M, comp_or_34_35, comp_or_36_39, comp_or_44_45, comp_or_46_47, comp_or_48_49, comp_or_50_51}; assign entry_epn_b[34:51] = (~(entry_epn[34:51])); if (HAVE_CMPMASK == 0) begin // 110 assign pgsize_eq_1G = ( entry_size[0] & entry_size[1] & (~(entry_size[2]))); // 111 assign pgsize_eq_16M = ( entry_size[0] & entry_size[1] & entry_size[2]); // 101 assign pgsize_eq_1M = ( entry_size[0] & (~(entry_size[1])) & entry_size[2]); // 011 assign pgsize_eq_64K = ((~(entry_size[0])) & entry_size[1] & entry_size[2]); assign pgsize_gte_1G = ( entry_size[0] & entry_size[1] & (~(entry_size[2]))); assign pgsize_gte_16M = ( entry_size[0] & entry_size[1] & entry_size[2]) | pgsize_gte_1G; assign pgsize_gte_1M = ( entry_size[0] & (~(entry_size[1])) & entry_size[2]) | pgsize_gte_16M; assign pgsize_gte_64K = ((~(entry_size[0])) & entry_size[1] & entry_size[2]) | pgsize_gte_1M; assign unused[1] = |{entry_cmpmask, entry_xbitmask}; end if (HAVE_CMPMASK == 1) begin // size entry_cmpmask: 0123 // 1GB 0000 // 16MB 1000 // 1MB 1100 // 64KB 1110 // 4KB 1111 assign pgsize_gte_1G = (~entry_cmpmask[0]); assign pgsize_gte_16M = (~entry_cmpmask[1]); assign pgsize_gte_1M = (~entry_cmpmask[2]); assign pgsize_gte_64K = (~entry_cmpmask[3]); // size entry_xbitmask: 0123 // 1GB 1000 // 16MB 0100 // 1MB 0010 // 64KB 0001 // 4KB 0000 assign pgsize_eq_1G = entry_xbitmask[0]; assign pgsize_eq_16M = entry_xbitmask[1]; assign pgsize_eq_1M = entry_xbitmask[2]; assign pgsize_eq_64K = entry_xbitmask[3]; assign unused[1] = 1'b0; end if (HAVE_XBIT == 0) begin assign function_34_51 = 1'b0; assign function_40_51 = 1'b0; assign function_44_51 = 1'b0; assign function_48_51 = 1'b0; assign unused[2] = |{function_34_51, function_40_51, function_44_51, function_48_51, entry_xbit, entry_epn_b, pgsize_eq_1G, pgsize_eq_16M, pgsize_eq_1M, pgsize_eq_64K}; end if (HAVE_XBIT != 0) begin // 1G assign function_34_51 = (~(entry_xbit)) | (~(pgsize_eq_1G)) | (|(entry_epn_b[34:51] & addr_in[34:51])); // 16M assign function_40_51 = (~(entry_xbit)) | (~(pgsize_eq_16M)) | (|(entry_epn_b[40:51] & addr_in[40:51])); // 1M assign function_44_51 = (~(entry_xbit)) | (~(pgsize_eq_1M)) | (|(entry_epn_b[44:51] & addr_in[44:51])); // 64K assign function_48_51 = (~(entry_xbit)) | (~(pgsize_eq_64K)) | (|(entry_epn_b[48:51] & addr_in[48:51])); assign unused[2] = 1'b0; end assign comp_or_48_51 = (&(match_line[48:51])) | pgsize_gte_64K; assign comp_or_44_47 = (&(match_line[44:47])) | pgsize_gte_1M; assign comp_or_40_43 = (&(match_line[40:43])) | pgsize_gte_16M; assign comp_or_34_39 = (&(match_line[34:39])) | pgsize_gte_1G; if (HAVE_XBIT == 0) begin assign addr_match = (comp_or_34_39 & // Ignore functions based on page size comp_or_40_43 & comp_or_44_47 & comp_or_48_51 & (&(match_line[31:33])) & // Regular compare largest page size ((&(match_line[0:30])) | (~(addr_enable[1])))) | // ignored part of epn (~(addr_enable[0])); // Include address as part of compare, // should never ignore for regular compare/read. // Could ignore for compare/invalidate end if (HAVE_XBIT != 0) begin assign addr_match = (function_48_51 & function_44_51 & function_40_51 & function_34_51 & comp_or_34_39 & // Ignore functions based on page size comp_or_40_43 & comp_or_44_47 & comp_or_48_51 & (&(match_line[31:33])) & // Regular compare largest page size ((&(match_line[0:30])) | (~(addr_enable[1])))) | // ignored part of epn (~(addr_enable[0])); // Include address as part of compare, // should never ignore for regular compare/read. // Could ignore for compare/invalidate end end // numpgsz5: NUM_PGSIZES = 5 assign pgsize_match = (&(match_line[52:54])) | (~(pgsize_enable)); assign class_match = (match_line[55] | (~(class_enable[0]))) & (match_line[56] | (~(class_enable[1]))) & ((&(match_line[55:56])) | (~(class_enable[2])) | ((~(entry_extclass[1])) & (~comp_invalidate))); // pid_nz bit assign extclass_match = (match_line[57] | (~(extclass_enable[0]))) & // iprot bit (match_line[58] | (~(extclass_enable[1]))); // pid_nz bit assign state_match = (match_line[59] | (~(state_enable[0]))) & (match_line[60] | (~(state_enable[1]))); assign thdid_match = (|(entry_thdid[0:3] & comp_thdid[0:3]) | (~(thdid_enable[0]))) & (&(match_line[69:72]) | (~(thdid_enable[1])) | ((~(entry_extclass[1])) & (~comp_invalidate))); // pid_nz bit assign pid_match = (&(match_line[61:68])) | // entry_pid=0 ignores pid match for compares, // but not for invalidates. ((~(entry_extclass[1])) & (~comp_invalidate)) | // pid_nz bit (~(pid_enable)); assign match = addr_match & // Address compare pgsize_match & // Size compare class_match & // Class compare extclass_match & // ExtClass compare state_match & // State compare thdid_match & // ThdID compare pid_match & // PID compare entry_v; // Valid endgenerate endmodule