blob: 7163fdc045b05bfe968c8797eb58d680aa55605e [file] [log] [blame]
//////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// 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.
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
//
//////////////////////////////////////////////////////////////////////
//// ////
//// MBIST and MEMORY Mux Control Selection ////
//// ////
//// This file is part of the mbist_ctrl cores project ////
//// https://github.com/dineshannayya/mbist_ctrl.git ////
//// ////
//// Description ////
//// This block integrate MBIST and Memory control selection ////
//// ////
//// To Do: ////
//// nothing ////
//// ////
//// Author(s): ////
//// - Dinesh Annayya, dinesha@opencores.org ////
//// ////
//// Revision : ////
//// 0.0 - 11th Oct 2021, Dinesh A ////
//// Initial integration
//// ////
//////////////////////////////////////////////////////////////////////
`include "mbist_def.svh"
module mbist_mux
#( parameter BIST_ADDR_WD = 9,
parameter BIST_DATA_WD = 32,
parameter BIST_ADDR_START = 9'h000,
parameter BIST_ADDR_END = 9'h1F8,
parameter BIST_REPAIR_ADDR_START = 9'h1FC,
parameter BIST_RAD_WD_I = BIST_ADDR_WD,
parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
input logic rst_n,
// MBIST CTRL SIGNAL
input logic bist_en,
input logic [BIST_ADDR_WD-1:0] bist_addr,
input logic [BIST_DATA_WD-1:0] bist_wdata,
input logic bist_clk,
input logic bist_wr,
input logic bist_rd,
input logic bist_error,
input logic [BIST_ADDR_WD-1:0] bist_error_addr,
output logic bist_correct,
input logic bist_sdi,
input logic bist_shift,
output logic bist_sdo,
// FUNCTIONAL CTRL SIGNAL
input logic func_clk_a,
input logic func_cen_a,
input logic [BIST_ADDR_WD-1:0] func_addr_a,
// Common for func and Mbist i/f
output logic [BIST_DATA_WD-1:0] func_dout_a,
input logic func_clk_b,
input logic func_cen_b,
input logic func_web_b,
input logic [BIST_DATA_WD/8-1:0] func_mask_b,
input logic [BIST_ADDR_WD-1:0] func_addr_b,
input logic [BIST_DATA_WD-1:0] func_din_b,
// towards memory
output logic mem_clk_a,
output logic mem_cen_a,
output logic [BIST_ADDR_WD-1:0] mem_addr_a,
input logic [BIST_DATA_WD-1:0] mem_dout_a,
output logic mem_clk_b,
output logic mem_cen_b,
output logic mem_web_b,
output logic [BIST_DATA_WD/8-1:0] mem_mask_b,
output logic [BIST_ADDR_WD-1:0] mem_addr_b,
output logic [BIST_DATA_WD-1:0] mem_din_b
);
parameter BIST_MASK_WD = BIST_DATA_WD/8;
wire [BIST_ADDR_WD-1:0] addr_a;
wire [BIST_ADDR_WD-1:0] addr_b;
wire mem_clk_a_cts; // used for internal clock tree
wire mem_clk_b_cts; // usef for internal clock tree
assign addr_a = (bist_en) ? bist_addr : func_addr_a;
assign addr_b = (bist_en) ? bist_addr : func_addr_b;
assign mem_cen_a = (bist_en) ? !bist_rd : func_cen_a;
assign mem_cen_b = (bist_en) ? !bist_wr : func_cen_b;
assign mem_web_b = (bist_en) ? !bist_wr : func_web_b;
assign mem_mask_b = (bist_en) ? {{BIST_MASK_WD}{1'b1}} : func_mask_b;
//assign mem_clk_a = (bist_en) ? bist_clk : func_clk_a;
//assign mem_clk_b = (bist_en) ? bist_clk : func_clk_b;
ctech_mux2x1 u_mem_clk_a_sel (.A0 (func_clk_a),.A1 (bist_clk),.S (bist_en), .X (mem_clk_a));
ctech_mux2x1 u_mem_clk_b_sel (.A0 (func_clk_b),.A1 (bist_clk),.S (bist_en), .X (mem_clk_b));
sky130_fd_sc_hd__clkbuf_16 u_cts_mem_clk_a (.A (mem_clk_a), . X(mem_clk_a_cts));
sky130_fd_sc_hd__clkbuf_16 u_cts_mem_clk_b (.A (mem_clk_b), . X(mem_clk_b_cts));
assign mem_din_b = (bist_en) ? bist_wdata : func_din_b;
assign func_dout_a = mem_dout_a;
mbist_repair_addr
#(.BIST_ADDR_WD (BIST_ADDR_WD),
.BIST_DATA_WD (BIST_DATA_WD),
.BIST_ADDR_START (BIST_ADDR_START),
.BIST_ADDR_END (BIST_ADDR_END),
.BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START),
.BIST_RAD_WD_I (BIST_RAD_WD_I),
.BIST_RAD_WD_O (BIST_RAD_WD_O))
u_repair_A(
.AddressOut (mem_addr_a ),
.Correct (bist_correct ),
.sdo (bist_sdo ),
.AddressIn (addr_a ),
.clk (mem_clk_a_cts ),
.rst_n (rst_n ),
.Error (bist_error ),
.ErrorAddr (bist_error_addr ),
.scan_shift (bist_shift ),
.sdi (bist_sdi )
);
mbist_repair_addr
#(.BIST_ADDR_WD (BIST_ADDR_WD),
.BIST_DATA_WD (BIST_DATA_WD),
.BIST_ADDR_START (BIST_ADDR_START),
.BIST_ADDR_END (BIST_ADDR_END),
.BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START),
.BIST_RAD_WD_I (BIST_RAD_WD_I),
.BIST_RAD_WD_O (BIST_RAD_WD_O))
u_repair_B(
.AddressOut (mem_addr_b ),
.Correct ( ), // Both Bist Correct are same
.sdo ( ),
.AddressIn (addr_b ),
.clk (mem_clk_b_cts ),
.rst_n (rst_n ),
.Error (bist_error ),
.ErrorAddr (bist_error_addr ),
.scan_shift (1'b0 ), // Both Repair hold same address
.sdi (1'b0 )
);
endmodule