// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: l2t_mbist_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 l2t_mbist_ctl ( mbist_run, mbist_l2tag_read, mbist_l2tag_write, mbist_l2tag_index, mbist_l2tag_way, mbist_l2tag_dec_way, mbist_l2tag_lkup_tag, mbist_l2tag_fail, mbist_l2tag_hit_way, mbist_l2data_write, mbist_l2data_word, mbist_l2data_way, mbist_l2data_index, mbist_l2data_fail, mbist_l2vuad_read, mbist_l2vuad_write, mbist_l2vuad_index, mbist_l2vuad_vd, mbist_l2vuad_fail, mbist_arb_l2t_write, mbist_write_data, mbist_write_data_decck, mbist_done, mbist_fail, mbist0_done, mbist2_done, mbist0_fail, mbist2_fail, mbist_start_mb0, mbist_start_mb2, mbist_arb_l2d_en, mbist_arb_l2d_write, mbist_l2d_en, l2clk, tcu_pce_ov, tcu_aclk, tcu_bclk, tcu_scan_en, tcu_clk_stop, scan_in, scan_out, mbist_start, mbist_bisi_mode, mbist_user_mode); wire pce_ov; wire stop; wire siclk; wire soclk; wire se; wire l1clk; wire clock_enable; wire start_in; wire l1clk_pm1; wire array_usr_reg_scanin; wire array_usr_reg_scanout; wire [3:0] user_array_sel_in; wire [3:0] user_array_sel; wire user_addr_mode_reg_scanin; wire user_addr_mode_reg_scanout; wire user_addr_mode_in; wire user_addr_mode; wire user_start_addr_reg_scanin; wire user_start_addr_reg_scanout; wire [17:0] user_start_addr_in; wire [17:0] user_start_addr; wire user_stop_addr_reg_scanin; wire user_stop_addr_reg_scanout; wire [17:0] user_stop_addr_in; wire [17:0] user_stop_addr; wire user_incr_addr_reg_scanin; wire user_incr_addr_reg_scanout; wire [17:0] user_incr_addr_in; wire [17:0] user_incr_addr; wire user_data_mode_reg_scanin; wire user_data_mode_reg_scanout; wire user_data_mode_in; wire user_data_mode; wire user_data_reg_scanin; wire user_data_reg_scanout; wire [7:0] user_data_in; wire [7:0] user_data; wire user_loop_mode_reg_scanin; wire user_loop_mode_reg_scanout; wire user_loop_mode_in; wire user_loop_mode; wire ten_n_mode_reg_scanin; wire ten_n_mode_reg_scanout; wire ten_n_mode_in; wire ten_n_mode; wire user_quad_sel_reg_scanin; wire user_quad_sel_reg_scanout; wire user_quad_sel_in; wire user_quad_sel; wire user_bisi_wr_mode_reg_scanin; wire user_bisi_wr_mode_reg_scanout; wire user_bisi_wr_mode_in; wire user_bisi_wr_mode; wire user_bisi_rd_mode_reg_scanin; wire user_bisi_rd_mode_reg_scanout; wire user_bisi_rd_mode_in; wire user_bisi_rd_mode; wire user_addr_mix_sel_reg_scanin; wire user_addr_mix_sel_reg_scanout; wire [1:0] user_addr_mix_sel_in; wire [1:0] user_addr_mix_sel; wire mb_user_data_mode; wire user_mode; wire mb_user_addr_mode; wire mb_user_quad_sel; wire mb_ten_n_mode; wire mb_user_loop_mode; wire mb_user_bisi_wr_mode; wire bisi_mode; wire mb_user_bisi_rd_mode; wire mb_user_bisi_rw_mode; wire mb_default_bisi; wire mbist_start_reg_scanin; wire mbist_start_reg_scanout; wire mbist_start_all; wire mbist_start_all_reg_scanin; wire mbist_start_all_reg_scanout; wire mbist_start_mb1; wire input_signals_reg_scanin; wire input_signals_reg_scanout; wire mb_enable_reg_scanin; wire mb_enable_reg_scanout; wire mb_enable; wire mb_enable_out; wire start; wire mb2_done; wire config_reg_scanin; wire config_reg_scanout; wire [1:0] config_in; wire [1:0] config_out; wire start_transition; wire end_transition; wire reset_engine; wire loop_again; wire run; wire loop_again_reg_scanin; wire loop_again_reg_scanout; wire stop_engine_l; wire stop_engine_l_q; wire [15:0] l2tag_dec_way; wire [3:0] l2tag_way; wire d_mbist_l2vuad_vd; wire array_1; wire arb_l2d_en; wire array_3; wire array_2; wire arb_l2d_write; wire l2d_en; wire mbist_output_reg_scanin; wire mbist_output_reg_scanout; wire cntl_l2rw; wire [27:0] mb_l2tag_lkup_tag; wire mb_array_2_wr; wire cntl_l2rw_out; wire input_cam_hit_reg_scanin; wire input_cam_hit_reg_scanout; wire [15:0] mb_l2tag_hit_way; wire cntl_reg_scanin; wire cntl_reg_scanout; wire [35:0] cntl_in; wire [35:0] cntl_out; wire run3; wire [13:0] cntl_algr; wire [13:0] next_algr; wire sel_nextaddr_reset; wire sel_nextaddr_restart; wire overflow; wire sel_nextaddr_incred; wire cout_rw; wire sel_nextaddr_same; wire [17:0] start_addr; wire [17:0] restart_addr; wire [17:0] incred_addr; wire [17:0] cntl_addr; wire [2:0] cntl_rw; wire [3:0] next_rw; wire cntl_msb; wire cntl_bisi; wire [3:0] cntl_array_sel; wire last_array; wire [1:0] cntl_data_sel; wire [1:0] cntl_addr_mix; wire addr_mix_pass; wire [3:0] cntl_march_element; wire sel_march_1_pass; wire [1:0] addr_mix_cntl_out; wire cntl_addr_mix_reg_scanin; wire cntl_addr_mix_reg_scanout; wire [1:0] addr_mix_sel; wire [1:0] addr_mix_sel_out; wire array_0; wire addr_mix_1; wire addr_mix_0; wire addr_mix_2; wire cout_addr; wire upaddr; wire march_0; wire march_1; wire march_2; wire march_6; wire march_7; wire [3:0] march_element_pre; wire march_pre_0; wire march_pre_1; wire march_pre_2; wire march_pre_6; wire march_pre_7; wire upaddr_pre; wire [17:0] incr_addr; wire [17:0] stop_addr; wire sel_rw_pass; wire [3:0] rw_incr; wire one_cycle_march; wire march_5; wire five_cycle_march; wire march_8; wire two_cycle_march; wire mem_wr_pbi; wire march_3; wire march_4; wire rw_1; wire rw_0; wire rw_4; wire mem_wr; wire bisi_wr_mode; wire bisi_rd_mode; wire mem_rd_pbi; wire mem_rd; wire [17:0] adj_addr; wire rw_3; wire [17:0] mem_addr1; wire true_data_l; wire rw_2; wire true_data; wire [7:0] data_pat_sel; wire [7:0] mem_data; wire l2tag_data_0_or_1; wire [27:0] l2tag_lkup_tag; wire l2tag_cam_pass; wire l2tag_cam_cmp_d4; wire l2tag_cam_fail; wire l2tag_strobe_valid; wire [17:0] mb_addr; wire l2tag_cam_cmp; wire mb_array_2_rd; wire cam_cmp_fail_delay_reg_scanin; wire cam_cmp_fail_delay_reg_scanout; wire l2tag_cam_cmp_d1; wire l2tag_cam_cmp_d2; wire l2tag_cam_cmp_d3; wire [17:0] mem_addr_mix0; wire [17:0] mem_addr_mix1; wire [17:0] mem_addr_mix2_pre; wire [3:0] mem_addr_mix2_dec; wire [17:0] mem_addr_mix2; wire [17:0] mem_addr; wire [3:0] array_sel; wire [3:0] march_element; wire [2:0] rw; wire [3:0] array_sel_cntl_out; wire array_sel_reg_scanin; wire array_sel_reg_scanout; wire [3:0] array_sel_out; wire [3:0] march_element_cntl_out; wire marche_element_reg_scanin; wire marche_element_reg_scanout; wire [3:0] march_element_out; wire [2:0] rw_cntl_out; wire march_element_reg_scanin; wire march_element_reg_scanout; wire [2:0] rw_out; wire sel_rw_1_pass; wire sel_rw_2_pass; wire sel_rw_5_pass; wire [7:0] mb_write_data; wire mb_array_0_rd; wire mb_array_1_rd; wire mb_array_3_rd; wire quad_cntl; wire mb_array_0_wr; wire mb_array_1_wr; wire mb_array_3_wr; wire mb_run; wire msb_latch_scanin; wire msb_latch_scanout; wire msb_in; wire msb_out; wire mb_done; wire [4:0] done_delay; wire run3_transition_reg_scanin; wire run3_transition_reg_scanout; wire run3_out; wire run3_transition; wire done_delay_reg_scanin; wire done_delay_reg_scanout; wire [4:0] done_delay_in; wire merged_fail_scanin; wire merged_fail_scanout; wire mb_fail_merged; wire mb0_fail; wire mb2_fail; wire merged_done_scanin; wire merged_done_scanout; wire mb_done_merged; wire mb0_done; wire mb1_fail; wire mb1_done; wire mb_l2tag_fail; wire mb_l2vuad_fail; wire mb_l2data_fail_pregate; wire l2data_rd_cmp_reg_scanin; wire l2data_rd_cmp_reg_scanout; wire array_3_rd_d1; wire array_3_rd_d2; wire array_3_rd_d3; wire array_3_rd_d4; wire array_3_rd_d5; wire array_3_rd_d6; wire mb_l2data_fail; wire l2tag_fail_d; wire l2tag_fail_sticky; wire l2vuad_fail_d; wire l2vuad_fail_sticky; wire l2data_fail_d; wire l2data_fail_sticky; wire l2tag_cam_fail_d; wire l2tag_cam_sticky; wire mbist_fail_input_reg_scanin; wire mbist_fail_input_reg_scanout; wire mbist_fail_sticky; wire mbist_fail_array; wire valid_fail; wire mb_fail; wire out_mb_tcu_done_reg_scanin; wire out_mb_tcu_done_reg_scanout; wire mb_done_out; wire out_mb_tcu_fail_reg_scanin; wire out_mb_tcu_fail_reg_scanout; wire mb_fail_out; wire out_run_mb_arrays_reg_scanin; wire out_run_mb_arrays_reg_scanout; wire mb_run_out; wire out_data_mb_arrays_reg_scanin; wire out_data_mb_arrays_reg_scanout; wire [7:0] mb_write_data_out; wire [7:0] mbist_write_data_decck_out; wire out_addr_mb_arrays_reg_scanin; wire out_addr_mb_arrays_reg_scanout; wire [17:0] mb_addr_out; wire out_wr_mb_arrays_reg_scanin; wire out_wr_mb_arrays_reg_scanout; wire mb_array_0_wr_out; wire mb_array_1_wr_out; wire mb_array_2_wr_out; wire mb_array_3_wr_out; wire out_rd_mb_arrays_reg_scanin; wire out_rd_mb_arrays_reg_scanout; wire mb_array_0_rd_out; wire mb_array_1_rd_out; wire mb_array_2_rd_out; wire [3:0] l2data_word; wire spares_scanin; wire spares_scanout; /////////////////////////////////////////////////////////////////////////////// // Outputs /////////////////////////////////////////////////////////////////////////////// output mbist_run; // run // l2tag output mbist_l2tag_read; // read enable for tag array output mbist_l2tag_write; // write enable for tag array output [8:0] mbist_l2tag_index; // Tag array index output [3:0] mbist_l2tag_way; // mux select to pick out a way for a read output [15:0] mbist_l2tag_dec_way; // The way select for the tag array output [27:0] mbist_l2tag_lkup_tag; //To test lookup operation. input mbist_l2tag_fail; input [15:0] mbist_l2tag_hit_way; //To see if a match happened. //Added 2/28/05. // l2data output mbist_l2data_write; // 0=Write to the dataarray 1=read output [3:0] mbist_l2data_word; // encoded 1/16 words are picked to write // out of 624 bits you can only write 78 bits at // a time output [3:0] mbist_l2data_way; // encoded way for data array access output [8:0] mbist_l2data_index; // data access index encoded input mbist_l2data_fail; // l2vuad output mbist_l2vuad_read; // Read enable for vuad array output mbist_l2vuad_write; // VUAD array write enable output [8:0] mbist_l2vuad_index; // index to access vuad arrays output mbist_l2vuad_vd; // This is a select signal to pick vd or ua arrays input mbist_l2vuad_fail; // ??? output mbist_arb_l2t_write; // Asserted as a request for writing tag array output [7:0] mbist_write_data; // write data output [7:0] mbist_write_data_decck; // write data output mbist_done; output mbist_fail; input mbist0_done; input mbist2_done; input mbist0_fail; input mbist2_fail; // mbist_start redistribution: output mbist_start_mb0; output mbist_start_mb2; // ??????????????????????????????????????????????????????????????????????????????????????? output mbist_arb_l2d_en; // select to pick mbist index for data array access output mbist_arb_l2d_write; // select to pick mbist data for data array access output mbist_l2d_en; // select to pick mbist way for data array access /////////////////////////////////////////////////////////////////////////////// // Inputs /////////////////////////////////////////////////////////////////////////////// input l2clk; input tcu_pce_ov; input tcu_aclk; input tcu_bclk; input tcu_scan_en; input tcu_clk_stop; input scan_in; output scan_out; input mbist_start; input mbist_bisi_mode; input mbist_user_mode; /////////////////////////////////////////////////////////////////////////////// // Wires /////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// // Scan Renames // ///////////////////////////////////////////////////////////////////////////// assign pce_ov = tcu_pce_ov; assign stop = tcu_clk_stop; assign siclk = tcu_aclk; assign soclk = tcu_bclk; assign se = tcu_scan_en; //////////////////////////////////////////////////////////////////////////////// // Clock header l2t_l1clkhdr_ctl_macro clkgen_freeclk ( .l2clk (l2clk ), .l1en (1'b1 ), .l1clk (l1clk ), .pce_ov(pce_ov), .stop(stop), .se(se)); assign clock_enable = start_in | mbist_done | mbist_run | mbist_fail ; l2t_l1clkhdr_ctl_macro clkgen ( .l2clk (l2clk ), .l1en (clock_enable ), .l1clk (l1clk_pm1 ), .pce_ov(pce_ov), .stop(stop), .se(se) ); // ///////////////////////////////////////////////////////////////////////////// // // user mode resgisters // MBIST PGM Control Register // // ///////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // user control registers // size // - user_array_sel 4 // - user_addr_mode 1 // - user_start_addr 15 // - user_stop_addr 15 // - user_inc_addr 15 // - user_data_mode 1 // - user_data 8 // - user_cmpsel_hold 1 // - user_cmpsel 3 // - user_loop_mode 1 // - user_quad_sel 1 (selects upper and lower halves ) l2t_msff_ctl_macro__width_4 array_usr_reg ( .scan_in(array_usr_reg_scanin), .scan_out(array_usr_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_array_sel_in[3:0] ), .dout ( user_array_sel[3:0] ), .siclk(siclk), .soclk(soclk)); assign user_array_sel_in[3:0]=user_array_sel[3:0]; // user address mode l2t_msff_ctl_macro__width_1 user_addr_mode_reg ( .scan_in(user_addr_mode_reg_scanin), .scan_out(user_addr_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_addr_mode_in ), .dout ( user_addr_mode ), .siclk(siclk), .soclk(soclk)); assign user_addr_mode_in=user_addr_mode; // user start address l2t_msff_ctl_macro__width_18 user_start_addr_reg ( .scan_in(user_start_addr_reg_scanin), .scan_out(user_start_addr_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_start_addr_in[17:0] ), .dout ( user_start_addr[17:0] ), .siclk(siclk), .soclk(soclk)); assign user_start_addr_in[17:0]=user_start_addr[17:0]; // user stop address l2t_msff_ctl_macro__width_18 user_stop_addr_reg ( .scan_in(user_stop_addr_reg_scanin), .scan_out(user_stop_addr_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_stop_addr_in[17:0] ), .dout ( user_stop_addr[17:0] ), .siclk(siclk), .soclk(soclk)); assign user_stop_addr_in[17:0]=user_stop_addr[17:0]; // user increment address l2t_msff_ctl_macro__width_18 user_incr_addr_reg ( .scan_in(user_incr_addr_reg_scanin), .scan_out(user_incr_addr_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_incr_addr_in[17:0] ), .dout ( user_incr_addr[17:0] ), .siclk(siclk), .soclk(soclk)); assign user_incr_addr_in[17:0]=user_incr_addr[17:0]; // user data mode l2t_msff_ctl_macro__width_1 user_data_mode_reg ( .scan_in(user_data_mode_reg_scanin), .scan_out(user_data_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_data_mode_in ), .dout ( user_data_mode ), .siclk(siclk), .soclk(soclk)); assign user_data_mode_in=user_data_mode; // user data select l2t_msff_ctl_macro__width_8 user_data_reg ( .scan_in(user_data_reg_scanin), .scan_out(user_data_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_data_in[7:0] ), .dout ( user_data[7:0] ), .siclk(siclk), .soclk(soclk)); assign user_data_in[7:0] = user_data[7:0]; // user loop mode l2t_msff_ctl_macro__width_1 user_loop_mode_reg ( .scan_in(user_loop_mode_reg_scanin), .scan_out(user_loop_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_loop_mode_in ), .dout ( user_loop_mode ), .siclk(siclk), .soclk(soclk)); assign user_loop_mode_in=user_loop_mode; // 10N Algorithm for bit mapping l2t_msff_ctl_macro__width_1 ten_n_mode_reg ( .scan_in(ten_n_mode_reg_scanin), .scan_out(ten_n_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( ten_n_mode_in ), .dout ( ten_n_mode ), .siclk(siclk), .soclk(soclk)); assign ten_n_mode_in=ten_n_mode; // user data mode l2t_msff_ctl_macro__width_1 user_quad_sel_reg ( .scan_in(user_quad_sel_reg_scanin), .scan_out(user_quad_sel_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_quad_sel_in ), .dout ( user_quad_sel ), .siclk(siclk), .soclk(soclk)); assign user_quad_sel_in=user_quad_sel; l2t_msff_ctl_macro__width_1 user_bisi_wr_mode_reg ( .scan_in(user_bisi_wr_mode_reg_scanin), .scan_out(user_bisi_wr_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_bisi_wr_mode_in ), .dout ( user_bisi_wr_mode ), .siclk(siclk), .soclk(soclk)); assign user_bisi_wr_mode_in=user_bisi_wr_mode; l2t_msff_ctl_macro__width_1 user_bisi_rd_mode_reg ( .scan_in(user_bisi_rd_mode_reg_scanin), .scan_out(user_bisi_rd_mode_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_bisi_rd_mode_in ), .dout ( user_bisi_rd_mode ), .siclk(siclk), .soclk(soclk)); assign user_bisi_rd_mode_in=user_bisi_rd_mode; l2t_msff_ctl_macro__width_2 user_addr_mix_sel_reg ( .scan_in(user_addr_mix_sel_reg_scanin), .scan_out(user_addr_mix_sel_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( user_addr_mix_sel_in[1:0] ), .dout ( user_addr_mix_sel[1:0] ), .siclk(siclk), .soclk(soclk)); assign user_addr_mix_sel_in[1:0]=user_addr_mix_sel[1:0]; assign mb_user_data_mode = user_mode & user_data_mode; assign mb_user_addr_mode = user_mode & user_addr_mode; assign mb_user_quad_sel = user_mode & user_quad_sel; assign mb_ten_n_mode = user_mode & ten_n_mode; assign mb_user_loop_mode = user_mode & user_loop_mode; assign mb_user_bisi_wr_mode = user_mode & user_bisi_wr_mode & bisi_mode; assign mb_user_bisi_rd_mode = user_mode & user_bisi_rd_mode & bisi_mode; assign mb_user_bisi_rw_mode = ((~user_bisi_wr_mode & ~user_bisi_rd_mode) | (user_bisi_wr_mode & user_bisi_rd_mode)) & bisi_mode; assign mb_default_bisi = bisi_mode & ~user_mode; // ///////////////////////////////////////////////////////////////////////////// // // MBIST Config Register // // ///////////////////////////////////////////////////////////////////////////// // // A low to high transition on mbist_start will reset and start the engine. // mbist_start must remain active high for the duration of MBIST. // If mbist_start deasserts the engine will stop but not reset. // Once MBIST has completed mb0_done will assert and the fail status // signals will be valid. // To run MBIST again the mbist_start signal must transition low then high. // // Loop on Address will disable the address mix function. // // ///////////////////////////////////////////////////////////////////////////// // flop incoming signals: // flop incoming signals: // --> mbist_start -> flop -> flop-> mbist_mb2 // -> mbist_start_all -> mbist_start_mb1 // -> mbist_start_all -> mbist_start_mb0 l2t_msff_ctl_macro__width_1 mbist_start_reg ( .scan_in(mbist_start_reg_scanin), .scan_out(mbist_start_reg_scanout), .l1clk ( l1clk ), .din ( mbist_start ), .dout ( mbist_start_all ), .siclk(siclk), .soclk(soclk)); l2t_msff_ctl_macro__width_3 mbist_start_all_reg ( .scan_in(mbist_start_all_reg_scanin), .scan_out(mbist_start_all_reg_scanout), .l1clk ( l1clk ), .din ( {mbist_start_all,mbist_start_all, mbist_start_all} ), .dout ( {mbist_start_mb1,mbist_start_mb0, mbist_start_mb2} ), .siclk(siclk), .soclk(soclk)); l2t_msff_ctl_macro__width_3 input_signals_reg ( .scan_in(input_signals_reg_scanin), .scan_out(input_signals_reg_scanout), .l1clk ( l1clk ), .din ( {mbist_start_mb1,mbist_bisi_mode,mbist_user_mode} ), .dout ( {start_in,bisi_mode,user_mode} ), .siclk(siclk), .soclk(soclk)); // default : mb_enable=0 // bisi : mb_enable=0 // user_mode : mb_enable=depend on programmed value l2t_msff_ctl_macro__width_1 mb_enable_reg ( .scan_in(mb_enable_reg_scanin), .scan_out(mb_enable_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mb_enable ), .dout ( mb_enable_out ), .siclk(siclk), .soclk(soclk)); assign mb_enable = user_mode ? mb_enable_out : 1'b0; assign start = user_mode ? (mb_enable_out & start_in) : (start_in & mb2_done); // assign start = start_in ; l2t_msff_ctl_macro__width_2 config_reg ( .scan_in(config_reg_scanin), .scan_out(config_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( config_in[1:0] ), .dout ( config_out[1:0] ), .siclk(siclk), .soclk(soclk)); assign config_in[0] = start; assign config_in[1] = config_out[0]; assign start_transition = config_out[0] & ~config_out[1]; assign end_transition = ~config_out[0] & config_out[1]; assign reset_engine = start_transition | loop_again | end_transition; assign run = config_out[1] ; l2t_msff_ctl_macro__width_1 loop_again_reg ( .scan_in(loop_again_reg_scanin), .scan_out(loop_again_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( stop_engine_l ), .dout ( stop_engine_l_q ), .siclk(siclk), .soclk(soclk)); assign loop_again=mb_user_loop_mode ? stop_engine_l & ~stop_engine_l_q: 1'b0; assign l2tag_dec_way[0] = (l2tag_way[3:0]==4'h0); assign l2tag_dec_way[1] = (l2tag_way[3:0]==4'h1); assign l2tag_dec_way[2] = (l2tag_way[3:0]==4'h2); assign l2tag_dec_way[3] = (l2tag_way[3:0]==4'h3); assign l2tag_dec_way[4] = (l2tag_way[3:0]==4'h4); assign l2tag_dec_way[5] = (l2tag_way[3:0]==4'h5); assign l2tag_dec_way[6] = (l2tag_way[3:0]==4'h6); assign l2tag_dec_way[7] = (l2tag_way[3:0]==4'h7); assign l2tag_dec_way[8] = (l2tag_way[3:0]==4'h8); assign l2tag_dec_way[9] = (l2tag_way[3:0]==4'h9); assign l2tag_dec_way[10] = (l2tag_way[3:0]==4'hA); assign l2tag_dec_way[11] = (l2tag_way[3:0]==4'hB); assign l2tag_dec_way[12] = (l2tag_way[3:0]==4'hC); assign l2tag_dec_way[13] = (l2tag_way[3:0]==4'hD); assign l2tag_dec_way[14] = (l2tag_way[3:0]==4'hE); assign l2tag_dec_way[15] = (l2tag_way[3:0]==4'hF); assign d_mbist_l2vuad_vd=array_1; // selects vuad dirty assign arb_l2d_en =user_mode ? run : array_3 | array_2; // provide early static signal assign arb_l2d_write=user_mode ? run : array_3 | array_2; // provide early static signal assign l2d_en =user_mode ? run : array_3 | array_2; // provide early static signal l2t_msff_ctl_macro__width_50 mbist_output_reg ( .scan_in(mbist_output_reg_scanin), .scan_out(mbist_output_reg_scanout), .l1clk ( l1clk_pm1 ), .din ({ cntl_l2rw, l2tag_dec_way[15:0], mb_l2tag_lkup_tag[27:0], d_mbist_l2vuad_vd, mb_array_2_wr, arb_l2d_en, arb_l2d_write, l2d_en}), .dout ({ cntl_l2rw_out, mbist_l2tag_dec_way[15:0], mbist_l2tag_lkup_tag[27:0], mbist_l2vuad_vd, mbist_arb_l2t_write, mbist_arb_l2d_en, mbist_arb_l2d_write, mbist_l2d_en}), .siclk(siclk), .soclk(soclk)); l2t_msff_ctl_macro__width_16 input_cam_hit_reg ( .scan_in(input_cam_hit_reg_scanin), .scan_out(input_cam_hit_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mbist_l2tag_hit_way[15:0] ), .dout ( mb_l2tag_hit_way[15:0] ), .siclk(siclk), .soclk(soclk)); // work ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// //////////////////////////////////// // CONTROL REG: //////////////////////////////////// //////////////////////////////////// l2t_msff_ctl_macro__width_36 cntl_reg ( .scan_in(cntl_reg_scanin), .scan_out(cntl_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( cntl_in[35:0] ), .dout ( cntl_out[35:0] ), .siclk(siclk), .soclk(soclk)); assign cntl_in[35:22] = reset_engine ? {14'b00000000000000}: (~run3) ? cntl_algr[13:0]: next_algr[13:0]; // assign cntl_in[12:3] = reset_engine ? start_addr[7:0]: // ~run3 ? cntl_addr[7:0]: // next_addr[7:0]; // reset_engine run3 overflow cout_rw output // --------------------------------------------------------- // 1 x x x start_addr // 0 0 x x cntl_addr // 0 1 1 x restart_addr // 0 1 0 1 incred_addr // 0 1 0 0 cntl_addr assign sel_nextaddr_reset = reset_engine; assign sel_nextaddr_restart = ~reset_engine & run3 & overflow; assign sel_nextaddr_incred = ~reset_engine & run3 & ~overflow & cout_rw; assign sel_nextaddr_same = ~(sel_nextaddr_reset | sel_nextaddr_restart | sel_nextaddr_incred); assign cntl_in[21:4] = ({18{sel_nextaddr_reset}} & start_addr[17:0]) | ({18{sel_nextaddr_restart}} & restart_addr[17:0]) | ({18{sel_nextaddr_incred}} & incred_addr[17:0]) | ({18{sel_nextaddr_same}} & cntl_addr[17:0]); assign cntl_in[3:1] = reset_engine ? 3'b000 : (~run3 ) ? cntl_rw[2:0]: next_rw[3:1]; assign cntl_in[0] = next_rw[0]; //////////////////////////////////// //////////////////////////////////// // NEXT ALGR //////////////////////////////////// //////////////////////////////////// // msb assign cntl_msb = start_in & cntl_out[ 35]; // done selection assign cntl_bisi = mb_default_bisi | mb_user_bisi_rw_mode ? cntl_out[34] : 1'b1; // array assign cntl_array_sel[3:0] = (user_mode | last_array) ? 4'b1111: cntl_out[33:30]; // array selection // data assign cntl_data_sel[1:0] = (bisi_mode | mb_user_data_mode) ? 2'b11 : cntl_out[29:28]; // data selection // address mix assign cntl_addr_mix[1:0] = addr_mix_pass ? 2'b11 : cntl_out[27:26]; // address mix assign cntl_march_element[3:0] = sel_march_1_pass ? 4'b1111: cntl_out[25:22]; // march element // assign addr_mix[1:0] = (bisi_mode | mb_user_addr_mode ) ? 2'b00 : // cntl_addr_mix[1:0]; // cmp logic assign addr_mix_cntl_out[1:0] = cntl_out[27:26]; l2t_msff_ctl_macro__width_2 cntl_addr_mix_reg ( .scan_in(cntl_addr_mix_reg_scanin), .scan_out(cntl_addr_mix_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( addr_mix_sel[1:0] ), .dout ( addr_mix_sel_out[1:0] ), .siclk(siclk), .soclk(soclk)); // assign cmp_sel[3:0]= (&cmp_sel_cntl_out[3:0] & ~(array_5)) ? cmp_sel_out[3:0] : assign addr_mix_sel[1:0]= (&addr_mix_cntl_out[1:0] ) ? addr_mix_sel_out[1:0] : mb_user_addr_mode ? user_addr_mix_sel[1:0] : addr_mix_cntl_out[1:0]; assign addr_mix_pass = (mb_user_addr_mode | bisi_mode ) | array_0 & addr_mix_1 | array_1 & addr_mix_1 | array_2 & addr_mix_1 | array_3 & addr_mix_1 ; assign addr_mix_0 = addr_mix_sel==2'b00 & run3; assign addr_mix_1 = addr_mix_sel==2'b01 & run3; assign addr_mix_2 = addr_mix_sel==2'b10 & run3; assign cntl_algr[13:0] = {cntl_msb, cntl_bisi, cntl_array_sel[3:0], cntl_data_sel[1:0], cntl_addr_mix[1:0], cntl_march_element[3:0]}; assign next_algr[13:0] = cout_addr ? cntl_algr[13:0] + 14'h1 : cntl_algr[13:0]; // mbist control //////////////////////////////////// //////////////////////////////////// // NEXT ADDR //////////////////////////////////// //////////////////////////////////// ///////////////////////// // address engine ///////////////////////// assign upaddr = march_0 | march_1 | march_2 | march_6 | march_7 | bisi_mode ; assign march_element_pre[3:0]=next_algr[3:0]; assign march_pre_0 = march_element_pre[3:0]==4'h0; assign march_pre_1 = march_element_pre[3:0]==4'h1; assign march_pre_2 = march_element_pre[3:0]==4'h2; assign march_pre_6 = march_element_pre[3:0]==4'h6; assign march_pre_7 = march_element_pre[3:0]==4'h7; assign upaddr_pre = march_pre_0 | march_pre_1 | march_pre_2 | march_pre_6 | march_pre_7; assign incr_addr[17:0] = mb_user_addr_mode ? user_incr_addr[17:0] : 18'b000000000000000001; assign start_addr[17:0] = mb_user_addr_mode ? user_start_addr[17:0] : 18'b000000000000000000; // assign next_addr_out[8:0] = cout_rw ? cntl_addr[8:0] + incr_addr[8:0] : cntl_addr[8:0]; // next address assign incred_addr[17:0] = cntl_addr[17:0] + incr_addr[17:0]; assign overflow = upaddr ? ( cntl_addr[17:0] == stop_addr[17:0]) & (cntl_rw[2:0]==3'b111 & cntl_l2rw): (~cntl_addr[17:0] == start_addr[17:0]) & (cntl_rw[2:0]==3'b111 & cntl_l2rw); // assign next_addr[17:0]= overflow ? restart_addr[17:0] : next_addr_out[17:0]; assign restart_addr[17:0] = upaddr_pre ? start_addr[17:0] : ~stop_addr[17:0]; assign cout_addr = overflow; //////////////////////////////////// //////////////////////////////////// // NEXT RW //////////////////////////////////// //////////////////////////////////// assign cntl_rw[2:0] = sel_rw_pass ? 3'b111: cntl_out[ 3: 1]; // read write control assign cntl_l2rw = (run3 & (array_3 & cntl_out[0]) | ~(array_3)) ; assign rw_incr[3:0] = {cntl_rw[2:0],cntl_l2rw}; assign next_rw[3:0] = rw_incr[3:0]+4'b0001 ; assign cout_rw = &{cntl_rw[2:0],cntl_l2rw}; // carry over for rw //////////////////////////////////// //////////////////////////////////// // MBIST CONTROL SIGNAL // - mem_wr //////////////////////////////////// //////////////////////////////////// assign one_cycle_march = march_0 | march_5 | march_7; assign five_cycle_march = march_6 | march_8; assign two_cycle_march = ~(one_cycle_march | five_cycle_march); ///////////////////////// // membist write enable ///////////////////////// assign mem_wr_pbi = run3 & ( march_0 | ((march_1 | march_2 | march_3 | march_4 ) & rw_1) | (march_6 & (rw_0 | rw_1 | rw_4)) | march_7 | (march_8 & (rw_0 | rw_1 | rw_4)) ); assign mem_wr = bisi_wr_mode ? 1'b1 : bisi_rd_mode ? 1'b0 : mem_wr_pbi; ///////////////////////// // membist read enable ///////////////////////// assign mem_rd_pbi = run3 & ~mem_wr; assign mem_rd= bisi_rd_mode ? 1'b1 : mem_rd_pbi; ///////////////////// // membist address: //////////////////// assign cntl_addr[17:0] = cntl_out[21:4]; // Original Code: // assign adj_addr[17:0] = (five_cycle_march & (rw_1 | rw_3)) ? {cntl_addr[17:6],~cntl_addr[5],cntl_addr[4:0]}: // cntl_addr[17:0] ; // Proposed Code: assign adj_addr[17:0] = (five_cycle_march & (rw_1 | rw_3)) ? {cntl_addr[17:4],~cntl_addr[3],cntl_addr[2:0]}: cntl_addr[17:0] ; // If l2d: default cntl_addr[7:0] works // addr_mix cntl_addr[10:3] works // Note: Based on my conversation w/ Judy, for l2d, if a row needs to be replaced with a // redundant row, the redundant row is in the other 16KB block. In that case, // for that row and its corresponding row for weak-bit test, weak-bit address // would not be on the bitline. // If l2t: default cntl_addr[8:2] works // addr_mix cntl_addr[6:0] works // If vuad: default cntl_addr[5:2] works // addr_mix cntl_addr[3:0] works assign mem_addr1[17:0] = upaddr ? adj_addr[17:0]: ~adj_addr[17:0]; ///////////////////// // true data //////////////////// assign true_data_l = bisi_mode | march_0 | (march_1 & rw_0) | (march_2 & rw_1) | (march_3 & rw_0) | (march_4 & rw_1) | (march_5) | (march_6 & (rw_1 | rw_3 | rw_4)) | (march_8 & (rw_0 | rw_2)); assign true_data=~true_data_l; ///////////////////// // membist data: //////////////////// assign data_pat_sel[7:0] = (mb_user_data_mode & bisi_mode) ? ~user_data[7:0]: (mb_user_data_mode) ? user_data[7:0]: bisi_mode ? 8'hFF: (cntl_data_sel[1:0] == 2'h0) ? 8'hAA: (cntl_data_sel[1:0] == 2'h1) ? 8'h99: (cntl_data_sel[1:0] == 2'h2) ? 8'hCC: 8'h00; assign mem_data[7:0] = true_data ? data_pat_sel[7:0] : ~data_pat_sel[7:0]; // l2tag cam assign l2tag_data_0_or_1 = mem_data[7:0] == 8'h00 | mem_data[7:0]==8'hFF; assign l2tag_lkup_tag[27:0] = {mem_data[3:0],mem_data[7:0],mem_data[7:0],mem_data[7:0]}; assign mb_l2tag_lkup_tag[27:0] = (march_1 | march_2) ? l2tag_lkup_tag[27:0] : ~l2tag_lkup_tag[27:0]; assign l2tag_cam_pass = l2tag_cam_cmp_d4 ? &mb_l2tag_hit_way[15:0] : ~|mb_l2tag_hit_way[15:0]; assign l2tag_cam_fail = (l2tag_strobe_valid) ? ~l2tag_cam_pass : 1'b0; assign l2tag_strobe_valid = mb_addr[8] & array_2 & (~bisi_mode | ~mb_user_addr_mode) & l2tag_way[3:0]==4'h0 & (march_1 | march_2) ; assign l2tag_cam_cmp = mb_array_2_rd & (march_1 | march_2) & l2tag_data_0_or_1; l2t_msff_ctl_macro__width_4 cam_cmp_fail_delay_reg ( .scan_in(cam_cmp_fail_delay_reg_scanin), .scan_out(cam_cmp_fail_delay_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( { l2tag_cam_cmp, l2tag_cam_cmp_d1, l2tag_cam_cmp_d2, l2tag_cam_cmp_d3 } ), .dout ({ l2tag_cam_cmp_d1, l2tag_cam_cmp_d2, l2tag_cam_cmp_d3, l2tag_cam_cmp_d4 } ), .siclk(siclk), .soclk(soclk)); //////////////////////////////////// //////////////////////////////////// // STOP ADDR //////////////////////////////////// //////////////////////////////////// // cycle count for bisi: // arrays cycles operation // --------------------------- // vuad0: 512 write // vuad1: 512 write // l2tag: 8192 write // l2data: 131072 write // vuad0: 512 read // vuad1: 512 read // l2tag: 8192 read <-- abort after 1st read // l2data: 131072 read //----------------------------- // total 280576 assign stop_addr[17:0] = mb_user_addr_mode ? user_stop_addr[17:0] : array_0 ? 18'b00_00000001_11111111: // l2vuad (valid) array_1 ? 18'b00_00000001_11111111: // l2vuad (dirty) array_2 ? 18'b00_00011111_11111111: // l2tag array_3 ? 18'b00_11111111_11111111: // l2data 18'b01_11111111_11111111; //////////////////////////////////// //////////////////////////////////// // ADDR MIX //////////////////////////////////// //////////////////////////////////// // L2tag // ------ // Each L2t bank is 8Kx28. Each bank is composed of 8 arrays // and each array represent 2 ways. // Each array is 128 rows x (28x8) columns. There is a 4:1 column muxing // and since 2 ways, the 8 consecutive columns represent 2 ways, where // every 4 goes to one sense amp. // Therefore, index[8:0] chooses one of 512 entires, where: // index[8:2] are row addresses, and // index[1:0] are column addresses. // VUAD memories // -------------- // Each VUAD instance is 32 words x 160 bits and structured as // 32 rows x 160 columns. It is a straight forward memory. // The rows are divided in between for read. i.e. 16 rows on top // and 16 rows in the bottom. // Therefore, for addressing, consider this: // address_mix = 0 : mem_address[4:0] // = 1 : mem_address[3:0],mem_address[4] // to jump between // top & bottom. // For adjacent row, consider inverting one of mem_address[3:0] so that // both fall amongst the top or bottom rows. // // Furthermore, there are 4 arrays of 32x160 for VD and 4 for UA. // There are index[8:0] is used to address the bits of each set of 4 arrays. // For VD bits, since there 2 bits for each entry and for each way, then // # of bits per entry for 16 ways are 16x2=32 which requires 7 bits of ecc, // therefore 39 bits per entry is needed. Therefore, for 512 entries, we need: // 512 x 39 which is stored as (4 arrays) of (32rows) x (39x4). // So, index[8:0] is used in the following way: // index[1:0]: decodes which entry on each row, // index[6:2]: decodes which row within an array, // index[8:7]: decodes which of four 32x160 array instances. // L2data // ------ // Each bank of L2data is composed of a top and bottom half. Top half for // col_offset 1 and 3 and the bottom one for col_offset 0 and 2. // Each half is composed of 2 quadrants and each quadrant is made up of four // 32KB blocks. // The top two 32KB in each quadrant is controlled with way_sel[7:0] and the // bottom two is controlled with way_sel[15:8]. // Each 32KB block is built of two 16KB blocks. // Each 16KB block is the configured as 256 rows x 624 columns. // These 624 columns are muxed 8:1 into 78 i/o's. // way_sel[7:0] and way_sel[15:8] decode the 8 columns within an i/o. // set[7:0] decodes 256 rows within a 16K B and set[8] chooses between top and // bottom 16KB. // // l2tag assign mem_addr_mix0[17:0] = mem_addr1[17:0]; assign mem_addr_mix1[17:0] = (array_2) ? { mem_addr1[17:13], mem_addr1[12], mem_addr1[9], mem_addr1[11], mem_addr1[10], mem_addr1[6:0], mem_addr1[8:7] } : // l2tag fast row (array_0) ? { mem_addr1[17:7],mem_addr1[4:0],mem_addr1[6:5] } : // vuad (array_1) ? { mem_addr1[17:7],mem_addr1[4:0],mem_addr1[6:5] } : (array_3) ? { mem_addr1[17:16],mem_addr1[5:3],mem_addr1[6],mem_addr1[2:0],mem_addr1[15:7] } : mem_addr1[17:0]; // Default l2d: fast row, then 16K block, then column // Default l2t: fast col, then row, then way // Default vuad: fast word_en, then row // index[7:0], waysel, index[8], word assign mem_addr_mix2_pre[17:0] = { mem_addr1[17:16],mem_addr1[2:0],mem_addr1[7:4],mem_addr1[3],mem_addr1[15:8] } ; assign mem_addr_mix2_dec[3:0] = mem_addr_mix2_pre[12:9]==4'd0 ? 4'd0 : mem_addr_mix2_pre[12:9]==4'd1 ? 4'd8 : mem_addr_mix2_pre[12:9]==4'd2 ? 4'd1 : mem_addr_mix2_pre[12:9]==4'd3 ? 4'd9 : mem_addr_mix2_pre[12:9]==4'd4 ? 4'd2 : mem_addr_mix2_pre[12:9]==4'd5 ? 4'd10 : mem_addr_mix2_pre[12:9]==4'd6 ? 4'd3 : mem_addr_mix2_pre[12:9]==4'd7 ? 4'd11 : mem_addr_mix2_pre[12:9]==4'd8 ? 4'd4 : mem_addr_mix2_pre[12:9]==4'd9 ? 4'd12 : mem_addr_mix2_pre[12:9]==4'd10 ? 4'd5 : mem_addr_mix2_pre[12:9]==4'd11 ? 4'd13 : mem_addr_mix2_pre[12:9]==4'd12 ? 4'd6 : mem_addr_mix2_pre[12:9]==4'd13 ? 4'd14 : mem_addr_mix2_pre[12:9]==4'd14 ? 4'd7 : mem_addr_mix2_pre[12:9]==4'd15 ? 4'd15 : 4'h0 ; assign mem_addr_mix2[17:0]={mem_addr_mix2_pre[17:13],mem_addr_mix2_dec[3:0],mem_addr_mix2_pre[8:0]}; assign mem_addr[17:0] = addr_mix_0 ? mem_addr_mix0[17:0] : addr_mix_1 ? mem_addr_mix1[17:0] : addr_mix_2 ? mem_addr_mix2[17:0] : mem_addr1[17:0]; //////////////////////////////////// //////////////////////////////////// // SEQ selection //////////////////////////////////// //////////////////////////////////// // array assign array_0 = array_sel[3:0]==4'h0 & run3; assign array_1 = array_sel[3:0]==4'h1 & run3; assign array_2 = array_sel[3:0]==4'h2 & run3; assign array_3 = array_sel[3:0]==4'h3 & run3; // assign array_4 = array_sel[3:0]==4'h4; // assign array_5 = array_sel[3:0]==4'h5; assign last_array = array_3; // cmp // assign cmp_0 = cmp_sel[3:0]==4'b0000; // assign cmp_1 = cmp_sel[3:0]==4'b0001; // assign cmp_2 = cmp_sel[3:0]==4'b0010; // assign cmp_3 = cmp_sel[3:0]==4'b0011; // assign cmp_4 = cmp_sel[3:0]==4'b0100; // assign cmp_5 = cmp_sel[3:0]==4'b0101; // assign cmp_6 = cmp_sel[3:0]==4'b0110; // assign cmp_7 = cmp_sel[3:0]==4'b0111; // assign cmp_15 = cmp_sel[3:0]==4'b1111; // march assign march_0 = (march_element[3:0]==4'h0); assign march_1 = (march_element[3:0]==4'h1); assign march_2 = (march_element[3:0]==4'h2); assign march_3 = (march_element[3:0]==4'h3); assign march_4 = (march_element[3:0]==4'h4); assign march_5 = (march_element[3:0]==4'h5); assign march_6 = (march_element[3:0]==4'h6); assign march_7 = (march_element[3:0]==4'h7); assign march_8 = (march_element[3:0]==4'h8); // rw assign rw_0 = (rw[2:0]==3'b000); assign rw_1 = (rw[2:0]==3'b001); assign rw_2 = (rw[2:0]==3'b010); assign rw_3 = (rw[2:0]==3'b011); assign rw_4 = (rw[2:0]==3'b100); // assign rw_5 = (rw[2:0]==3'b101); // assign rw_6 = (rw[2:0]==3'b110); // assign rw_7 = (rw[2:0]==3'b111); //////////////////////////////////// //////////////////////////////////// // SEQ logic //////////////////////////////////// //////////////////////////////////// // array logic assign array_sel_cntl_out[3:0]=cntl_out[33:30]; l2t_msff_ctl_macro__width_4 array_sel_reg ( .scan_in(array_sel_reg_scanin), .scan_out(array_sel_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( array_sel[3:0] ), .dout ( array_sel_out[3:0] ), .siclk(siclk), .soclk(soclk)); assign array_sel[3:0]=(&array_sel_cntl_out[3:0]) ? array_sel_out[3:0] : user_mode ? user_array_sel[3:0] : array_sel_cntl_out[3:0]; // cmp logic // assign cmp_sel_cntl_out[3:0] = cntl_out[29:26]; // msff_ctl_macro cmp_sel_reg (width=4) ( // .scan_in(cmp_sel_reg_scanin), // .scan_out(cmp_sel_reg_scanout), // .din ( cmp_sel[3:0] ), // .dout ( cmp_sel_out[3:0] )); // // assign cmp_sel[3:0]= (&cmp_sel_cntl_out[3:0] & ~(array_4 | array_5)) ? cmp_sel_out[3:0] : // cmp_sel_cntl_out[3:0]; // march logic assign march_element_cntl_out[3:0]=cntl_out[25:22]; l2t_msff_ctl_macro__width_4 marche_element_reg ( .scan_in(marche_element_reg_scanin), .scan_out(marche_element_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( march_element[3:0] ), .dout ( march_element_out ), .siclk(siclk), .soclk(soclk)); assign march_element[3:0]=(&march_element_cntl_out[3:0]) ? march_element_out[3:0] : march_element_cntl_out[3:0]; // rw assign rw_cntl_out[2:0]=cntl_out[3:1]; l2t_msff_ctl_macro__width_3 march_element_reg ( .scan_in(march_element_reg_scanin), .scan_out(march_element_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( rw[2:0] ), .dout ( rw_out[2:0] ), .siclk(siclk), .soclk(soclk)); assign rw[2:0]=(&rw_cntl_out[2:0]) ? rw_out[2:0] : rw_cntl_out[2:0]; ////////////////////////////////////////////////////////////////// // SEL_PASS LOGIC ////////////////////////////////////////////////////////////////// // pass logic: // march assign sel_march_1_pass = bisi_mode | (mb_ten_n_mode & march_5) | march_8; assign bisi_wr_mode = mb_default_bisi | mb_user_bisi_rw_mode ? ~cntl_bisi & run3 : mb_user_bisi_wr_mode & run3; assign bisi_rd_mode =mb_default_bisi | mb_user_bisi_rw_mode ? cntl_bisi & run3 : mb_user_bisi_rd_mode & run3; // rw assign sel_rw_1_pass = bisi_mode | one_cycle_march ; assign sel_rw_2_pass = two_cycle_march; assign sel_rw_5_pass = five_cycle_march; assign sel_rw_pass = (run3 & sel_rw_1_pass & rw_0) | (run3 & sel_rw_2_pass & rw_1) | (run3 & sel_rw_5_pass & rw_4) ; //////////////////////////////////// //////////////////////////////////// // membist control assignment //////////////////////////////////// //////////////////////////////////// assign mb_addr[17:0]= mem_addr[17:0]; assign l2tag_way[3:0]=mb_addr[12:9]; assign mb_write_data[7:0]=mem_data[7:0]; // only one array read signal should be active assign mb_array_0_rd = array_0 & mem_rd; // l2tag assign mb_array_1_rd = array_1 & mem_rd; // l2vuad (valid) assign mb_array_2_rd = array_2 & mem_rd; // l2vuad (dirty) // assign mb_array_3_rd = array_3 & mem_rd & (mb_user_addr_mode ; // l2data assign mb_array_3_rd = mb_user_addr_mode ? array_3 & mem_rd & ~quad_cntl: array_3 & mem_rd ; assign mb_array_0_wr = array_0 & mem_wr; assign mb_array_1_wr = array_1 & mem_wr; assign mb_array_2_wr = array_2 & mem_wr; assign mb_array_3_wr = mb_user_addr_mode ? array_3 & mem_wr & quad_cntl : array_3 & mem_wr ; //((~user_mode) | (user_mode & quad_cntl)) & array_3; assign quad_cntl = mb_user_quad_sel ? cntl_l2rw_out : ~cntl_l2rw_out; assign mb_run = run; //////////////////////////////////// //////////////////////////////////// // DONE LOGIC //////////////////////////////////// //////////////////////////////////// l2t_msff_ctl_macro__width_1 msb_latch ( .scan_in(msb_latch_scanin), .scan_out(msb_latch_scanout), .l1clk ( l1clk_pm1 ), .din ( msb_in ), .dout ( msb_out ), .siclk(siclk), .soclk(soclk)); assign msb_in= (~start_in ) | (mb_user_loop_mode & mb_done) ? 1'b0 : (cntl_msb) ? 1'b1 : msb_out; assign stop_engine_l = start_in & cntl_msb; assign mb_done=msb_out & (done_delay[4:0]==5'b11110); assign run3 = &done_delay[4:1] & ~stop_engine_l & start_in; l2t_msff_ctl_macro__width_1 run3_transition_reg ( .scan_in(run3_transition_reg_scanin), .scan_out(run3_transition_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( run3 ), .dout ( run3_out ), .siclk(siclk), .soclk(soclk)); assign run3_transition = run3 & ~run3_out; l2t_msff_ctl_macro__width_5 done_delay_reg ( .scan_in(done_delay_reg_scanin), .scan_out(done_delay_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( done_delay_in[4:0] ), .dout ( done_delay[4:0] ), .siclk(siclk), .soclk(soclk)); assign done_delay_in[4:0] = run3 ? 5'b11111 : mb_done ? 5'b11110 : (run & ~run3) ? done_delay[4:0] + 5'b00001 : 5'b00000; // merge start, done, fail signals: // ordering of test operation of engines // - mb0 parallel with mb2 - mb1 // default mode: // done - default: mb_all_done = mb0_done & mb1_done; // - user : mb_all_done = mb0_done | mb1_done | mb2_done; // fail - default: mb_all_fail = mb0_fail | mb1_fail | mb2_fail; // - user : mb_all_fail = mb0_fail | mb1_fail | mb2_fail; // merge fail and done signals: l2t_msff_ctl_macro__width_3 merged_fail ( .scan_in(merged_fail_scanin), .scan_out(merged_fail_scanout), .l1clk ( l1clk_pm1 ), .din ( {mbist0_fail,mbist2_fail,mb_fail_merged} ), .dout ( {mb0_fail, mb2_fail, mbist_fail} ), .siclk(siclk), .soclk(soclk)); l2t_msff_ctl_macro__width_3 merged_done ( .scan_in(merged_done_scanin), .scan_out(merged_done_scanout), .l1clk ( l1clk_pm1 ), .din ( {mbist0_done,mbist2_done,mb_done_merged} ), .dout ( {mb0_done, mb2_done, mbist_done} ), .siclk(siclk), .soclk(soclk)); assign mb_fail_merged=mb1_fail | mb2_fail | mb0_fail; assign mb_done_merged= user_mode ? (mb0_done | mb2_done | mb1_done) : (mb0_done & mb1_done); //////////////////////////////////// //////////////////////////////////// // FAIL LOGIC //////////////////////////////////// //////////////////////////////////// // mb_*_fail signals are all inverted // 0 - pass, 1 - fail assign mb_l2tag_fail = ~mbist_l2tag_fail; assign mb_l2vuad_fail = ~mbist_l2vuad_fail; assign mb_l2data_fail_pregate = ~mbist_l2data_fail; l2t_msff_ctl_macro__width_6 l2data_rd_cmp_reg ( .scan_in(l2data_rd_cmp_reg_scanin), .scan_out(l2data_rd_cmp_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( {mb_array_3_rd,array_3_rd_d1,array_3_rd_d2,array_3_rd_d3,array_3_rd_d4,array_3_rd_d5} ), .dout ( {array_3_rd_d1 ,array_3_rd_d2,array_3_rd_d3,array_3_rd_d4,array_3_rd_d5,array_3_rd_d6} ), .siclk(siclk), .soclk(soclk)); assign mb_l2data_fail = array_3_rd_d6 ? mb_l2data_fail_pregate : 1'b0; //assign mb_l2data_fail= (~mb_array_3_wr & mb_l2data_fail_pregate); assign l2tag_fail_d = run3_transition ? 1'b0 : mb_l2tag_fail | l2tag_fail_sticky; assign l2vuad_fail_d = run3_transition ? 1'b0 : mb_l2vuad_fail | l2vuad_fail_sticky; assign l2data_fail_d = run3_transition ? 1'b0 : mb_l2data_fail | l2data_fail_sticky; assign l2tag_cam_fail_d = run3_transition ? 1'b0 : l2tag_cam_fail | l2tag_cam_sticky; l2t_msff_ctl_macro__width_4 mbist_fail_input_reg ( .scan_in(mbist_fail_input_reg_scanin), .scan_out(mbist_fail_input_reg_scanout), .l1clk ( l1clk_pm1 ), .din ({l2tag_fail_d, l2vuad_fail_d, l2data_fail_d, l2tag_cam_fail_d }), .dout ({l2tag_fail_sticky, l2vuad_fail_sticky, l2data_fail_sticky, l2tag_cam_sticky }), .siclk(siclk), .soclk(soclk)); assign mbist_fail_sticky = l2tag_fail_sticky | l2vuad_fail_sticky | l2data_fail_sticky | l2tag_cam_sticky ; assign mbist_fail_array = mb_l2tag_fail | mb_l2vuad_fail | mb_l2data_fail | l2tag_cam_fail ; assign valid_fail=run3 | (stop_engine_l & ~mb_done); assign mb_fail = mb_done ? mbist_fail_sticky : mbist_fail_array & valid_fail; ////////////////////////////////////////////////////////////////// // OUTPUT FLOP: ////////////////////////////////////////////////////////////////// // mb_done l2t_msff_ctl_macro__width_1 out_mb_tcu_done_reg ( .scan_in(out_mb_tcu_done_reg_scanin), .scan_out(out_mb_tcu_done_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mb_done ), .dout ( mb_done_out ), .siclk(siclk), .soclk(soclk)); // mb_fail l2t_msff_ctl_macro__width_1 out_mb_tcu_fail_reg ( .scan_in(out_mb_tcu_fail_reg_scanin), .scan_out(out_mb_tcu_fail_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mb_fail ), .dout ( mb_fail_out ), .siclk(siclk), .soclk(soclk)); // thes are all the output flops to arrays // for the following signals: // // - run // - data // - address l2t_msff_ctl_macro__width_1 out_run_mb_arrays_reg ( .scan_in(out_run_mb_arrays_reg_scanin), .scan_out(out_run_mb_arrays_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mb_run), .dout ( mb_run_out), .siclk(siclk), .soclk(soclk)); // data 8 bits l2t_msff_ctl_macro__width_16 out_data_mb_arrays_reg ( .scan_in(out_data_mb_arrays_reg_scanin), .scan_out(out_data_mb_arrays_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( {mb_write_data[7:0],mb_write_data[7:0]}), .dout ( {mb_write_data_out[7:0],mbist_write_data_decck_out[7:0]}), .siclk(siclk), .soclk(soclk)); // address 16 bits l2t_msff_ctl_macro__width_18 out_addr_mb_arrays_reg ( .scan_in(out_addr_mb_arrays_reg_scanin), .scan_out(out_addr_mb_arrays_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( mb_addr[17:0]), .dout ( mb_addr_out[17:0]), .siclk(siclk), .soclk(soclk)); // // write enable l2t_msff_ctl_macro__width_4 out_wr_mb_arrays_reg ( .scan_in(out_wr_mb_arrays_reg_scanin), .scan_out(out_wr_mb_arrays_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( { mb_array_0_wr, mb_array_1_wr, mb_array_2_wr, mb_array_3_wr } ), .dout ({ mb_array_0_wr_out, mb_array_1_wr_out, mb_array_2_wr_out, mb_array_3_wr_out } ), .siclk(siclk), .soclk(soclk)); // read enable l2t_msff_ctl_macro__width_3 out_rd_mb_arrays_reg ( .scan_in(out_rd_mb_arrays_reg_scanin), .scan_out(out_rd_mb_arrays_reg_scanout), .l1clk ( l1clk_pm1 ), .din ( { mb_array_0_rd, mb_array_1_rd, mb_array_2_rd } ), .dout ({ mb_array_0_rd_out, mb_array_1_rd_out, mb_array_2_rd_out } ), .siclk(siclk), .soclk(soclk)); // port name re-assignment assign mbist_run =mb_run_out; assign mbist_write_data[7:0] =mb_write_data_out[7:0]; assign mbist_write_data_decck[7:0] =mbist_write_data_decck_out[7:0]; // duplicated the bus for routing reasons assign mbist_l2tag_index[8:0] =mb_addr_out[8:0]; assign mbist_l2data_index[8:0] =mb_addr_out[8:0]; assign mbist_l2vuad_index[8:0] =mb_addr_out[8:0]; assign mbist_l2tag_way[3:0] =mb_addr_out[12:9]; assign mbist_l2data_way[3:0] =mb_addr_out[12:9]; // top half 0,1,2,3 ,8 ,9, 10,11 // bot hald 4,5,6,7 12,13,14,15 // current: // 0 1 2 3 11 10 9 8 // 15 14 13 12 4 5 6 7 // designer's request: // 0 2 8 10 1 3 9 11 top half // 15 13 7 5 4 6 12 14 bot half // mb_addr_out[16:13] // 000 // 001 // 010 // 011 // 100 // 101 // 110 // 111 assign l2data_word[3:0] = mb_addr_out[16:15]==2'b01 ? ~mb_addr_out[16:13] : mb_addr_out[16:13]; assign mbist_l2data_word[3:0] =cntl_l2rw_out ? ~l2data_word[3:0] : l2data_word[3:0]; // assign l2data_word_frow[3:0] = l2data_word_raw[3:0]==4'd0 ? 4'd0 : // l2data_word_raw[3:0]==4'd1 ? 4'd2 : // l2data_word_raw[3:0]==4'd2 ? 4'd8 : // l2data_word_raw[3:0]==4'd3 ? 4'd10 : // l2data_word_raw[3:0]==4'd11 ? 4'd1 : // l2data_word_raw[3:0]==4'd10 ? 4'd3 : // l2data_word_raw[3:0]==4'd9 ? 4'd9 : // l2data_word_raw[3:0]==4'd8 ? 4'd11 : // l2data_word_raw[3:0]==4'd15 ? 4'd15 : // l2data_word_raw[3:0]==4'd14 ? 4'd13 : // l2data_word_raw[3:0]==4'd13 ? 4'd7 : // l2data_word_raw[3:0]==4'd12 ? 4'd5 : // l2data_word_raw[3:0]==4'd4 ? 4'd4 : // l2data_word_raw[3:0]==4'd5 ? 4'd6 : // l2data_word_raw[3:0]==4'd6 ? 4'd12 : // l2data_word_raw[3:0]==4'd7 ? 4'd14 : // 4'd0; // assign mb1_fail =mb_fail_out; assign mb1_done =mb_done_out; assign mbist_l2vuad_write =mb_array_0_wr_out | mb_array_1_wr_out; assign mbist_l2tag_write =mb_array_2_wr_out; assign mbist_l2data_write =mb_array_3_wr_out; assign mbist_l2tag_read =mb_array_2_rd_out; assign mbist_l2vuad_read =mb_array_0_rd_out | mb_array_1_rd_out; // spare gates: l2t_spare_ctl_macro__num_2 spares ( .scan_in(spares_scanin), .scan_out(spares_scanout), .l1clk (l1clk_pm1), .siclk(siclk), .soclk(soclk) ); supply0 vss; // <- port for ground supply1 vdd; // <- port for power // ///////////////////////////////////////////////////////////////////////////// // fixscan start: assign array_usr_reg_scanin = scan_in ; assign user_addr_mode_reg_scanin = array_usr_reg_scanout ; assign user_start_addr_reg_scanin = user_addr_mode_reg_scanout; assign user_stop_addr_reg_scanin = user_start_addr_reg_scanout; assign user_incr_addr_reg_scanin = user_stop_addr_reg_scanout; assign user_data_mode_reg_scanin = user_incr_addr_reg_scanout; assign user_data_reg_scanin = user_data_mode_reg_scanout; assign user_loop_mode_reg_scanin = user_data_reg_scanout ; assign ten_n_mode_reg_scanin = user_loop_mode_reg_scanout; assign user_quad_sel_reg_scanin = ten_n_mode_reg_scanout ; assign user_bisi_wr_mode_reg_scanin = user_quad_sel_reg_scanout; assign user_bisi_rd_mode_reg_scanin = user_bisi_wr_mode_reg_scanout; assign user_addr_mix_sel_reg_scanin = user_bisi_rd_mode_reg_scanout; assign mbist_start_reg_scanin = user_addr_mix_sel_reg_scanout; assign mbist_start_all_reg_scanin = mbist_start_reg_scanout ; assign input_signals_reg_scanin = mbist_start_all_reg_scanout; assign mb_enable_reg_scanin = input_signals_reg_scanout; assign config_reg_scanin = mb_enable_reg_scanout ; assign loop_again_reg_scanin = config_reg_scanout ; assign mbist_output_reg_scanin = loop_again_reg_scanout ; assign input_cam_hit_reg_scanin = mbist_output_reg_scanout ; assign cntl_reg_scanin = input_cam_hit_reg_scanout; assign cntl_addr_mix_reg_scanin = cntl_reg_scanout ; assign cam_cmp_fail_delay_reg_scanin = cntl_addr_mix_reg_scanout; assign array_sel_reg_scanin = cam_cmp_fail_delay_reg_scanout; assign marche_element_reg_scanin = array_sel_reg_scanout ; assign march_element_reg_scanin = marche_element_reg_scanout; assign msb_latch_scanin = march_element_reg_scanout; assign run3_transition_reg_scanin = msb_latch_scanout ; assign done_delay_reg_scanin = run3_transition_reg_scanout; assign merged_fail_scanin = done_delay_reg_scanout ; assign merged_done_scanin = merged_fail_scanout ; assign l2data_rd_cmp_reg_scanin = merged_done_scanout ; assign mbist_fail_input_reg_scanin = l2data_rd_cmp_reg_scanout; assign out_mb_tcu_done_reg_scanin = mbist_fail_input_reg_scanout; assign out_mb_tcu_fail_reg_scanin = out_mb_tcu_done_reg_scanout; assign out_run_mb_arrays_reg_scanin = out_mb_tcu_fail_reg_scanout; assign out_data_mb_arrays_reg_scanin = out_run_mb_arrays_reg_scanout; assign out_addr_mb_arrays_reg_scanin = out_data_mb_arrays_reg_scanout; assign out_wr_mb_arrays_reg_scanin = out_addr_mb_arrays_reg_scanout; assign out_rd_mb_arrays_reg_scanin = out_wr_mb_arrays_reg_scanout; assign spares_scanin = out_rd_mb_arrays_reg_scanout; assign scan_out = spares_scanout ; // fixscan end: endmodule // any PARAMS parms go into naming of macro module l2t_msff_ctl_macro__width_18 ( din, l1clk, scan_in, siclk, soclk, dout, scan_out); wire [17:0] fdin; wire [16:0] so; input [17:0] din; input l1clk; input scan_in; input siclk; input soclk; output [17:0] dout; output scan_out; assign fdin[17:0] = din[17:0]; dff #(18) d0_0 ( .l1clk(l1clk), .siclk(siclk), .soclk(soclk), .d(fdin[17:0]), .si({scan_in,so[16:0]}), .so({so[16:0],scan_out}), .q(dout[17:0]) ); endmodule