You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
12 KiB
Verilog

// © 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
// Description: Mapped Itag Compare
//
//*****************************************************************************
module rv_cmpitag(
vld,
itag,
vld_ary,
itag_ary,
abort,
hit_clear,
hit_abort
);
`include "tri_a2o.vh"
parameter q_itag_busses_g = 7;
input [0:`THREADS-1] vld;
input [0:`ITAG_SIZE_ENC-1] itag;
input [0:(q_itag_busses_g*`THREADS)-1] vld_ary;
input [0:(q_itag_busses_g*`ITAG_SIZE_ENC)-1] itag_ary;
input [0:q_itag_busses_g-1] abort;
output hit_clear;
output hit_abort;
wire [0:7] valid;
wire [0:7] itag_xor[0:7];
wire [0:3] itag_andl10_b;
wire [0:3] itag_andl11_b;
wire [0:3] itag_andl12_b;
wire [0:3] itag_andl13_b;
wire [0:3] itag_andl14_b;
wire [0:3] itag_andl15_b;
wire [0:3] itag_andl16_b;
wire [0:3] itag_andl17_b;
wire [0:1] itag_andl20;
wire [0:1] itag_andl21;
wire [0:1] itag_andl22;
wire [0:1] itag_andl23;
wire [0:1] itag_andl24;
wire [0:1] itag_andl25;
wire [0:1] itag_andl26;
wire [0:1] itag_andl27;
wire [0:7] itagc_andl3_b;
wire [0:3] itagc_orl4;
wire [0:1] itagc_orl5_b;
wire itagc_orl6;
wire [0:7] itaga_andl3_b;
wire [0:3] itaga_orl4;
wire [0:1] itaga_orl5_b;
wire itaga_orl6;
wire [0:7] itag_abort;
wire [0:7] itag_abort_b;
(* analysis_not_referenced="true" *)
wire unused;
//-------------------------------------------------------------------------------------------------------
// Total Logic: XOR + 6 levels
//-------------------------------------------------------------------------------------------------------
generate
begin : xhdl0
genvar n;
for (n = 0; n <= 5; n = n + 1)
begin : q_valid_gen
assign valid[n] = |(vld_ary[n*`THREADS:n*`THREADS+`THREADS-1] & vld);
assign itag_xor[n] = {~(itag ^ itag_ary[n*`ITAG_SIZE_ENC:n*`ITAG_SIZE_ENC+`ITAG_SIZE_ENC-1]), valid[n]};
end
end
endgenerate
//-------------------------------------------------------------------------------------------------------
// XOR ITAG Compares
//-------------------------------------------------------------------------------------------------------
assign itag_abort[0:5] = abort[0:5];
generate
if (q_itag_busses_g == 6)
begin : l1xor_gen6
assign itag_xor[6] = {8{1'b0}};
assign itag_xor[7] = {8{1'b0}};
assign valid[6] = 1'b0;
assign valid[7] = 1'b0;
assign itag_abort[6] = 1'b0;
assign itag_abort[7] = 1'b0;
end
endgenerate
generate
if (q_itag_busses_g == 7)
begin : l1xor_gen7
assign itag_xor[6] = {~(itag ^ itag_ary[6*`ITAG_SIZE_ENC:6*`ITAG_SIZE_ENC+`ITAG_SIZE_ENC-1]), valid[6]};
assign itag_xor[7] = {8{1'b0}};
assign valid[6] = |(vld_ary[6*`THREADS:6*`THREADS+`THREADS-1] & vld);
assign valid[7] = 1'b0;
assign itag_abort[6] = abort[6];
assign itag_abort[7] = 1'b0;
assign unused = valid[7] ;
end
endgenerate
generate
if (q_itag_busses_g == 8)
begin : l1xor_gen8
assign itag_xor[6] = {~(itag ^ itag_ary[6*`ITAG_SIZE_ENC:6*`ITAG_SIZE_ENC+`ITAG_SIZE_ENC-1]), valid[6]};
assign itag_xor[7] = {~(itag ^ itag_ary[7*`ITAG_SIZE_ENC:7*`ITAG_SIZE_ENC+`ITAG_SIZE_ENC-1]), valid[7]};
assign valid[6] = |(vld_ary[6*`THREADS:6*`THREADS+`THREADS-1] & vld);
assign valid[7] = |(vld_ary[7*`THREADS:7*`THREADS+`THREADS-1] & vld);
assign itag_abort[6] = abort[6];
assign itag_abort[7] = abort[7];
end
endgenerate
assign itag_abort_b = ~itag_abort;
//-------------------------------------------------------------------------------------------------------
// AND Tree. 8 groups of 8, 3 levels each
//-------------------------------------------------------------------------------------------------------
// Level 1
assign itag_andl10_b[0] = ~(itag_xor[0][0] & itag_xor[0][1]);
assign itag_andl10_b[1] = ~(itag_xor[0][2] & itag_xor[0][3]);
assign itag_andl10_b[2] = ~(itag_xor[0][4] & itag_xor[0][5]);
assign itag_andl10_b[3] = ~(itag_xor[0][6] & itag_xor[0][7]);
assign itag_andl11_b[0] = ~(itag_xor[1][0] & itag_xor[1][1]);
assign itag_andl11_b[1] = ~(itag_xor[1][2] & itag_xor[1][3]);
assign itag_andl11_b[2] = ~(itag_xor[1][4] & itag_xor[1][5]);
assign itag_andl11_b[3] = ~(itag_xor[1][6] & itag_xor[1][7]);
assign itag_andl12_b[0] = ~(itag_xor[2][0] & itag_xor[2][1]);
assign itag_andl12_b[1] = ~(itag_xor[2][2] & itag_xor[2][3]);
assign itag_andl12_b[2] = ~(itag_xor[2][4] & itag_xor[2][5]);
assign itag_andl12_b[3] = ~(itag_xor[2][6] & itag_xor[2][7]);
assign itag_andl13_b[0] = ~(itag_xor[3][0] & itag_xor[3][1]);
assign itag_andl13_b[1] = ~(itag_xor[3][2] & itag_xor[3][3]);
assign itag_andl13_b[2] = ~(itag_xor[3][4] & itag_xor[3][5]);
assign itag_andl13_b[3] = ~(itag_xor[3][6] & itag_xor[3][7]);
assign itag_andl14_b[0] = ~(itag_xor[4][0] & itag_xor[4][1]);
assign itag_andl14_b[1] = ~(itag_xor[4][2] & itag_xor[4][3]);
assign itag_andl14_b[2] = ~(itag_xor[4][4] & itag_xor[4][5]);
assign itag_andl14_b[3] = ~(itag_xor[4][6] & itag_xor[4][7]);
assign itag_andl15_b[0] = ~(itag_xor[5][0] & itag_xor[5][1]);
assign itag_andl15_b[1] = ~(itag_xor[5][2] & itag_xor[5][3]);
assign itag_andl15_b[2] = ~(itag_xor[5][4] & itag_xor[5][5]);
assign itag_andl15_b[3] = ~(itag_xor[5][6] & itag_xor[5][7]);
assign itag_andl16_b[0] = ~(itag_xor[6][0] & itag_xor[6][1]);
assign itag_andl16_b[1] = ~(itag_xor[6][2] & itag_xor[6][3]);
assign itag_andl16_b[2] = ~(itag_xor[6][4] & itag_xor[6][5]);
assign itag_andl16_b[3] = ~(itag_xor[6][6] & itag_xor[6][7]);
assign itag_andl17_b[0] = ~(itag_xor[7][0] & itag_xor[7][1]);
assign itag_andl17_b[1] = ~(itag_xor[7][2] & itag_xor[7][3]);
assign itag_andl17_b[2] = ~(itag_xor[7][4] & itag_xor[7][5]);
assign itag_andl17_b[3] = ~(itag_xor[7][6] & itag_xor[7][7]);
// Level 2
assign itag_andl20[0] = ~(itag_andl10_b[0] | itag_andl10_b[1]);
assign itag_andl20[1] = ~(itag_andl10_b[2] | itag_andl10_b[3]);
assign itag_andl21[0] = ~(itag_andl11_b[0] | itag_andl11_b[1]);
assign itag_andl21[1] = ~(itag_andl11_b[2] | itag_andl11_b[3]);
assign itag_andl22[0] = ~(itag_andl12_b[0] | itag_andl12_b[1]);
assign itag_andl22[1] = ~(itag_andl12_b[2] | itag_andl12_b[3]);
assign itag_andl23[0] = ~(itag_andl13_b[0] | itag_andl13_b[1]);
assign itag_andl23[1] = ~(itag_andl13_b[2] | itag_andl13_b[3]);
assign itag_andl24[0] = ~(itag_andl14_b[0] | itag_andl14_b[1]);
assign itag_andl24[1] = ~(itag_andl14_b[2] | itag_andl14_b[3]);
assign itag_andl25[0] = ~(itag_andl15_b[0] | itag_andl15_b[1]);
assign itag_andl25[1] = ~(itag_andl15_b[2] | itag_andl15_b[3]);
assign itag_andl26[0] = ~(itag_andl16_b[0] | itag_andl16_b[1]);
assign itag_andl26[1] = ~(itag_andl16_b[2] | itag_andl16_b[3]);
assign itag_andl27[0] = ~(itag_andl17_b[0] | itag_andl17_b[1]);
assign itag_andl27[1] = ~(itag_andl17_b[2] | itag_andl17_b[3]);
// Level 3 - sneak in the abort here
assign itagc_andl3_b[0] = ~(itag_andl20[0] & itag_andl20[1] & itag_abort_b[0]);
assign itagc_andl3_b[1] = ~(itag_andl21[0] & itag_andl21[1] & itag_abort_b[1]);
assign itagc_andl3_b[2] = ~(itag_andl22[0] & itag_andl22[1] & itag_abort_b[2]);
assign itagc_andl3_b[3] = ~(itag_andl23[0] & itag_andl23[1] & itag_abort_b[3]);
assign itagc_andl3_b[4] = ~(itag_andl24[0] & itag_andl24[1] & itag_abort_b[4]);
assign itagc_andl3_b[5] = ~(itag_andl25[0] & itag_andl25[1] & itag_abort_b[5]);
assign itagc_andl3_b[6] = ~(itag_andl26[0] & itag_andl26[1] & itag_abort_b[6]);
assign itagc_andl3_b[7] = ~(itag_andl27[0] & itag_andl27[1] & itag_abort_b[7]);
// Level 3 - sneak in the abort here
assign itaga_andl3_b[0] = ~(itag_andl20[0] & itag_andl20[1] & itag_abort[0]);
assign itaga_andl3_b[1] = ~(itag_andl21[0] & itag_andl21[1] & itag_abort[1]);
assign itaga_andl3_b[2] = ~(itag_andl22[0] & itag_andl22[1] & itag_abort[2]);
assign itaga_andl3_b[3] = ~(itag_andl23[0] & itag_andl23[1] & itag_abort[3]);
assign itaga_andl3_b[4] = ~(itag_andl24[0] & itag_andl24[1] & itag_abort[4]);
assign itaga_andl3_b[5] = ~(itag_andl25[0] & itag_andl25[1] & itag_abort[5]);
assign itaga_andl3_b[6] = ~(itag_andl26[0] & itag_andl26[1] & itag_abort[6]);
assign itaga_andl3_b[7] = ~(itag_andl27[0] & itag_andl27[1] & itag_abort[7]);
//-------------------------------------------------------------------------------------------------------
// CLEAR OR Tree. 8 groups. Coming in inverted. 3 more levels
//-------------------------------------------------------------------------------------------------------
// Level 4
assign itagc_orl4[0] = ~(itagc_andl3_b[0] & itagc_andl3_b[1]);
assign itagc_orl4[1] = ~(itagc_andl3_b[2] & itagc_andl3_b[3]);
assign itagc_orl4[2] = ~(itagc_andl3_b[4] & itagc_andl3_b[5]);
assign itagc_orl4[3] = ~(itagc_andl3_b[6] & itagc_andl3_b[7]);
// Level 5
assign itagc_orl5_b[0] = ~(itagc_orl4[0] | itagc_orl4[1]);
assign itagc_orl5_b[1] = ~(itagc_orl4[2] | itagc_orl4[3]);
// Level 6
assign itagc_orl6 = ~(itagc_orl5_b[0] & itagc_orl5_b[1]);
assign hit_clear = itagc_orl6;
//-------------------------------------------------------------------------------------------------------
// ABORT OR Tree. 8 groups. Coming in inverted. 3 more levels
//-------------------------------------------------------------------------------------------------------
// Level 4
assign itaga_orl4[0] = ~(itaga_andl3_b[0] & itaga_andl3_b[1]);
assign itaga_orl4[1] = ~(itaga_andl3_b[2] & itaga_andl3_b[3]);
assign itaga_orl4[2] = ~(itaga_andl3_b[4] & itaga_andl3_b[5]);
assign itaga_orl4[3] = ~(itaga_andl3_b[6] & itaga_andl3_b[7]);
// Level 5
assign itaga_orl5_b[0] = ~(itaga_orl4[0] | itaga_orl4[1]);
assign itaga_orl5_b[1] = ~(itaga_orl4[2] | itaga_orl4[3]);
// Level 6
assign itaga_orl6 = ~(itaga_orl5_b[0] & itaga_orl5_b[1]);
assign hit_abort = itaga_orl6;
endmodule // rv_cmpitag