Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / spc / lsu / rtl / lsu_tlc_ctl.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: lsu_tlc_ctl.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 ============================================
module lsu_tlc_ctl (
l2clk,
scan_in,
tcu_pce_ov,
tcu_scan_en,
spc_aclk,
spc_bclk,
mmu_dtlb_reload,
tld_demap_control0,
tld_demap_control1,
tld_use_secondary_context0,
tld_index_valid,
lsu_lsu_pmen_,
lsu_asi_error_inject_b31,
lsu_asi_error_inject_b27,
lsu_asi_error_inject_b26,
dcc_tlb_rw_index_e,
lbist_run,
mbi_run,
mbi_dtb_write_en,
mbi_repl_write,
mbi_dis_clr_ubit,
mbi_cambist_run,
mbi_dtb_demap_en,
mbi_demap_type,
scan_out,
tlc_wr_u_en,
tlc_rw_index_vld,
tlc_demap,
tlc_demap_context,
tlc_demap_all,
tlc_demap_real,
tlc_sel_demap_tag_c0,
tlc_sel_demap_tag_c1,
tlc_sel_write_tag,
tlc_sel_dm_tag,
tlc_sel_wr_dm_bist,
tlc_sel_tte_tag,
tlc_use_primary_context_c0,
tlc_use_secondary_context_c0,
tlc_wr_or_demap,
tlc_write_next,
tlc_tte0_clken,
tlc_tte1_clken,
tlc_tag_error_inj,
tlc_data_error_inj,
tlc_mbi_run,
tlc_dis_clr_ubit,
lsu_sel_lsu_addr_e);
wire se;
wire pce_ov;
wire stop;
wire siclk;
wire soclk;
wire l1clk;
wire reload0_latch_scanin;
wire reload0_latch_scanout;
wire reload0;
wire reload1_latch_scanin;
wire reload1_latch_scanout;
wire reload1;
wire [2:0] demap_c0;
wire [3:0] demap_c1;
wire wr_vld_in;
wire sel_wr_dm_bist_next;
wire dm_tag_in;
wire wr_vld_latch_scanin;
wire wr_vld_latch_scanout;
wire wr_vld;
wire demap_context;
wire demap_all;
wire demap_real;
wire sel_demap_tag_d;
wire override_context0;
wire tag_error_inj;
wire data_error_inj;
wire error_inj_latch_scanin;
wire error_inj_latch_scanout;
wire bist_latch_scanin;
wire bist_latch_scanout;
wire spares_scanin;
wire spares_scanout;
input l2clk;
input scan_in;
input tcu_pce_ov;
input tcu_scan_en;
input spc_aclk;
input spc_bclk;
// The following signals indicate the
// first cycle of TTE transfer as well
// as the operation (write or demap)
input mmu_dtlb_reload;
input [2:0] tld_demap_control0; // Demap and context controls
input [3:0] tld_demap_control1; // Demap and context controls
input tld_use_secondary_context0;
input tld_index_valid; // Write with index
input lsu_lsu_pmen_; // Power management enable
input lsu_asi_error_inject_b31;
input lsu_asi_error_inject_b27;
input lsu_asi_error_inject_b26;
input dcc_tlb_rw_index_e;
input lbist_run;
input mbi_run;
input mbi_dtb_write_en;
input mbi_repl_write;
input mbi_dis_clr_ubit;
input mbi_cambist_run;
input mbi_dtb_demap_en;
input [1:0] mbi_demap_type;
output scan_out;
output tlc_wr_u_en; // Write enable for tlb
output tlc_rw_index_vld; // Use index for read or write
output tlc_demap; // Any demap
output tlc_demap_context; // Demap context
output tlc_demap_all; // Demap all
output tlc_demap_real; // Demap real
output tlc_sel_demap_tag_c0;
output tlc_sel_demap_tag_c1;
output tlc_sel_write_tag;
output tlc_sel_dm_tag;
output tlc_sel_wr_dm_bist;
output tlc_sel_tte_tag;
output tlc_use_primary_context_c0;// Control context muxes
output tlc_use_secondary_context_c0;
output tlc_wr_or_demap; // Tells LSU to use the demap/write tid for context selection
output tlc_write_next;
output tlc_tte0_clken;
output tlc_tte1_clken;
output tlc_tag_error_inj;
output tlc_data_error_inj;
output tlc_mbi_run;
output tlc_dis_clr_ubit;
output lsu_sel_lsu_addr_e;
//////////////////////////////////////////////////////////////////////////////
assign se = tcu_scan_en;
assign pce_ov = tcu_pce_ov;
assign stop = 1'b0;
assign siclk = spc_aclk;
assign soclk = spc_bclk;
// Clock header
lsu_tlc_ctl_l1clkhdr_ctl_macro clkgen (
.l2clk (l2clk ),
.l1en (1'b1 ),
.l1clk (l1clk ),
.pce_ov(pce_ov),
.stop(stop),
.se(se)
);
////////////////////////////////////////////////////////////////////////////////
//
//
//
//flop mmu_dtlb_reload
lsu_tlc_ctl_msff_ctl_macro__width_1 reload0_latch (
.scan_in(reload0_latch_scanin),
.scan_out(reload0_latch_scanout),
.din (mmu_dtlb_reload ),
.dout (reload0 ),
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk)
);
lsu_tlc_ctl_msff_ctl_macro__width_1 reload1_latch (
.scan_in(reload1_latch_scanin),
.scan_out(reload1_latch_scanout),
.din (reload0 ),
.dout (reload1 ),
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk)
);
// demap_control[3]: use secondary context for demap/write
// demap_control[2]: 1 means demap, 0 means write
// demap_control[1:0] (if demap_control[2] is 1)
// 00 Demap page
// 01 Demap context
// 10 Demap all (to be consistent with Niagara 1)
// 11 Demap real
// demap_control[1:0] (if demap_control[2] is 0)
// 00 Demap and write with supplied context
// 01 Demap and write with context_0
// 10 Demap and write with context_1
// 11 Illegal (but demap and write with context_0)
assign demap_c0[2:0] =
tld_demap_control0[2:0];
assign demap_c1[3:0] =
tld_demap_control1[3:0];
assign wr_vld_in =
reload1 & ~demap_c1[2] & ~tlc_mbi_run;
assign tlc_write_next = wr_vld_in;
assign sel_wr_dm_bist_next = wr_vld_in | reload0 | tlc_mbi_run;
assign dm_tag_in = ~(wr_vld_in | tlc_mbi_run);
lsu_tlc_ctl_msff_ctl_macro__width_3 wr_vld_latch (
.scan_in(wr_vld_latch_scanin),
.scan_out(wr_vld_latch_scanout),
.din ({wr_vld_in, dm_tag_in, sel_wr_dm_bist_next}),
.dout ({wr_vld, tlc_sel_dm_tag,tlc_sel_wr_dm_bist}),
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk)
);
assign lsu_sel_lsu_addr_e = tlc_sel_wr_dm_bist;
assign demap_context =
reload1 & demap_c1[2] & ~demap_c1[1] & demap_c1[0];
assign demap_all =
reload1 & demap_c1[2] & demap_c1[1] & ~demap_c1[0];
assign demap_real =
reload1 & demap_c1[2] & demap_c1[1] & demap_c1[0];
// demap default context if:
// a write with the use_context_[0,1] bits off OR
// a demap with use_seconday off
assign sel_demap_tag_d =
(reload1 & demap_c1[2] & ~demap_c1[3]) |
(reload1 & ~demap_c1[2] & ~demap_c1[1] & ~demap_c1[0]) ;
// demap context 0 if:
// a demap with use_secondary OR
// a write with use_context_0 on
assign tlc_sel_demap_tag_c0 =
(reload1 & demap_c1[2] & demap_c1[3]) |
(reload1 & ~demap_c1[2] & demap_c1[0]) ;
// demap context 1 if a write with use_context_1 on
assign tlc_sel_demap_tag_c1 =
(reload1 & ~demap_c1[2] & demap_c1[1] & ~demap_c1[0]) ;
assign tlc_sel_write_tag = wr_vld;
assign tlc_sel_tte_tag = wr_vld | sel_demap_tag_d | tlc_mbi_run;
// Context mux controls
assign override_context0 =
reload0 & ~demap_c0[2] & (demap_c0[1] | demap_c0[0]);
assign tlc_use_primary_context_c0 =
(override_context0 & ~tld_use_secondary_context0) |
(reload0 & demap_c0[2] & ~tld_use_secondary_context0) ;
assign tlc_use_secondary_context_c0 =
(override_context0 & tld_use_secondary_context0) |
(reload0 & demap_c0[2] & tld_use_secondary_context0) ;
///outputs
assign tlc_demap = tlc_mbi_run ? (mbi_cambist_run & mbi_dtb_demap_en) : reload1;
assign tlc_demap_context = tlc_mbi_run ? (mbi_cambist_run & mbi_dtb_demap_en & (mbi_demap_type[1:0] == 2'b10)) : demap_context;
assign tlc_demap_all = tlc_mbi_run ? (mbi_cambist_run & mbi_dtb_demap_en & (mbi_demap_type[1:0] == 2'b11)) : demap_all;
assign tlc_demap_real = tlc_mbi_run ? (mbi_cambist_run & mbi_dtb_demap_en & (mbi_demap_type[1:0] == 2'b01)) : demap_real;
assign tlc_wr_u_en = tlc_mbi_run ? mbi_dtb_write_en : wr_vld;
assign tlc_rw_index_vld = (tlc_mbi_run ? ~mbi_repl_write : (dcc_tlb_rw_index_e | (wr_vld & tld_index_valid))) | lbist_run;
// This needs to be a cycle earlier than the tlb controls for timing
assign tlc_wr_or_demap = reload0 | wr_vld_in;
//////////////////////////////////
// Power mgmt for the datapath
assign tlc_tte0_clken = mmu_dtlb_reload | reload0 | lsu_lsu_pmen_;
assign tlc_tte1_clken = reload0 | reload1 | lsu_lsu_pmen_;
///////////////////////////////////
// Error injection
assign tag_error_inj = lsu_asi_error_inject_b31 & lsu_asi_error_inject_b26 & wr_vld_in;
assign data_error_inj = lsu_asi_error_inject_b31 & lsu_asi_error_inject_b27 & wr_vld_in;
lsu_tlc_ctl_msff_ctl_macro__width_2 error_inj_latch (
.scan_in(error_inj_latch_scanin),
.scan_out(error_inj_latch_scanout),
.din ({ tag_error_inj, data_error_inj }),
.dout ({tlc_tag_error_inj,tlc_data_error_inj }),
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk)
);
///////////////////////////////////
// BIST
lsu_tlc_ctl_msff_ctl_macro__width_1 bist_latch (
.scan_in(bist_latch_scanin),
.scan_out(bist_latch_scanout),
.din (mbi_run),
.dout (tlc_mbi_run),
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk)
);
assign tlc_dis_clr_ubit = tlc_mbi_run & mbi_dis_clr_ubit;
lsu_tlc_ctl_spare_ctl_macro__num_1 spares (
.scan_in(spares_scanin),
.scan_out(spares_scanout),
.l1clk (l1clk),
.siclk(siclk),
.soclk(soclk)
);
// fixscan start:
assign reload0_latch_scanin = scan_in ;
assign reload1_latch_scanin = reload0_latch_scanout ;
assign wr_vld_latch_scanin = reload1_latch_scanout ;
assign error_inj_latch_scanin = wr_vld_latch_scanout ;
assign bist_latch_scanin = error_inj_latch_scanout ;
assign spares_scanin = bist_latch_scanout ;
assign scan_out = spares_scanout ;
// fixscan end:
endmodule
// any PARAMS parms go into naming of macro
module lsu_tlc_ctl_l1clkhdr_ctl_macro (
l2clk,
l1en,
pce_ov,
stop,
se,
l1clk);
input l2clk;
input l1en;
input pce_ov;
input stop;
input se;
output l1clk;
cl_sc1_l1hdr_8x c_0 (
.l2clk(l2clk),
.pce(l1en),
.l1clk(l1clk),
.se(se),
.pce_ov(pce_ov),
.stop(stop)
);
endmodule
// any PARAMS parms go into naming of macro
module lsu_tlc_ctl_msff_ctl_macro__width_1 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [0:0] fdin;
input [0:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [0:0] dout;
output scan_out;
assign fdin[0:0] = din[0:0];
dff #(1) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[0:0]),
.si(scan_in),
.so(scan_out),
.q(dout[0:0])
);
endmodule
// any PARAMS parms go into naming of macro
module lsu_tlc_ctl_msff_ctl_macro__width_3 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [2:0] fdin;
wire [1:0] so;
input [2:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [2:0] dout;
output scan_out;
assign fdin[2:0] = din[2:0];
dff #(3) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[2:0]),
.si({scan_in,so[1:0]}),
.so({so[1:0],scan_out}),
.q(dout[2:0])
);
endmodule
// any PARAMS parms go into naming of macro
module lsu_tlc_ctl_msff_ctl_macro__width_2 (
din,
l1clk,
scan_in,
siclk,
soclk,
dout,
scan_out);
wire [1:0] fdin;
wire [0:0] so;
input [1:0] din;
input l1clk;
input scan_in;
input siclk;
input soclk;
output [1:0] dout;
output scan_out;
assign fdin[1:0] = din[1:0];
dff #(2) d0_0 (
.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.d(fdin[1:0]),
.si({scan_in,so[0:0]}),
.so({so[0:0],scan_out}),
.q(dout[1:0])
);
endmodule
// Description: Spare gate macro for control blocks
//
// Param num controls the number of times the macro is added
// flops=0 can be used to use only combination spare logic
module lsu_tlc_ctl_spare_ctl_macro__num_1 (
l1clk,
scan_in,
siclk,
soclk,
scan_out);
wire si_0;
wire so_0;
wire spare0_flop_unused;
wire spare0_buf_32x_unused;
wire spare0_nand3_8x_unused;
wire spare0_inv_8x_unused;
wire spare0_aoi22_4x_unused;
wire spare0_buf_8x_unused;
wire spare0_oai22_4x_unused;
wire spare0_inv_16x_unused;
wire spare0_nand2_16x_unused;
wire spare0_nor3_4x_unused;
wire spare0_nand2_8x_unused;
wire spare0_buf_16x_unused;
wire spare0_nor2_16x_unused;
wire spare0_inv_32x_unused;
input l1clk;
input scan_in;
input siclk;
input soclk;
output scan_out;
cl_sc1_msff_8x spare0_flop (.l1clk(l1clk),
.siclk(siclk),
.soclk(soclk),
.si(si_0),
.so(so_0),
.d(1'b0),
.q(spare0_flop_unused));
assign si_0 = scan_in;
cl_u1_buf_32x spare0_buf_32x (.in(1'b1),
.out(spare0_buf_32x_unused));
cl_u1_nand3_8x spare0_nand3_8x (.in0(1'b1),
.in1(1'b1),
.in2(1'b1),
.out(spare0_nand3_8x_unused));
cl_u1_inv_8x spare0_inv_8x (.in(1'b1),
.out(spare0_inv_8x_unused));
cl_u1_aoi22_4x spare0_aoi22_4x (.in00(1'b1),
.in01(1'b1),
.in10(1'b1),
.in11(1'b1),
.out(spare0_aoi22_4x_unused));
cl_u1_buf_8x spare0_buf_8x (.in(1'b1),
.out(spare0_buf_8x_unused));
cl_u1_oai22_4x spare0_oai22_4x (.in00(1'b1),
.in01(1'b1),
.in10(1'b1),
.in11(1'b1),
.out(spare0_oai22_4x_unused));
cl_u1_inv_16x spare0_inv_16x (.in(1'b1),
.out(spare0_inv_16x_unused));
cl_u1_nand2_16x spare0_nand2_16x (.in0(1'b1),
.in1(1'b1),
.out(spare0_nand2_16x_unused));
cl_u1_nor3_4x spare0_nor3_4x (.in0(1'b0),
.in1(1'b0),
.in2(1'b0),
.out(spare0_nor3_4x_unused));
cl_u1_nand2_8x spare0_nand2_8x (.in0(1'b1),
.in1(1'b1),
.out(spare0_nand2_8x_unused));
cl_u1_buf_16x spare0_buf_16x (.in(1'b1),
.out(spare0_buf_16x_unused));
cl_u1_nor2_16x spare0_nor2_16x (.in0(1'b0),
.in1(1'b0),
.out(spare0_nor2_16x_unused));
cl_u1_inv_32x spare0_inv_32x (.in(1'b1),
.out(spare0_inv_32x_unused));
assign scan_out = so_0;
endmodule